您的位置:首页 > 编程语言 > PHP开发

PHP单例模式

2015-08-19 21:46 573 查看

PHP单例模式

一 什么是单例模式

作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。

二 为什么要使用单例模式

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

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

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

三 单例模式特点

1、构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化。

2、拥有一个保存类的实例的静态成员变量。

3、拥有一个访问这个实例的公共的静态方法(常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到类是否已经被实例化)。

另外,需要创建__clone()方法防止对象被复制(克隆)。

四 哪些场景使用单例模式

1、应用程序与数据库交互

        一个应用中会存在大量的数据库操作,比如过数据库句柄来连接数据库这一行为,使用单例模式可以避免大量的new操作,因为每一次new操作都会消耗内存资源和系统资源。

2、控制配置信息

        如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现.

五 如何实现单例模式

1 普通

<?php
......
//初始化一个数据库句柄
$db = new DB(...);

//添加用户信息
$db->addUserInfo(...);

......

//在函数中访问数据库,查找用户信息
function getUserInfo()
{
$db = new DB(...);//再次new 数据库类,和数据库建立连接
$db = query(....);//根据查询语句访问数据库
}

?>


2 应用

<?php

class DB
{
private $_db;
private static $_instance;

private function __construct(...)
{
$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(...);

?>


3 深入理解

<?php
class db {
public $conn;
public static $sql;
public static $instance=null;
private function __construct(){
require_once('db.config.php');
$this->conn = mysql_connect($db['host'],$db['user'],$db['password']);
if(!mysql_select_db($db['database'],$this->conn)){
echo "失败";
};
mysql_query('set names utf8',$this->conn);
}
public static function getInstance(){
if(is_null(self::$instance)){
self::$instance = new db;
}
return self::$instance;
}
/**
* 查询数据库
*/
public function select($table,$condition=array(),$field = array()){
$where='';
if(!empty($condition)){

foreach($condition as $k=>$v){
$where.=$k."='".$v."' and ";
}
$where='where '.$where .'1=1';
}
$fieldstr = '';
if(!empty($field)){

foreach($field as $k=>$v){
$fieldstr.= $v.',';
}
$fieldstr = rtrim($fieldstr,',');
}else{
$fieldstr = '*';
}
self::$sql = "select {$fieldstr} from {$table} {$where}";
$result=mysql_query(self::$sql,$this->conn);
$resuleRow = array();
$i = 0;
while($row=mysql_fetch_assoc($result)){
foreach($row as $k=>$v){
$resuleRow[$i][$k] = $v;
}
$i++;
}
return $resuleRow;
}
/**
* 添加一条记录
*/
public function insert($table,$data){
$values = '';
$datas = '';
foreach($data as $k=>$v){
$values.=$k.',';
$datas.="'$v'".',';
}
$values = rtrim($values,',');
$datas   = rtrim($datas,',');
self::$sql = "INSERT INTO  {$table} ({$values}) VALUES ({$datas})";
if(mysql_query(self::$sql)){
return mysql_insert_id();
}else{
return false;
};
}
/**
* 修改一条记录
*/
public function update($table,$data,$condition=array()){
$where='';
if(!empty($condition)){

foreach($condition as $k=>$v){
$where.=$k."='".$v."' and ";
}
$where='where '.$where .'1=1';
}
$updatastr = '';
if(!empty($data)){
foreach($data as $k=>$v){
$updatastr.= $k."='".$v."',";
}
$updatastr = 'set '.rtrim($updatastr,',');
}
self::$sql = "update {$table} {$updatastr} {$where}";
return mysql_query(self::$sql);
}
/**
* 删除记录
*/
public function delete($table,$condition){
$where='';
if(!empty($condition)){

foreach($condition as $k=>$v){
$where.=$k."='".$v."' and ";
}
$where='where '.$where .'1=1';
}
self::$sql = "delete from {$table} {$where}";
return mysql_query(self::$sql);

}
public static function getLastSql(){
echo self::$sql;
}
}

$db = db::getInstance();
//$list = $db->select('demo',array('name'=>'tom','password'=>'ds'),array('name','password'));
//echo $db->insert('demo',array('name'=>'最近你啦','password'=>'123'));
//echo $db->update('demo',array("name"=>'xxx',"password"=>'123'),array('id'=>1));
echo $db->delete('demo',array('id'=>'2'));
db::getLastSql();
echo "<pre>";
?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息