模型类的单例模式

如果在一个功能中(控制器),需要使用某个表的多次操作,应该使用该表的一个模型就可以完成全部的任务!

思考:如何保证模型类的单例呢?

典型的,可以通过一个单例的工厂来实现!( 为什么不用三私一公呢?因为基本上所有的模型类都需要单例模式,把所有的模型类都修改为三私一公比较麻烦

而且通过单例工厂来实现更加灵活);

 

代码展示

  1.Model 模型类---MyPDO,它是连接数据库和操作数据库的模型类

  

<?php
class MyPDO
{
    private static $instance;  //保存对象
    private $host;      //主机地址
    private $dbname;    //数据库名字
    private $port;      //端口
    private $user;      //用户名
    private $pwd;       //密码
    private $charset;   //字符集
    private $link;      //连接对象


    private function __construct($data){

        $this->initParam($data);
        $this->getPDO();
        $this->errorMode();
    }

    private function __clone(){

    }

    //获取单例
    public static function getInstance($data=array()){
        if(!self::$instance instanceof self){
            return self::$instance=new self($data);
        }
        return self::$instance;
    }

    //初始化参数
    private function initParam($data){
        $this->host=isset($data['host'])?$data['host']:'localhost'; 
        $this->dbname=isset($data['dbname'])?$data['dbname']:'my_db';
        $this->port=isset($data['port'])?$data['port'] : '3306';
        $this->user=isset($data['user'])?$data['user']:'root';
        $this->pwd=isset($data['pwd'])?$data['pwd']:'root';
        $this->charset=isset($data['charset'])?$data['charset']:'utf8';
    }

    //显示错误
    private function showError($e,$sql=null){
        echo "错误信息".$e->getMessage()."<br>";
        echo "错误代码".$e->getCode()."<br>";
        echo "错误文件".$e->getFile()."<br>";
        echo "错误行号".$e->getLine().'<br>';
        if($sql!=null){
            echo "错误sql语句".$sql;
        }
    }
    //连接数据库
    private function getPDO(){
        try {
            $this->link= new PDO("mysql:host={$this->host};port={$this->port};dbname={$this->dbname};charset={$this->charset}","{$this->user}","{$this->pwd}");
        } catch (PDOException $e) {
           $this->showError($e);
            exit;
        }
    }

    //设置错误模式
    private function errorMode(){
        $this->link->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    }

    

    /**
     * 增删改功能
     * @param string sql语句
     * @return int 受影响的行数
     */
    public function exec($sql){
        try {
            return $row=$this->link->exec($sql);
        } catch (PDOException $e) {
            $this->showError($e,$sql);
            exit;
        }

    }

    /**
     * 获取二维数组结果集
     * @param string sql
     * @return PDOStatement 结果集
     */

     public function fetchAll($sql){
         try{
            $stmt=$this->link->query($sql);
            return $stmt->fetchAll();

         }catch(PDOException $e){
            $this->showError($e,$sql);
         }

     }

     /**
      * 获取一维数组结果集
      *@param string sql
      *@return PDOStatement 结果集
      */
      public function fetch($sql){
          try {
            $stmt= $this->link->query($sql);
            return $stmt->fetch();
          } catch (PDOException $e) {
              $this->showError($e,$sql);
          }

      }

      /**
       * 获取单行单列
       * @param string sql
       * @return mixed 内容
       */
      public  function fetchColumn($sql){
          try {
            $stmt=$this->link->query($sql);
            return $stmt->fetchColumn();
          } catch (PDOException $e) {
              $this->showError($e,$sql);
          }
      }

      //转账事务操作
      public function beginTransction($sql_out,$sql_in){
         try {
                $this->link->beginTransaction();
                $out=$this->link->exec($sql_out);
                $in=$this->link->exec($sql_in);
                if($out && $in){
                    $this->link->commit();
                    echo "转账成功";
                }else{
                    $this->link->rollBack();
                }
         } catch (PDOException $e) {
             $this->showError($e);
         }
      }

}

  2.Model 模型-Model.class.php 基础模型类,每个模型类都需要继承Model.class.php 类(不继承代码不冗余,每次都要连接数据库和增删改查)

<?php

    /**
     * 基础模型类,其他模型类继承此类
     * 所有模型类的父类
     */
    class Moudel
    {
        //定义存储pdo对象的属性,要求在子类中可以被访问;
        protected $pdo;
        //构造方法,当子类继承的时候,直接就初始化pdo的对象
        public function __construct(){
            //初始化pdo
            $this->initPDO();
        }

        //初始化pdo对象
        protected function initPDO(){
            //加载MyPDO类
            require './MyPDO.class.php';
            $this->pdo=MyPDO::getInstance();
        }
      
    }

3.Model 模型--Factory.class.php  单例模型工厂类,每次使用模型类  不需要实例化

<?php     
    /**
     * 项目中的单例工厂
     */
    class Factory
    {
        /**
         * 定义一个创建单例对象的方法
         * @param string 类的名字
         * @return object 
         */
        public static function M($class_name){
            //定义保存实例化对象的数组,下标对应的类,值为实例化的对象
             static $arr=array();
             //判断
             if(!isset($arr[$class_name])){
                    //如果当前类没有对象,就引入类的文件,并且实例化
                    include_once "./{$class_name}.class.php";
                    $arr[$class_name]= new $class_name;
             }
             return $arr[$class_name];
        }   
    }

4.Model 模型 Mybank 表模型类,它对应着数据库的my_bank 表,对这个表的所有操作,都在这里

 

<?php 

    //加载Model基础类并继承
    include 'Model.class.php';
    //显示my_bank表模型类
    class Mybank extends Model
    {
        /**
         * 获取my_bank下的说有数据
         * @param string sql语句
         * @return array 结果集
         */
        public function showTable($sql){
            //this->pdo 是继承父类基础模型MyPDO的对象
            return $this->pdo->fetchAll($sql);
        }
    }

 

5.Controller 控制器,它负责调用模型和视图

<?php 

    //调用单例工厂
    include 'Factory.class.php';
    //模型Mybank单例
    $bank= Factory::M("Mybank");
    //调用单例的方法,返回结果集rs
    $rs=$bank->showTable("select * from my_bank");

    //调用View 视图
    include 'index.php';  //引入这个视图,rs 才可以使用

 

 

6.VIew 视图   它是用来显示给用户的


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        table{
            width: 300px;
            border: solid 1px solid;
        }
        td{
            width:80px ;
            text-align: center;
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <table>
        <tr>
            <th>编号</th>
            <th>卡号</th>
            <th>金额</th>
        </tr>
    <?php foreach ($rs as $value):?>
    <tr>
        <td><?php echo  $value['id']?></td>
        <td><?php echo $value['carNo']?></td>
        <td><?php echo $value['money']?></td>
    </tr>
    <?php endforeach?>
    </table>
</body>
</html>

 

 

 

<?php 

    //加载Model基础类并继承
    include 'Model.class.php';
    //显示my_bank表模型类
    class Mybank extends Model
    {
        /**
         * 获取my_bank下的说有数据
         * @param string sql语句
         * @return array 结果集
         */
        public function showTable($sql){
            //this->pdo 是继承父类基础模型MyPDO的对象
            return $this->pdo->fetchAll($sql);
        }
    }
posted @ 2021-01-24 12:50  WhiteSpace  阅读(127)  评论(0编辑  收藏  举报