確保類別在系統中只有一個實例,並提供全域存取點。三要素:唯一實例、自行建立、全域提供。
class Example {
private static $_instance = null;
// 私有建構子,防外部 new
private function __construct() {
echo 'I am Constructed';
}
// 靜態方法取得實例
public static function singleton() {
if (!isset(self::$_instance)) {
$c = __CLASS__;
self::$_instance = new $c();
}
return self::$_instance;
}
// 防止克隆
public function __clone() {
trigger_error('Clone not allowed', E_USER_ERROR);
}
public function test() {
echo "test";
}
}
// 使用
$obj = Example::singleton(); // 正確
$obj->test();
// 錯誤示範
// $obj = new Example; // Fatal: 建構子私有
// $clone = clone $obj; // E_USER_ERROR
| 要素 | 實作方式 | 目的 |
|---|---|---|
| 靜態私有屬性 | private static $_instance | 儲存唯一實例 |
| 私有建構子 | private __construct() | 阻擋 new Example() |
| 私有克隆 | private __clone() | 阻擋 clone $obj |
| 公開靜態方法 | public static singleton() | 唯一取得實例管道 |
| ::__CLASS__ | 動態取得類別名 | 支援繼承時正確實例化 |
PHP 採用 Share-Nothing 架構,每個請求獨立進程,請求結束記憶體完全釋放。
因此 PHP 單例不跨請求持久化,僅在單次請求內保證唯一。
理解單例本質,並在適當場景使用,避免濫用造成強耦合。