PHP基于单例模式编写PDO类的方法

5年以前  |  阅读数:801 次  |  编程语言:PHP 

一、单例模式简介

简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务;

二、为什么要使用PHP单例模式?

 1、php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 使用单例模式, 则可以避免大量的new 操作消耗的资源。  


 2、如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看ZF的`FrontController`部分。  


 3、在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处`var_dump`, `echo`。

三、PHP基于单例模式编写PDO类的示例代码

代码如下:


    <?php
    /**
     * MyPDO
     * @author Jason.Wei <jasonwei06@hotmail.com>
     * @license http://www.sunbloger.com/
     * @version 5.0 utf8
     */
    class MyPDO
    {
     protected static $_instance = null;
     protected $dbName = '';
     protected $dsn;
     protected $dbh;

     /**
      * 构造
      * 
      * @return MyPDO
      */
     private function __construct($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset)
     {
      try {
       $this->dsn = 'mysql:host='.$dbHost.';dbname='.$dbName;
       $this->dbh = new PDO($this->dsn, $dbUser, $dbPasswd);
       $this->dbh->exec('SET character_set_connection='.$dbCharset.', character_set_results='.$dbCharset.', character_set_client=binary');
      } catch (PDOException $e) {
       $this->outputError($e->getMessage());
      }
     }

     /**
      * 防止克隆
      * 
      */
     private function __clone() {}

     /**
      * Singleton instance
      * 
      * @return Object
      */
     public static function getInstance($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset)
     {
      if (self::$_instance === null) {
       self::$_instance = new self($dbHost, $dbUser, $dbPasswd, $dbName, $dbCharset);
      }
      return self::$_instance;
     }

     /**
      * Query 查询
      *
      * @param String $strSql SQL语句
      * @param String $queryMode 查询方式(All or Row)
      * @param Boolean $debug
      * @return Array
      */
     public function query($strSql, $queryMode = 'All', $debug = false)
     {
      if ($debug === true) $this->debug($strSql);
      $recordset = $this->dbh->query($strSql);
      $this->getPDOError();
      if ($recordset) {
       $recordset->setFetchMode(PDO::FETCH_ASSOC);
       if ($queryMode == 'All') {
        $result = $recordset->fetchAll();
       } elseif ($queryMode == 'Row') {
        $result = $recordset->fetch();
       }
      } else {
       $result = null;
      }
      return $result;
     }

     /**
      * Update 更新
      *
      * @param String $table 表名
      * @param Array $arrayDataValue 字段与值
      * @param String $where 条件
      * @param Boolean $debug
      * @return Int
      */
     public function update($table, $arrayDataValue, $where = '', $debug = false)
     {
      $this->checkFields($table, $arrayDataValue);
      if ($where) {
       $strSql = '';
       foreach ($arrayDataValue as $key => $value) {
        $strSql .= ", `$key`='$value'";
       }
       $strSql = substr($strSql, 1);
       $strSql = "UPDATE `$table` SET $strSql WHERE $where";
      } else {
       $strSql = "REPLACE INTO `$table` (`".implode('`,`', array_keys($arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";
      }
      if ($debug === true) $this->debug($strSql);
      $result = $this->dbh->exec($strSql);
      $this->getPDOError();
      return $result;
     }

     /**
      * Insert 插入
      *
      * @param String $table 表名
      * @param Array $arrayDataValue 字段与值
      * @param Boolean $debug
      * @return Int
      */
     public function insert($table, $arrayDataValue, $debug = false)
     {
      $this->checkFields($table, $arrayDataValue);
      $strSql = "INSERT INTO `$table` (`".implode('`,`', array_keys($arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";
      if ($debug === true) $this->debug($strSql);
      $result = $this->dbh->exec($strSql);
      $this->getPDOError();
      return $result;
     }

     /**
      * Replace 覆盖方式插入
      *
      * @param String $table 表名
      * @param Array $arrayDataValue 字段与值
      * @param Boolean $debug
      * @return Int
      */
     public function replace($table, $arrayDataValue, $debug = false)
     {
      $this->checkFields($table, $arrayDataValue);
      $strSql = "REPLACE INTO `$table`(`".implode('`,`', array_keys($arrayDataValue))."`) VALUES ('".implode("','", $arrayDataValue)."')";
      if ($debug === true) $this->debug($strSql);
      $result = $this->dbh->exec($strSql);
      $this->getPDOError();
      return $result;
     }

     /**
      * Delete 删除
      *
      * @param String $table 表名
      * @param String $where 条件
      * @param Boolean $debug
      * @return Int
      */
     public function delete($table, $where = '', $debug = false)
     {
      if ($where == '') {
       $this->outputError("'WHERE' is Null");
      } else {
       $strSql = "DELETE FROM `$table` WHERE $where";
       if ($debug === true) $this->debug($strSql);
       $result = $this->dbh->exec($strSql);
       $this->getPDOError();
       return $result;
      }
     }

     /**
      * execSql 执行SQL语句
      *
      * @param String $strSql
      * @param Boolean $debug
      * @return Int
      */
     public function execSql($strSql, $debug = false)
     {
      if ($debug === true) $this->debug($strSql);
      $result = $this->dbh->exec($strSql);
      $this->getPDOError();
      return $result;
     }

     /**
      * 获取字段最大值
      * 
      * @param string $table 表名
      * @param string $field_name 字段名
      * @param string $where 条件
      */
     public function getMaxValue($table, $field_name, $where = '', $debug = false)
     {
      $strSql = "SELECT MAX(".$field_name.") AS MAX_VALUE FROM $table";
      if ($where != '') $strSql .= " WHERE $where";
      if ($debug === true) $this->debug($strSql);
      $arrTemp = $this->query($strSql, 'Row');
      $maxValue = $arrTemp["MAX_VALUE"];
      if ($maxValue == "" || $maxValue == null) {
       $maxValue = 0;
      }
      return $maxValue;
     }

     /**
      * 获取指定列的数量
      * 
      * @param string $table
      * @param string $field_name
      * @param string $where
      * @param bool $debug
      * @return int
      */
     public function getCount($table, $field_name, $where = '', $debug = false)
     {
      $strSql = "SELECT COUNT($field_name) AS NUM FROM $table";
      if ($where != '') $strSql .= " WHERE $where";
      if ($debug === true) $this->debug($strSql);
      $arrTemp = $this->query($strSql, 'Row');
      return $arrTemp['NUM'];
     }

     /**
      * 获取表引擎
      * 
      * @param String $dbName 库名
      * @param String $tableName 表名
      * @param Boolean $debug
      * @return String
      */
     public function getTableEngine($dbName, $tableName)
     {
      $strSql = "SHOW TABLE STATUS FROM $dbName WHERE Name='".$tableName."'";
      $arrayTableInfo = $this->query($strSql);
      $this->getPDOError();
      return $arrayTableInfo[0]['Engine'];
     }

     /**
      * beginTransaction 事务开始
      */
     private function beginTransaction()
     {
      $this->dbh->beginTransaction();
     }

     /**
      * commit 事务提交
      */
     private function commit()
     {
      $this->dbh->commit();
     }

     /**
      * rollback 事务回滚
      */
     private function rollback()
     {
      $this->dbh->rollback();
     }

     /**
      * transaction 通过事务处理多条SQL语句
      * 调用前需通过getTableEngine判断表引擎是否支持事务
      *
      * @param array $arraySql
      * @return Boolean
      */
     public function execTransaction($arraySql)
     {
      $retval = 1;
      $this->beginTransaction();
      foreach ($arraySql as $strSql) {
       if ($this->execSql($strSql) == 0) $retval = 0;
      }
      if ($retval == 0) {
       $this->rollback();
       return false;
      } else {
       $this->commit();
       return true;
      }
     }

     /**
      * checkFields 检查指定字段是否在指定数据表中存在
      *
      * @param String $table
      * @param array $arrayField
      */
     private function checkFields($table, $arrayFields)
     {
      $fields = $this->getFields($table);
      foreach ($arrayFields as $key => $value) {
       if (!in_array($key, $fields)) {
        $this->outputError("Unknown column `$key` in field list.");
       }
      }
     }

     /**
      * getFields 获取指定数据表中的全部字段名
      *
      * @param String $table 表名
      * @return array
      */
     private function getFields($table)
     {
      $fields = array();
      $recordset = $this->dbh->query("SHOW COLUMNS FROM $table");
      $this->getPDOError();
      $recordset->setFetchMode(PDO::FETCH_ASSOC);
      $result = $recordset->fetchAll();
      foreach ($result as $rows) {
       $fields[] = $rows['Field'];
      }
      return $fields;
     }

     /**
      * getPDOError 捕获PDO错误信息
      */
     private function getPDOError()
     {
      if ($this->dbh->errorCode() != '00000') {
       $arrayError = $this->dbh->errorInfo();
       $this->outputError($arrayError[2]);
      }
     }

     /**
      * debug
      * 
      * @param mixed $debuginfo
      */
     private function debug($debuginfo)
     {
      var_dump($debuginfo);
      exit();
     }

     /**
      * 输出错误信息
      * 
      * @param String $strErrMsg
      */
     private function outputError($strErrMsg)
     {
      throw new Exception('MySQL Error: '.$strErrMsg);
     }

     /**
      * destruct 关闭数据库连接
      */
     public function destruct()
     {
      $this->dbh = null;
     }
    }
    ?>

四、调用方法:


    <?php
    require 'MyPDO.class.php';
    $db = MyPDO::getInstance('localhost', 'root', '123456', 'test', 'utf8');

    //do something...

    $db->destruct();
    ?>

五、总结

以上就是PHP基于单例模式编写PDO类的全部内容,希望对大家学习或者使用PHP能有所帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

 相关文章:
PHP分页显示制作详细讲解
SSH 登录失败:Host key verification failed
获取IMSI
将二进制数据转为16进制以便显示
获取IMEI
文件下载
贪吃蛇
双位运算符
PHP自定义函数获取搜索引擎来源关键字的方法
Java生成UUID
发送邮件
年的日历图
提取后缀名
在Zeus Web Server中安装PHP语言支持
让你成为最历害的git提交人
Yii2汉字转拼音类的实例代码
再谈PHP中单双引号的区别详解
指定应用ID以获取对应的应用名称
Python 2与Python 3版本和编码的对比
php封装的page分页类完整实例