PHP 5 起引入魔術方法,雙底線 __ 開頭保留為魔術方法,建議避免自訂同名方法。
<?php
class Magic {
public function __toString() {
return "hello world!";
}
public function __invoke($x) {
echo "__invoke called with param $x\n";
}
}
$obj = new Magic();
echo $obj; // hello world! (物件當字串用)
$obj(10); // __invoke called with param 10 (物件當函式呼叫)
?>
<?php
class Magic {
public function __call($name, $arguments) {
echo "Calling $name with params: " . implode(", ", $arguments) . "\n";
}
public static function __callStatic($name, $arguments) {
echo "Static call $name with params: " . implode(", ", $arguments) . "\n";
}
}
$obj = new Magic();
$obj->run("para1", "para2"); // Calling run with params: para1, para2
Magic::staticMethod("arg1"); // Static call staticMethod with params: arg1
?>
<?php
class Magic {
private $data = array();
public function __get($name) {
return isset($this->data[$name]) ? $this->data[$name] : "Property $name not found";
}
public function __set($name, $value) {
$this->data[$name] = $value;
echo "Setting $name to $value\n";
}
}
$obj = new Magic();
echo $obj->name; // Property name not found(觸發 __get)
$obj->age = 25; // Setting age to 25(觸發 __set)
echo $obj->age; // 25
?>
<?php
class Magic {
private $data = array();
public function __isset($name) {
echo "__isset invoked for $name\n";
return isset($this->data[$name]);
}
public function __unset($name) {
echo "__unset invoked for $name\n";
unset($this->data[$name]);
}
}
$obj = new Magic();
isset($obj->name); // __isset invoked for name
unset($obj->name); // __unset invoked for name
?>
| 方法 | 觸發時機 | 回傳值 |
|---|---|---|
| __toString | 物件當字串使用 | string |
| __invoke | 物件當函式呼叫 | 任意 |
| __call | 呼叫不存在的實例方法 | 任意 |
| __callStatic | 呼叫不存在的靜態方法 | 任意 |
| __get | 讀取不可存取屬性 | 任意 |
| __set | 寫入不可存取屬性 | void |
| __isset | isset()/empty() 檢查不可存取屬性 | bool |
| __unset | unset() 不可存取屬性 | void |