首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 單例模式實作完整指南與最佳實務

     編輯:PHP 相關知識

前言

單例模式確保一個類別僅有一個實例,並提供全域存取點。常用於資料庫連線、日誌記錄、設定管理等全域共享資源。本文展示標準 PHP 單例實作,並說明關鍵細節。

標準單例類別實作

<?php
class Singleton {
    // 唯一實例靜態屬性
    private static ?self $instance = null;

    // 範例業務屬性
    private string $name = '';

    // 私有建構子,防止外部 new
    private function __construct() {}

    // 防止複製
    private function __clone() {}

    // 防止反序列化建立新實例
    public function __wakeup() {
        throw new \Exception("Cannot unserialize singleton");
    }

    // 取得唯一實例
    public static function getInstance(): self {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // 業務方法
    public function getName(): string {
        return $this->name;
    }

    public function setName(string $name): void {
        $this->name = $name;
    }
}

// 使用範例
$s1 = Singleton::getInstance();
$s1->setName('first');
echo "s1 name: {$s1->getName()}\n"; // first

unset($s1); // 釋放變數,但靜態實例仍存在

$s2 = Singleton::getInstance();
echo "s2 name: {$s2->getName()}\n"; // first(同一實例)
echo "同一實例? " . ($s1 === $s2 ? '是' : '否') . "\n"; // 是
?>

關鍵點解析

  • private __construct:阻止 new Singleton()。
  • private __clone:阻止 clone $singleton。
  • __wakeup:阻止 unserialize() 重建實例。
  • static $instance:儲存唯一實例,生命週期貫穿整個請求。
  • 型別宣告:PHP 7.4+ 支援 ?self、string 等型別提示。

進階:延遲初始化與執行緒安全

PHP 為單執行緒模型(CLI/FPM),getInstance() 的 if (null) 檢查足夠。若使用 Swoole/RoadRunner 等多執行緒環境,需加鎖:

public static function getInstance(): self {
    if (self::$instance === null) {
        // 簡易鎖(僅示意,生產環境請用 Mutex/Semaphore)
        $lock = fopen(__FILE__, 'r');
        flock($lock, LOCK_EX);
        if (self::$instance === null) {
            self::$instance = new self();
        }
        flock($lock, LOCK_UN);
        fclose($lock);
    }
    return self::$instance;
}

常見誤區

  • ❌ 將單例當作全域變數濫用,導致耦合度高、難以單元測試。
  • ❌ 建構子執行重度邏輯(如資料庫連線),應改為延遲初始化或依賴注入。
  • ✅ 適合:Logger、Config、DB Connection Pool 等真正需要全域唯一的服務。

總結

單例模式在 PHP 中實作簡單,但需謹慎使用。掌握私有建構子、防複製、防反序列化三大要素,即可寫出健壯的單例類別。希望本文對您的 PHP 程式設計有所幫助。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved