1.什么是单例模式?
1. 含义
单例模式作为一种对象创建模式,保证某个类只有一个实例,并实例化自身并将该实例全局提供给整个系统。 它不创建实例的副本,而是返回对存储在单例类中的实例的引用。
2、单例模式的三个要点:
(1). 需要一个静态成员变量来保存类的唯一实例:
$;
(2)。 构造函数和克隆函数必须声明为私有,以防止外部程序new class失去单例模式的意义:
private function __construct() { $this->_db = pg_connect('xxxx'); } private function __clone() { }//覆盖__clone()方法,禁止克隆
(3)。 必须提供一个公共静态方法(通常是一个方法)来访问该实例,从而返回对唯一实例的引用
public static function getInstance() { if(! (self::$_instance instanceof self) ) { self::$_instance = new self(); } return self::$_instance; }
登录复制
二、为什么要使用单例模式?
1.PHP的缺点:
PHP 语言是一种解释性脚本语言。 这种运行机制使得每个PHP页面解释执行后,所有相关资源都可以被回收。 也就是说,PHP在语言层面上没有办法让一个对象常驻内存,这一点与Java、Java等编译类型不同。 在页面级别,可以真正实现该实例在应用程序生命周期中的唯一性。 然而,在 PHP 中,所有变量,无论是全局变量还是类的静态成员,都是页面级的。 每执行一个页面,就会重新创建一个新的对象,页面执行完毕后会被清除。 看来 PHP 单例模式没什么意义,所以我觉得 PHP 单例模式只有在单个页面级请求有多个应用场景,需要共享同一个对象资源的时候才非常有意义。
2. PHP中单例模式的应用场合:
(1)、应用程序与数据库交互
应用程序中会有大量的数据库操作,比如通过数据库句柄连接数据库的行为。 使用单例模式可以避免大量的新操作,因为每个新操作都会消耗内存资源和系统资源。
(2)、控制配置信息
如果系统中需要一个类来全局控制某些配置信息,那么使用单例模式会非常方便。
3、单例模式如何实现?
1、常见数据库访问示例:
addUserInfo(...); ...... //在函数中访问数据库,查找用户信息 function getUserInfo() { $db = new DB(...);//再次new 数据库类,和数据库建立连接 $db = query(....);//根据查询语句访问数据库 } ?>
登录复制
2、应用单例模式操作数据库:
nstruct(...) { $this->_db = pg_connect(...);//postgrsql } private function __clone() {}; //覆盖__clone()方法,禁止克隆 public static function getInstance() { if(! (self::$_instance instanceof self) ) { self::$_instance = new self(); } return self::$_instance; } public function addUserInfo(...) { } public function getUserInfo(...) { } } //test $db = DB::getInstance(); $db->addUserInfo(...); $db->getUserInfo(...); ?>
登录复制
以下代码是对PDO操作数据库类的封装,采用单例模式:
nstruct($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() {} 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; } 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; } 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; } 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; } 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; } 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; } } public function execSql($strSql, $debug = false) { if ($debug === true) $this->debug($strSql); $result = $this->dbh->exec($strSql); $this->getPDOError(); return $result; } 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; } 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']; } public function getTableEngine($dbName, $tableName) { $strSql = "SHOW TABLE STATUS FROM $dbName WHERE Name='".$tableName."'"; $arrayTableInfo = $this->query($strSql); $this->getPDOError(); return $arrayTableInfo[0]['Engine']; } private function beginTransaction() { $this->dbh->beginTransaction(); } private function commit() { $this->dbh->commit(); } private function rollback() { $this->dbh->rollback(); } 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; } } 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."); } } } 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; } private function getPDOError() { if ($this->dbh->errorCode() != '00000') { $arrayError = $this->dbh->errorInfo(); $this->outputError($arrayError[2]); } } private function debug($debuginfo) { var_dump($debuginfo); exit(); } private function outputError($strErrMsg) { throw new Exception('MySQL Error: '.$strErrMsg); } public function destruct() { $this->dbh = null; } } ?>
登录复制
调用方法:
query("select count(*) frome table"); $db->destruct(); ?>
登录复制