如果在一個功能中(控制器),需要使用某個表的多次操作,應該使用該表的一個模型就可以完成全部的任務!
思考:如何保證模型類的單例呢?
典型的,可以通過一個單例的工廠來實現!( 爲什麼不用三私一公呢?因爲基本上所有的模型類都需要單例模式,把所有的模型類都修改爲三私一公比較麻煩
而且通過單例工廠來實現更加靈活);
代碼展示
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>