多態性是物件導向三大支柱之一。PHP 5 引入了介面、抽象類、類型提示,但缺乏原生晚期靜態綁定(LSB)導致靜態方法多態受限。PHP 5.3 引入 static:: 關鍵字徹底解決此問題。本文剖析 PHP 多態的實現機制與演進。
interface CacheDriver {
public function get($key);
public function set($key, $value, $ttl);
}
class RedisCache implements CacheDriver { /* ... */ }
class MemcachedCache implements CacheDriver { /* ... */ }
function warmUp(CacheDriver $driver) { /* 依賴介面而非具體類 */ }
執行期根據傳入物件實際類型動態分派方法,這是 PHP 最自然的多態形式。
abstract class PaymentGateway {
abstract public function charge($amount);
public function process($amount) {
$this->validate($amount);
$this->charge($amount); // 多態調用
$this->notify();
}
}
class StripeGateway extends PaymentGateway { public function charge($amount) { /* ... */ } }
class PayPalGateway extends PaymentGateway { public function charge($amount) { /* ... */ } }
class Model {
public static function tableName() { return 'base'; }
public static function findAll() {
$table = self::tableName(); // 編譯期綁定到 Model
return "SELECT * FROM $table";
}
}
class User extends Model {
public static function tableName() { return 'users'; }
}
User::findAll(); // 返回 "SELECT * FROM base" ❌
self:: 在定義時靜態綁定,無法實現靜態方法多態。
class Model {
public static function findAll() {
$table = static::tableName(); // 執行期綁定到實際調用類
return "SELECT * FROM $table";
}
}
User::findAll(); // 返回 "SELECT * FROM users" ✅
static:: 關鍵字使靜態方法具備多態能力,Active Record、Factory 模式得以優雅實現。
interface,類別 implements,依賴注入容器綁定實現。static::: 靜態工廠、Eloquent 模型查詢構建器鏈式調用。mixed、static 回傳型別,編譯期捕獲多態錯誤。動態分派(虛函數表查找)在 PHP 中極快(納秒級),瓶頸通常在 IO。LSB 只在靜態調用點增加一次執行期查找,影響可忽略。
掌握 PHP 多態機制,能讓您設計出可擴展、可測試、符合開閉原則的領域模型,是進階 PHP 開發者的必修內功。