模型类的单例模式
如果在一个功能中(控制器),需要使用某个表的多次操作,应该使用该表的一个模型就可以完成全部的任务!
思考:如何保证模型类的单例呢?
典型的,可以通过一个单例的工厂来实现!( 为什么不用三私一公呢?因为基本上所有的模型类都需要单例模式,把所有的模型类都修改为三私一公比较麻烦
而且通过单例工厂来实现更加灵活);
代码展示
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);
}
}