PHP 5.3 引入的靜態延遲綁定(Late Static Binding,簡稱 LSB)解決了繼承體系中靜態方法調用的經典難題。在 LSB 出現之前,self:: 關鍵字總是解析為定義該方法的類,而非實際調用的子類。這導致在父類的靜態方法中引用靜態屬性或調用靜態方法時,無法正確獲取子類覆寫的版本。
static::static:: 在運行時根據實際調用的類進行解析,而非編寫代碼時的類。這使得「模板方法模式」在靜態上下文中成為可能。
<?php
class A {
protected static $def = '123456';
public static function test() {
// 獲取實際調用的類名
echo get_class(new static);
}
public static function test2() {
// 訪問實際調用類的靜態屬性
echo static::$def;
}
}
class B extends A {
protected static $def = '456789';
}
class C extends A {
protected static $def = 'abcdef';
}
// 測試輸出
echo B::test(); // 輸出: B
echo "<br>";
echo C::test(); // 輸出: C
echo "<br>";
echo B::test2(); // 輸出: 456789
echo "<br>";
echo C::test2(); // 輸出: abcdef
echo "<br>";
echo A::test(); // 輸出: A
echo "<br>";
echo A::test2(); // 輸出: 123456
?>
| 關鍵字 | 解析時機 | 繼承場景表現 |
|---|---|---|
self:: |
編譯期 | 永遠指向定義該方法的類 |
static:: |
運行期 | 指向實際調用的子類 |
find()、save() 方法,子類只需聲明表名。create() 靜態工廠方法,自動實例化正確的子類。static:: 僅能用於靜態上下文(靜態方法、靜態屬性、靜態常量)。get_called_class() 可獲取調用類的完整命名空間名稱。static:: 也可用於常量解析(如 static::CONSTANT)。掌握靜態延遲綁定,能讓你設計出更靈活、可復用的靜態類體系,是現代 PHP 開發的必備技能。