PHP 中以雙底線 __ 開頭的方法稱為魔術方法,會在特定情況下自動被呼叫,提供物件導向程式設計的強大擴展能力。
| 方法 | 觸發時機 | 用途 |
|---|---|---|
__construct() | 物件實例化時 | 初始化屬性、資源連線 |
__destruct() | 物件銷毀時 | 釋放資源、關閉連線 |
__set() | 設定不可見/不存在屬性 | 動態屬性寫入、資料驗證 |
__get() | 讀取不可見/不存在屬性 | 動態屬性讀取、延遲載入 |
__call() | 呼叫不可見/不存在方法 | 動態方法處理、代理模式 |
__callStatic() | 靜態呼叫不可見/不存在方法 | 靜態動態方法處理 |
__clone() | 物件複製時 | 深層複製、資源重新分配 |
嘗試設定不存在或不可見屬性時觸發:
function __set($name, $value) {
// $name: 動態屬性名稱
// $value: 要設定的值
// 實作邏輯:驗證、記錄、轉存等
$this->data[$name] = $value;
}
嘗試讀取不存在或不可見屬性時觸發:
function __get($name) {
// $name: 動態屬性名稱
// 實作邏輯:回傳預設值、計算屬性、拋出異常等
return isset($this->data[$name]) ? $this->data[$name] : null;
}
嘗試呼叫不存在或不可見方法時觸發:
function __call($name, $arguments) {
// $name: 方法名稱
// $arguments: 參數陣列
// 實作邏輯:方法代理、動態路由等
echo "呼叫不存在的方法: $name";
}
function __callStatic($name, $arguments) {
// 靜態上下文中的動態方法處理
}
物件被 clone 關鍵字複製時自動呼叫,用於處理參考型屬性:
function __clone() {
// 為參考型屬性重新分配記憶體
$this->relatedObject = clone $this->relatedObject;
$this->id = uniqid(); // 重新生成唯一識別碼
}
class DynamicEntity {
private $attributes = [];
public function __set($name, $value) {
$this->attributes[$name] = $value;
}
public function __get($name) {
return $this->attributes[$name] ?? null;
}
public function __call($name, $arguments) {
if (strpos($name, 'get') === 0) {
$field = lcfirst(substr($name, 3));
return $this->$field;
}
throw new BadMethodCallException("Method $name not found");
}
}
$entity = new DynamicEntity();
$entity->name = 'PHP'; // 觸發 __set
echo $entity->name; // 觸發 __get,輸出 PHP
$entity->getName(); // 觸發 __call,輸出 PHP
__clone 必須處理參考型屬性,避免淺層複製導致資料共享問題__call) 適合代理模式、ORM 欄位存取器等場景