先來看一個最簡單的單例模式的實現:
運行結果如下:

但是光是這樣寫嚴格意義上來講並不是真正的單例模式,因為用戶完全可以通過new關鍵詞來實例化新的對象。
$test1 = new Singleton(); $test2 = new Singleton();運行結果如下:

所以我們要對我們的代碼做一點改進,將構造方法的訪問級別設置為protected:
這時當用戶試圖以new關鍵詞實例化一個新的對象時,會報如下截圖所示的錯誤:

當然,狡猾的用戶還是可以通過clone關鍵詞來克隆一個新對象:
$test1 = Singleton::getInstance();
$test2 = clone $test1;
if($test1 === $test2){
echo 是同一個對象;
}else{
echo 不是同一個對象;
}

所以我們還要把__clone方法聲明為protected:
時當用戶試圖以clone關鍵詞克隆一個新的對象時,會報如下截圖所示的錯誤:

所以要嚴格意義上實現一個單例模式,要注意的有以下幾點:
1、將構造函數聲明為protected;
2、創建一個getInstance的靜態方法來獲取保存該類的靜態變量;
3、將__clone方法聲明為protected
當然在實際的開發中,大部分情況下只要實現簡單的單例模式就行了(第一個例子的寫法)。