PHP中的魔術(shù)方法

特征

  1. __兩個(gè)下劃線開始
  2. 不需要顯示的調(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('訪問的方法不存在');
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容