模型類的單例模式

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

思考:如何保證模型類的單例呢?

典型的,可以通過一個單例的工廠來實現!( 爲什麼不用三私一公呢?因爲基本上所有的模型類都需要單例模式,把所有的模型類都修改爲三私一公比較麻煩

而且通過單例工廠來實現更加靈活);

 

代碼展示

  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基礎模型類
require './Model.class.php';
//轉賬模型類,有多麼功能就封裝什麼方法就行
class Mybank extends Moudel
{
    //基礎模型類中 已經繼承到方法直接用就行
      //定義轉賬方法
      public function zhuanZ($out,$in,$money){
          //這裏的$this->pdo 就是父類基礎模型下的pdo
        return $this->pdo->beginTransction("update my_bank set money=money-$money where carNo=$out","update my_bank set money=money+$money where carNo=$in");
    }
}

 

5.Controller 控制器,它負責調用模型和視圖

 

<?php 
    //控制器調用視圖 view.html
    require 'index.html';


    //通過工廠得到模型類的單例對象
    include 'Factory.class.php';



    if(!empty($_GET)){
        $out=$_GET['out'];
        $in=$_GET['in'];
        $money=$_GET['money'];
        //通過Factory單例工廠,實例化Mybank類 
        $ban=Factory::M("Mybank");
        echo $ban->zhuanZ($out,$in,$money);     //成功轉賬
       
    }

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>
</head>
<body>
    <form action="" method="get">
        轉出卡號:<input type="text" name="out" id=""><br>
        轉入卡號:<input type="text" name="in" id=""><br>
        金額:<input type="text" name="money" id=""><br>
        <input type="submit" value="轉賬">
    </form>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章