所有的單例模式至少擁有以下三種公共元素:
1. 它們必須擁有一個構造函數,並且必須被標記爲private
2. 它們擁有一個保存類的實例的靜態成員變量
3. 它們擁有一個訪問這個實例的公共的靜態方法
單例類不能再其它類中直接實例化,只能被其自身實例化。它不會創建實例副本,而是會向單例類內部存儲的實例返回一個引用。
使用單例模式的情況
1、php的應用主要在於數據庫應用, 所以一個應用中會存在大量的數據庫操作, 使用單例模式, 則可以避免大量的new 操作消耗的資源。
2、如果系統中需要有一個類來全局控制某些配置信息, 那麼使用單例模式可以很方便的實現. 這個可以參看ZF的FrontController部分。
3、在一次頁面請求中, 便於進行調試, 因爲所有的代碼(例如數據庫操作類db)都集中在一個類中, 我們可以在類中設置鉤子, 輸出日誌,從而避免到處var_dump, echo。
代碼實現
<?php
class databass {
//保存類實例的靜態成員變量
private static $_instance = null;
private function __construct(){
echo 'This is a Constructed method;';
}
//創建__clone方法防止對象被複制克隆
public function __clone(){
trigger_error('clone is not allow!',E_USER_ERROR);
}
//單例方法,用於訪問實例的公共的靜態方法
public static function getinstance(){
if(!(self::$_instance instanceof databass)){
self::$_instance = new databass();
}
return self::$_instance;
}
public function test(){
echo "調用成功!!";
}
}
//用new實例化private標記構造函數的類會報錯
$databass = new databass();
//正確方法,用雙冒號::操作符訪問靜態方法獲取實例
$databass = databass::getinstance();
$databass->test();
//複製(克隆)對象將導致一個E_USER_ERROR
$databass_clone = clone $databass;
?>