一、单例模式简介
简单的说,一个对象(在学习设计模式之前,需要比较了解面向对象思想)只负责一个特定的任务;
二、为什么要使用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能有所帮助,如果有疑问大家可以留言交流,谢谢大家对硕编程的支持。
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!