ClassName::$prop、ClassName::method())$obj->prop 存取,但靜態方法可透過物件呼叫$this,無法存取非靜態成員PHP 5.3 引入 static:: 關鍵字,解決繼承體系中「誰在呼叫」的問題:
self:: 永遠解析為定義該方法的類別(編譯期綁定)static:: 解析為實際呼叫的類別(執行期綁定)get_called_class() 可取得實際被呼叫的類別名稱<?php
class Vehicle {
protected static $name = 'This is a Vehicle';
public static function what_vehicle() {
echo get_called_class() . "\n"; // 顯示實際呼叫類別
echo self::$name . "\n"; // 編譯期綁定:Vehicle
}
}
class Sedan extends Vehicle {
protected static $name = 'This is a Sedan';
}
Sedan::what_vehicle();
// 輸出:
// Sedan
// This is a Vehicle ← self 綁定父類別
<?php
class Vehicle {
protected static $name = 'This is a Vehicle';
public static function what_vehicle() {
echo get_called_class() . "\n";
echo static::$name . "\n"; // 執行期綁定:Sedan
}
}
class Sedan extends Vehicle {
protected static $name = 'This is a Sedan';
}
Sedan::what_vehicle();
// 輸出:
// Sedan
// This is a Sedan ← static 綁定子類別
abstract class Model {
protected static $table = '';
public static function find($id) {
// 使用 static:: 取得子類別定義的 table
$table = static::$table;
$class = get_called_class();
// ... 執行查詢並回傳 $class 實例
}
}
class User extends Model {
protected static $table = 'users';
}
$user = User::find(1); // 正確使用 users 表
parent::、self::、static::、forward_static_call() 均屬「轉發呼叫」,不會更新 LSB 記錄的類別static::$prop 仍指向父類別記憶體(共享值)self:: 適合呼叫不應被覆寫的內部實作細節;static:: 適合擴充點(如工廠方法、Active Record)理解 self(早期綁定)與 static(後期綁定)的差異,是掌握 PHP 物件導向繼承機制的關鍵。善用 LSB 能編寫出更彈性、可擴充的基類別架構。