PHP单例模式是什么 php实现单例模式的方法
一、什么是单例模式?
1、含义
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
2、单例模式的三个要点:
(1).需要一个保存类的唯一实例的静态成员变量:
privatestatic$_instance;
(2).构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义:
privatefunction__construct() { $this->_db=pg_connect('xxxx'); } privatefunction__clone() { }//覆盖__clone()方法,禁止克隆
(3).必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用
publicstaticfunctiongetInstance() { if(!(self::$_instanceinstanceofself)) { self::$_instance=newself(); } returnself::$_instance; }
二、为什么要使用单例模式?
1、PHP缺点:
PHP语言是一种解释型的脚本语言,这种运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收。也就是说,PHP在语言级别上没有办法让某个对象常驻内存,这和asp.net、Java等编译型是不同的,比如在Java中单例会一直存在于整个应用程序的生命周期里,变量是跨页面级的,真正可以做到这个实例在应用程序生命周期中的唯一性。然而在PHP中,所有的变量无论是全局变量还是类的静态成员,都是页面级的,每次页面被执行时,都会重新建立新的对象,都会在页面执行完毕后被清空,这样似乎PHP单例模式就没有什么意义了,所以PHP单例模式我觉得只是针对单次页面级请求时出现多个应用场景并需要共享同一对象资源时是非常有意义的。
2、单例模式在PHP中的应用场合:
(1)、应用程序与数据库交互
一个应用中会存在大量的数据库操作,比如过数据库句柄来连接数据库这一行为,使用单例模式可以避免大量的new操作,因为每一次new操作都会消耗内存资源和系统资源。
(2)、控制配置信息
如果系统中需要有一个类来全局控制某些配置信息,那么使用单例模式可以很方便的实现.
三、如何实现单例模式?
1、普通的数据库访问例子:
<?php ...... //初始化一个数据库句柄 $db=newDB(...); //添加用户信息 $db->addUserInfo(...); ...... //在函数中访问数据库,查找用户信息 functiongetUserInfo() { $db=newDB(...);//再次new数据库类,和数据库建立连接 $db=query(....);//根据查询语句访问数据库 } ?>
2、应用单例模式对数据库进行操作:
<?php classDB { private$_db; privatestatic$_instance; privatefunction__construct(...) { $this->_db=pg_connect(...);//postgrsql } privatefunction__clone(){};//覆盖__clone()方法,禁止克隆 publicstaticfunctiongetInstance() { if(!(self::$_instanceinstanceofself)){ self::$_instance=newself(); } returnself::$_instance; } publicfunctionaddUserInfo(...) { } publicfunctiongetUserInfo(...) { } } //test $db=DB::getInstance(); $db->addUserInfo(...); $db->getUserInfo(...); ?>
下面的代码是PDO操作数据库类的一个封装,采用了单例模式:
<?php /** *MyPDO */ classMyPDO { protectedstatic$_instance=null; protected$dbName=''; protected$dsn; protected$dbh; /** *构造 * *@returnMyPDO */ privatefunction__construct($dbHost,$dbUser,$dbPasswd,$dbName,$dbCharset) { try{ $this->dsn='mysql:host='.$dbHost.';dbname='.$dbName; $this->dbh=newPDO($this->dsn,$dbUser,$dbPasswd); $this->dbh->exec('SETcharacter_set_connection='.$dbCharset.',character_set_results='.$dbCharset.',character_set_client=binary'); }catch(PDOException$e){ $this->outputError($e->getMessage()); } } /** *防止克隆 * */ privatefunction__clone(){} /** *Singletoninstance * *@returnObject */ publicstaticfunctiongetInstance($dbHost,$dbUser,$dbPasswd,$dbName,$dbCharset) { if(self::$_instance===null){ self::$_instance=newself($dbHost,$dbUser,$dbPasswd,$dbName,$dbCharset); } returnself::$_instance; } /** *Query查询 * *@paramString$strSqlSQL语句 *@paramString$queryMode查询方式(AllorRow) *@paramBoolean$debug *@returnArray */ publicfunctionquery($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更新 * *@paramString$table表名 *@paramArray$arrayDataValue字段与值 *@paramString$where条件 *@paramBoolean$debug *@returnInt */ publicfunctionupdate($table,$arrayDataValue,$where='',$debug=false) { $this->checkFields($table,$arrayDataValue); if($where){ $strSql=''; foreach($arrayDataValueas$key=>$value){ $strSql.=",`$key`='$value'"; } $strSql=substr($strSql,1); $strSql="UPDATE`$table`SET$strSqlWHERE$where"; }else{ $strSql="REPLACEINTO`$table`(`".implode('`,`',array_keys($arrayDataValue))."`)VALUES('".implode("','",$arrayDataValue)."')"; } if($debug===true)$this->debug($strSql); $result=$this->dbh->exec($strSql); $this->getPDOError(); return$result; } /** *Insert插入 * *@paramString$table表名 *@paramArray$arrayDataValue字段与值 *@paramBoolean$debug *@returnInt */ publicfunctioninsert($table,$arrayDataValue,$debug=false) { $this->checkFields($table,$arrayDataValue); $strSql="INSERTINTO`$table`(`".implode('`,`',array_keys($arrayDataValue))."`)VALUES('".implode("','",$arrayDataValue)."')"; if($debug===true)$this->debug($strSql); $result=$this->dbh->exec($strSql); $this->getPDOError(); return$result; } /** *Replace覆盖方式插入 * *@paramString$table表名 *@paramArray$arrayDataValue字段与值 *@paramBoolean$debug *@returnInt */ publicfunctionreplace($table,$arrayDataValue,$debug=false) { $this->checkFields($table,$arrayDataValue); $strSql="REPLACEINTO`$table`(`".implode('`,`',array_keys($arrayDataValue))."`)VALUES('".implode("','",$arrayDataValue)."')"; if($debug===true)$this->debug($strSql); $result=$this->dbh->exec($strSql); $this->getPDOError(); return$result; } /** *Delete删除 * *@paramString$table表名 *@paramString$where条件 *@paramBoolean$debug *@returnInt */ publicfunctiondelete($table,$where='',$debug=false) { if($where==''){ $this->outputError("'WHERE'isNull"); }else{ $strSql="DELETEFROM`$table`WHERE$where"; if($debug===true)$this->debug($strSql); $result=$this->dbh->exec($strSql); $this->getPDOError(); return$result; } } /** *execSql执行SQL语句 * *@paramString$strSql *@paramBoolean$debug *@returnInt */ publicfunctionexecSql($strSql,$debug=false) { if($debug===true)$this->debug($strSql); $result=$this->dbh->exec($strSql); $this->getPDOError(); return$result; } /** *获取字段最大值 * *@paramstring$table表名 *@paramstring$field_name字段名 *@paramstring$where条件 */ publicfunctiongetMaxValue($table,$field_name,$where='',$debug=false) { $strSql="SELECTMAX(".$field_name.")ASMAX_VALUEFROM$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; } /** *获取指定列的数量 * *@paramstring$table *@paramstring$field_name *@paramstring$where *@parambool$debug *@returnint */ publicfunctiongetCount($table,$field_name,$where='',$debug=false) { $strSql="SELECTCOUNT($field_name)ASNUMFROM$table"; if($where!='')$strSql.="WHERE$where"; if($debug===true)$this->debug($strSql); $arrTemp=$this->query($strSql,'Row'); return$arrTemp['NUM']; } /** *获取表引擎 * *@paramString$dbName库名 *@paramString$tableName表名 *@paramBoolean$debug *@returnString */ publicfunctiongetTableEngine($dbName,$tableName) { $strSql="SHOWTABLESTATUSFROM$dbNameWHEREName='".$tableName."'"; $arrayTableInfo=$this->query($strSql); $this->getPDOError(); return$arrayTableInfo[0]['Engine']; } /** *beginTransaction事务开始 */ privatefunctionbeginTransaction() { $this->dbh->beginTransaction(); } /** *commit事务提交 */ privatefunctioncommit() { $this->dbh->commit(); } /** *rollback事务回滚 */ privatefunctionrollback() { $this->dbh->rollback(); } /** *transaction通过事务处理多条SQL语句 *调用前需通过getTableEngine判断表引擎是否支持事务 * *@paramarray$arraySql *@returnBoolean */ publicfunctionexecTransaction($arraySql) { $retval=1; $this->beginTransaction(); foreach($arraySqlas$strSql){ if($this->execSql($strSql)==0)$retval=0; } if($retval==0){ $this->rollback(); returnfalse; }else{ $this->commit(); returntrue; } } /** *checkFields检查指定字段是否在指定数据表中存在 * *@paramString$table *@paramarray$arrayField */ privatefunctioncheckFields($table,$arrayFields) { $fields=$this->getFields($table); foreach($arrayFieldsas$key=>$value){ if(!in_array($key,$fields)){ $this->outputError("Unknowncolumn`$key`infieldlist."); } } } /** *getFields获取指定数据表中的全部字段名 * *@paramString$table表名 *@returnarray */ privatefunctiongetFields($table) { $fields=array(); $recordset=$this->dbh->query("SHOWCOLUMNSFROM$table"); $this->getPDOError(); $recordset->setFetchMode(PDO::FETCH_ASSOC); $result=$recordset->fetchAll(); foreach($resultas$rows){ $fields[]=$rows['Field']; } return$fields; } /** *getPDOError捕获PDO错误信息 */ privatefunctiongetPDOError() { if($this->dbh->errorCode()!='00000'){ $arrayError=$this->dbh->errorInfo(); $this->outputError($arrayError[2]); } } /** *debug * *@parammixed$debuginfo */ privatefunctiondebug($debuginfo) { var_dump($debuginfo); exit(); } /** *输出错误信息 * *@paramString$strErrMsg */ privatefunctionoutputError($strErrMsg) { thrownewException('MySQLError:'.$strErrMsg); } /** *destruct关闭数据库连接 */ publicfunctiondestruct() { $this->dbh=null; } } ?>
调用方法:
<?php require'MyPDO.class.php'; $db=MyPDO::getInstance('localhost','root','123456','test','utf8'); $db->query("selectcount(*)frometable"); $db->destruct(); ?>
以上就是本文的全部内容,希望对大家学习php程序设计有所帮助。