魔術方法是 PHP 物件模型的核心特性,以雙下劃線 __ 開頭,在特定生命週期自動觸發。掌握它們能讓類設計更靈活、更符合框架開發規範。
| 方法 | 觸發時機 | 典型用途 |
|---|---|---|
__construct() | 實例化對象時 | 初始化屬性、依賴注入、資源連接 |
__destruct() | 對象銷毀/腳本結束 | 關閉連接、釋放資源、寫入日誌 |
__call($name, $args) | 調用不可訪問方法 | 動態代理、方法別名、錯誤友好提示 |
__callStatic($name, $args) | 靜態調用不可訪問方法 | 靜態工廠、鏈式調用入口 |
__get($name) | 讀取不可訪問屬性 | 動態屬性、懶加載、數據映射 |
__set($name, $value) | 寫入不可訪問屬性 | 屬性驗證、自動轉換、觸發事件 |
__isset($name) | isset()/empty() 檢測不可訪問屬性 | 配合 __get 實現完整屬性訪問控制 |
__unset($name) | unset() 不可訪問屬性 | 清理動態屬性、緩存失效 |
__toString() | 對象作為字符串使用 | 調試輸出、模板渲染、日誌記錄 |
__invoke() | 對象作為函數調用 | 閉包替代、策略模式、可調用對象 |
__clone() | clone 複製對象時 | 深拷貝、重置資源 ID、生成唯一標識 |
__sleep() | serialize() 序列化前 | 清理臨時數據、指定序列化屬性白名單 |
__wakeup() | unserialize() 反序列化後 | 重建連接、初始化資源、安全驗證 |
__set_state($arr) | var_export() 導出類時 | 自定義導出格式、單例模式還原 |
__debugInfo() | var_dump() 輸出對象時 | 隱藏敏感屬性、格式化調試輸出 |
__construct 和同名方法時,只調用 __constructprivate、protected、不存在 三種情況__sleep 必須返回數組: 指定需序列化的屬性名,返回空數組則不序列化任何屬性__wakeup 安全風險: 反序列化可實例化任意類,敏感操作需驗證__toString 必須返回字符串: 否則拋出 E_RECOVERABLE_ERRORclass Model {
protected $data = [];
protected $dirty = [];
public function __get($name) {
return $this->data[$name] ?? null;
}
public function __set($name, $value) {
$this->dirty[$name] = true;
$this->data[$name] = $value;
}
public function __isset($name) {
return isset($this->data[$name]);
}
public function __unset($name) {
unset($this->data[$name], $this->dirty[$name]);
}
public function __toString() {
return get_class($this) . ': ' . json_encode($this->data);
}
public function save() {
// 僅更新 dirty 屬性...
}
}
善用魔術方法,能編寫出既優雅又強大的 PHP 類庫,是進階 PHPer 必修內功。