• 单例模式的升华


    的确global可以解决问题,也起到单例模式的作用,但在OOP中,我们拒绝这种编码。因为global存在安全隐患(全局变量不受保护的本质)。

    全局变量是面向对象程序员遇到的引发BUG的主要原因之一。这是因为全局变量将类捆绑于特定的环境,破坏了封装。如果新的应用程序无法保证一开始就定义了相同的全局变量,那么一个依赖于全局变量的类就无法从一个应用程序中提取出来并应用到新应用程序中。

    确切的讲,单例模式恰恰是对全局变量的一种改进,避免那些存储唯一实例的全局变量污染命名空间。你无法用错误类型的数据覆写一个单例。这种保护在不支持命名空间的PHP版本里尤其重要。因为在PHP中命名冲突会在编译时被捕获,并使脚本停止运行.....

    <?php
    /**
     * MyPDO
     * @author Jason.Wei <jasonwei06@hotmail.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();
    ?>
  • 相关阅读:
    mongoose 报错:DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead
    node
    node
    CSS
    JS
    Express
    java Map按Key排序
    Jedis(三)——Hash/List/Set
    Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor
    java中如何给Runnable线程传递参数?
  • 原文地址:https://www.cnblogs.com/matengfei123/p/7080422.html
Copyright © 2020-2023  润新知