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