萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP單例模式學習筆記詳解

PHP單例模式學習筆記詳解

單例模式是php中一個為了簡化大家開發及重復調用的一個功能,下面我來給各位朋友詳細介紹單例模式用法。

1.單例模式的概念

顧名思義,單例模式只有一個實例,而且自行實例化,向全局提供這個實例。需要強調的是,單例模式

確保某個類只能有一個實例!

2.單例模式的三個要點

(1)需要一個靜態變量來保存類的唯一實例

 代碼如下 復制代碼

private static $_instance;

(2)構造函數和克隆函數必須為私有的,防止用戶創建對象和復制實例對象

 代碼如下 復制代碼

private function __construct()
{
//私有化默認構造方法,防止外界直接實例化
}
private function __clone()
{
//私有化克隆方法,防止用戶復制實例
}

(3)必須提供一個公共的靜態方法(一般為getInstance),從而返回一個唯一實例的引用

 代碼如下 復制代碼 public static function getInstance()   
{   
    if(! (self::$_instance instanceof self) )  
    {   
        self::$_instance = new self();   
    } 
    return self::$_instance;   
 
}

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學

習中深刻理解單例模式的應用。

copyright © 萬盛學電腦網 all rights reserved