特征
- __兩個(gè)下劃線開始
- 不需要顯示的調(diào)用,由某些條件下觸發(fā)(類似數(shù)據(jù)庫中的隱式觸發(fā)器)
__construct()
在對(duì)象初始化時(shí)調(diào)用,通常用來初始化成員變量,或者初始化方法
__destruct()
在對(duì)象銷毀時(shí)調(diào)用,通常用來清理操作
屬性的重載
定義了一個(gè)當(dāng)訪問不存在的屬性和方法時(shí),發(fā)生自定義的操作
__get($name)
在訪問一個(gè)不存在的屬性時(shí)調(diào)用,
class Device {
public function __get($name) {
if(array_key_exists($name, $this->data)) {
return $this->data[$name];
}
return null;
}
}
該魔術(shù)方法最常用的地方就是通過創(chuàng)建一個(gè)“只讀”的屬性來擴(kuò)展訪問控制。在上面的Battery類中,有一個(gè)私有屬性$charge,我們可以通過__get()魔術(shù)方法將該屬性擴(kuò)展為在類外部可讀但不能修改。代碼如下
class Battery {
private $charge = 0;
public function __get($name) {
if(isset($this->$name)) {
return $this->$name;
}
return null;
}
}
__set($name, $value)
__set()魔術(shù)方法在我們嘗試修改一個(gè)不可訪問的屬性時(shí)會(huì)被調(diào)用,它接收兩個(gè)參數(shù),一個(gè)表示屬性的名字,一個(gè)表示屬性的值。示例代碼如下:
class Device {
public function __set($name, $value) {
// use the property name as the array key
$this->data[$name] = $value;
}
}
__isset($name)
__isset()魔術(shù)方法在對(duì)一個(gè)不可訪問的屬性調(diào)用isset()方法時(shí)會(huì)被調(diào)用,它接收一個(gè)參數(shù),表示屬性的名字。它應(yīng)該返回一個(gè)布爾值,用來表示該屬性是否存在。代碼如下:
class Device {
public function __isset($name) {
return array_key_exists($name, $this->data);
}
}
__unset($name)
__unset()魔術(shù)方法在調(diào)用unset()函數(shù)銷毀一個(gè)不能訪問的屬性時(shí)會(huì)被調(diào)用,它接收一個(gè)參數(shù),表述屬性的名字。
__toString()
__toString()在我們將對(duì)象當(dāng)作字符串一樣使用時(shí)會(huì)被調(diào)用,它不接收任何參數(shù)。類似java中的。toString()函數(shù)輸出自定義的信息內(nèi)容。
克隆對(duì)象 __clone()
默認(rèn)的,對(duì)象都是按引用傳值的。因此,在將一個(gè)對(duì)象賦值給另一個(gè)變量時(shí),只是創(chuàng)建了指向該對(duì)象的一個(gè)引用,并沒有復(fù)制該對(duì)象。為了實(shí)現(xiàn)真正得復(fù)制一個(gè)對(duì)象,我們需要使用clone關(guān)鍵字。
這種“按引用傳遞”的策略同樣適用于包含在對(duì)象內(nèi)部的對(duì)象。即使我們克隆了一個(gè)對(duì)象,在對(duì)象內(nèi)部的任何對(duì)象都不會(huì)被克隆,因此最終的結(jié)果是兩個(gè)對(duì)象共享了同一個(gè)內(nèi)部對(duì)象。示例代碼如下:
$device = new Device(new Battery(), 'iMagic');
$device2 = clone $device;
$device->battery->setCharge(65);
echo $device2->battery->charge;
// 65
__clone()魔術(shù)方法__clone()可以解決上面的問題。當(dāng)對(duì)一個(gè)對(duì)象使用clone關(guān)鍵字時(shí),該魔術(shù)方法會(huì)被調(diào)用。在這個(gè)魔術(shù)方法里,我們可以實(shí)現(xiàn)任何子對(duì)象的克隆,代碼如下:
class Device {
...
public function __clone() {
// copy our Battery object
$this->battery = clone $this->battery;
}
...
}
__call()
魔術(shù)方法__call()在調(diào)用不存在或不可訪問的方法時(shí)會(huì)被調(diào)用。它接收兩個(gè)參數(shù),一個(gè)是調(diào)用的方法的名字,一個(gè)是包含函數(shù)參數(shù)的數(shù)組。我們可以使用這種方法調(diào)用子對(duì)象中得同名函數(shù)。
//方法不存在時(shí)報(bào)錯(cuò)
public function __call($name, $args)
{
Support::Error('訪問的方法不存在');
}