1.單例模式的概念
顧名思義,單例模式只有一個實例,而且自行實例化,向全局提供這個實例。需要強調的是,單例模式
確保某個類只能有一個實例!
2.單例模式的三個要點
(1)需要一個靜態變量來保存類的唯一實例
代碼如下 復制代碼private static $_instance;
(2)構造函數和克隆函數必須為私有的,防止用戶創建對象和復制實例對象
代碼如下 復制代碼private function __construct()
{
//私有化默認構造方法,防止外界直接實例化
}
private function __clone()
{
//私有化克隆方法,防止用戶復制實例
}
(3)必須提供一個公共的靜態方法(一般為getInstance),從而返回一個唯一實例的引用
代碼如下 復制代碼 public static function getInstance()3.php中使用單例模式的原因
PHP語言是一種解釋型的腳本語言,這種運行機制使得每個PHP頁面被解釋執行後,所有的相關資
源都會被回收。也就是說,PHP在語言級別上沒有辦法讓某個對象常駐內存,這和asp.net、Java等編譯
型是不同的,比如在Java中單例會一直存在於整個應用程序的生命周期裡,變量是跨頁面級的,真正可
以做到這個實例在應用程序生命周期中的唯一性。然而在PHP中,所有的變量無論是全局變量還是類的靜
態成員,都是頁面級的,每次頁面被執行時,都會重新建立新的對象,都會在頁面執行完畢後被清空,
這樣似乎PHP單例模式就沒有什麼意義了,所以PHP單例模式我覺得只是針對單次頁面級請求時出現多個
應用場景並需要共享同一對象資源時是非常有意義的。
4.如何實現單例模式
代碼如下 復制代碼<?php
/**
* 單例模式示例:Demo
*/
class Demo{
//靜態成員變量,用來保存全局實例
private static $_instance;
//私有化構造方法,保證外界不能直接實例化
private function __construct(){
}
//私有化克隆方法,防止用戶復制實例
private function __clone(){
}
//返還此類的唯一實例
public function getInstance(){
if(!(self::$_instance instanceof self))
{
self::$_instance = new self();
}
return self::$_instance;
}
//這是第一個測試方法
public function test1Function(){
echo '這是第一個測試方法';
}
//這是第二個測試方法
public function test2Function(){
echo '這是第二個測試方法';
}
}
//正確的使用方法
@$demo = Demo::getInstance();
$demo->test1Function();
$demo->test2Function();
//這樣實例化會出錯,因為構造方法為private
//$demo_new = new Demo;
//復制demo會出錯,因為默認的clone方法為private
// $demo_clone = clone $demo;
?>
5.單利模式的應用場合
(1)應用與數據庫的交互,多用於數據庫的連接
(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(...);
?>
深入理解
代碼如下 復制代碼<?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>";
?>
php中有很多的設計模式,其中的單例模式是我們寫代碼的時候較為常用的一種模式,它不但能
夠有效的減少new操作的資源消耗,而且能夠很方便的對某些全局配置信息進行控制!希望大家在php學
習中深刻理解單例模式的應用。