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

PHP static 靜態變數與靜態成員完整指南:函數、類別、延遲綁定與 C# 對比

     編輯:PHP 綜合知識

兩大應用脈絡

層級關鍵字位置生命週期可見範圍
函數內區域變數function foo() { static $x = 0; }腳本執行期間**永久存活**僅該函數內部
類別靜態成員class A { static $x; static function f() {} }類別被載入到腳本結束全域 (透過 A::$x、self::$x、parent::$x)

函數靜態變數:記住上一次的值

function counter() {
    static $count = 0; // 只在第一次呼叫初始化
    $count++;
    echo "$count
"; } counter(); // 1 counter(); // 2 counter(); // 3

應用場景:遞迴計數、快取昂貴計算結果、單次初始化資源 (如資料庫連線)。

類別靜態屬性與方法

class Config {
    public static string $appName = 'MyApp';
    protected static array $cache = [];
    
    public static function get(string $key, $default = null) {
        return self::$cache[$key] ?? $default;
    }
    
    public static function set(string $key, $value): void {
        self::$cache[$key] = $value;
    }
}

// 存取方式
echo Config::$appName;        // 類別名稱::
Config::set('debug', true);
$debug = Config::get('debug');

關鍵字對比:self vs static vs $this

關鍵字綁定時機指向可用於
self::**編譯期** (早期綁定)**定義該類別**的類別靜態屬性、靜態方法、常數
static::**執行期** (晚期靜態綁定 LSB)**實際被呼叫**的類別 (子類別)靜態屬性、靜態方法
$this->執行期當前**實例物件**實例屬性、實例方法
parent::編譯期直接**父類別**覆寫時呼叫父實作

LSB 實戰:可被子類別覆寫的靜態工廠

class Model {
    protected static string $table = 'models';
    
    public static function create(array $data): self {
        // 這裡用 static:: 而非 self::
        return new static($data); // 實際 new 的是子類別
    }
}

class User extends Model {
    protected static string $table = 'users';
}

$user = User::create(['name' => 'John']); // 回傳 User 實例

靜態建構子模式 (PHP 無原生支援)

class Service {
    public static string $config;
    
    public static function init(): void {
        // 複雜初始化邏輯:讀檔、連線、驗證
        self::$config = json_decode(file_get_contents(__DIR__.'/config.json'), true);
    }
}

// 類別定義後立即呼叫 (或在啟動腳本)
Service::init();

繼承體系下的靜態成員存取規則

class A {
    public static $x = 'A';
    public static function who() { echo self::$x; }      // 早期綁定 → A
    public static function whoLate() { echo static::$x; } // 晚期綁定 → 看誰呼叫
}

class B extends A {
    public static $x = 'B';
}

A::who();      // A
B::who();      // A (self 綁定在 A)
A::whoLate();  // A
B::whoLate();  // B (static 解析為 B)

PHP vs C# static 差異速查

特性PHPC#
函數內 static 區域變數支援不支援 (需用類別靜態欄位)
靜態類別無 (用 final class + private constructor 模擬)static class 關鍵字
靜態建構子無 (手動 init())static Constructor()
晚期靜態綁定static:: (PHP 5.3+)無 (需泛型/反射模擬)
覆寫靜態方法允許 (隱藏父方法)不允許 (new 隱藏而非覆寫)
存取語法Class::$prop / Class::method()Class.Prop / Class.Method()

常見陷阱

  • 靜態屬性共享陷阱:父子類別若未各自宣告 static $x,會共享同一記憶體位址
  • Trait 靜態成員:每個使用 Trait 的類別都有**獨立副本**
  • 序列化:serialize() **不包含**靜態屬性
  • 單元測試:靜態狀態導致測試相互干擾,需 tearDown 重置或用依賴注入替代
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved