1. 程式人生 > 實用技巧 >PHP的那些魔術方法(二)

PHP的那些魔術方法(二)

上文中介紹了非常常用並且也是面試時的熱門魔術方法,而這篇文章中的所介紹的或許並不是那麼常用,但絕對是加分項。當你能準確地說出這些方法及作用的時候,相信對方更能對你刮目相看。

__sleep()與__wakeup()

字面上的意思很好玩,睡覺和起床。它們分別對應著serialize()和unserialize()方法,也就是序列化和反序列化時會觸發這兩個魔術方法。

這裡需要注意的是,__sleep()需要返回一個數組,而這個陣列對應著類中的屬性名。通常來說,它們可以在序列化前進行資料清理工作,或者反序列化前進行資料的預處理工作。比如序列化前關閉資料庫連線或者反序列化前開啟資料庫連線。

public function __sleep()
{
    echo '===sleep===' . PHP_EOL;
    echo '呼叫serialize()時來找我,先睡一會的' . PHP_EOL;
    echo '===unset===' . PHP_EOL;
    return ['a'];
}

public function __wakeup()
{
    echo '===wakeup===' . PHP_EOL;
    echo '呼叫unserialize()時來找我,起床吧' . PHP_EOL;
    echo '===wakeup===' . PHP_EOL;
}

__toString()

顧名思義,這個方法通過返回一個字串,實現物件的列印。如果沒有實現這個方法,我們直接使用echo是無法列印物件的,會報錯。當實現了這個魔術方法後,直接使用echo或者print等方法就可以進入這個魔術方法中,並打印出該方法中返回的內容。

public function __toString()
{
    echo '===toString===' . PHP_EOL;
    echo '呼叫echo、print時會使用我' . PHP_EOL;
    echo '===toString===' . PHP_EOL;
    return '打印出來看看吧';
}

當然,它也能實現物件轉換到字串,如在字串拼接的時候,如:$obj = new Object(); $a = 'this is ' . $obj;這樣使用。

__invoke()

很有意思的一個魔術方法,它的作用是將物件當做方法使用時會呼叫這個魔術方法。什麼意思呢?比如:$obj = new Object();,然後直接$obj();

這時,就會進入這個魔術方法。那麼有什麼用呢?對於閉包以及反射來說,這個魔術方法有不可替代的作用。將來我們會在別的文章中進行詳細說明。

public function __invoke()
{
    echo '===invoke===' . PHP_EOL;
    echo '把類當方法使用時就進這裡了' . PHP_EOL;
    echo '===invoke===' . PHP_EOL;
}

__clone()

使用clone關鍵字進行物件的複製時,就會呼叫這個魔術方法。其實就是原型模式的實現。在原型模式的相關文章中我們再來詳細說明。

public function __clone()
{
    echo '===clone===' . PHP_EOL;
    echo '複製類的時候我就發揮作用了' . PHP_EOL;
    echo '===clone===' . PHP_EOL;
}

__set_state()與__debugInfo()

真的是神奇的PHP語法,最後這兩個魔術方法一個是用的下劃線命名,一個是用的小駝峰。實在無力吐槽~~

這兩個方法對應的是var_export()和var_dump()方法在使用時的呼叫。一般是在除錯時使用,其實非常類似於__toString()方法。

public static function __set_state($an_array)
{
    echo '===set_state===' . PHP_EOL;
    echo '使用var_export()的時候使用呼叫我哦' . PHP_EOL;
    echo '===set_state===' . PHP_EOL;
    $m = new PHPMagic();
    $m->var1 = 111;
    $m->var2 = 222;
    return $m;
}

public function __debugInfo()
{
    echo '===debugInfo===' . PHP_EOL;
    echo '使用var_dump()的時候就是我來啦' . PHP_EOL;
    echo '===debugInfo===' . PHP_EOL;
    return [
        'var1' => $this->var1,
        'var2' => $this->var2,
    ];
}

通過兩篇文章,我們熟悉了PHP所定義的這些魔術方法。在這裡需要特別注意的是,PHP中將所有以__兩個下劃線開頭的方法做為魔術方法的保留命名。所以在定義類方法的時候,不要使用兩個下劃線開頭的方法名。

文件參考:https://www.php.net/manual/zh/language.oop5.magic.php

完整程式碼:https://github.com/zhangyue0503/php/blob/master/newblog/PHPMagic.php

關注公眾號:【硬核專案經理】獲取最新文章

新增微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料

知乎、公眾號、抖音、頭條搜尋【硬核專案經理】

B站ID:482780532