在PHP中,有一堆魔術方法,服務于類和物件,PHP雖然也是純種的面向物件語言,但是之前的PHP還真不是,所以有一些面向物件的標準實作并不完善,比如多載,但是,我們可以通過一些魔術方法來彌補,例如__call()方法就可以用來實作多載,
話不多說,我們一個一個的來看,
__construct()和__destruct()
這兩個是非常出名并且也是非常常用的魔術方法,__construct()是建構式,在Java中,建構式是與類名相同的方法名,而PHP在早期的版本中也是這樣的,但從5以后改成了__construct()方法來實作,原因是當類名進行修改的時候,可以不用再去修改這個方法名了,當然,我們用與類名相同的方法名也是可以向下兼容的,不過最好不要這樣用,
__destruct()方法是解構式,不需要顯式的呼叫,系統會自動呼叫這個方法,而且解構式不需要引數,因為它不需要去呼叫嘛,系統自動呼叫的時候也是不會去帶引數的,
public function __construct()
{
echo '建構式' . PHP_EOL;
}
public function __destruct()
{
echo '解構式' . PHP_EOL;
}
__call()與__callStatic()
非常重要而且也是面試時經常會問到的魔術方法,它們倆的作用其實差不多,都是用于未定義的方法,當使用這些未定義的方法時就會進入這兩個函式中,比如說我們呼叫$a->b();這個方法,但其實在$a的類模板中并沒有b()方法,這時就會進入__call()方法進行處理,__callStatic()則是通過靜態呼叫時如果沒有定義對應的方法,就進入到__callStatic()方法中,如A::b(),并沒有定義b()方法,這時就進入了__callStatic()中進行處理,
開頭說道,__call()可以實作類似于Java中的函式多載的能力,函式多載其實就是同名的函式,但引數或回傳值不同,在Java等強型別語言中可以方便的實作,但PHP是弱型別語言,無法準確的定位方法的多載,使用__call()方法其實也需要很多的判斷,并不是非常的推薦一定要和Java一樣的去實作函式多載,我們還是需要根據語言的特性來對業務功能進行深入的分析后再進行對應的實作,
在Laravel框架中,使用的Facade模式,也就是門面模式,核心代碼就是使用了__callStatic()方法,有興趣的小伙伴可以自行查看下Laravel的原始碼,
public function __call($name, $arguments)
{
echo '===call===' . PHP_EOL;
echo '未定義的方法找我' . PHP_EOL;
echo '您需要的是' . $name . ',引數是:';
print_r($arguments);
echo '===call===' . PHP_EOL;
}
public static function __callStatic($name, $arguments)
{
echo '===callStatic===' . PHP_EOL;
echo '未定義的靜態方法找我' . PHP_EOL;
echo '您需要的是' . $name . ',引數是:';
print_r($arguments);
echo '===callStatic===' . PHP_EOL;
}
$name引數是方法的名稱,如$a->b(),$name的值就是"b",$arguments是引數陣列,如$a->b("1",2);則$arguments=["1", 2];
__set()和__get()
上面的__call()方法針對的是未定義的方法,而__set()和__get()則是操作不可訪問的屬性,注意,這里并不是指沒有定義的屬性,如果定義為private的屬性也可以通過這兩個魔術方法來進行定義,當然,也包括未定義的屬性,這兩個屬性其實可以對應Java中對于Java Bean的屬性封裝,
例如$a->p=1;,兩種情況:
- 我們沒有定義$p這個屬性
- 我們定義了$p,但是是private $p;
以上兩種情況都適用于__set()和__get()魔術方法,
public function __set($name, $value)
{
echo '===set===' . PHP_EOL;
echo '給不可訪問的屬性賦值時找我' . PHP_EOL;
echo '您需要的是' . $name . ',值是:' . $value . PHP_EOL;
echo '===set===' . PHP_EOL;
if ($name == 'a') {
$this->$name = $value;
}
}
public function __get($name)
{
echo '===get===' . PHP_EOL;
echo '獲取不可訪問的屬性賦值時找我' . PHP_EOL;
echo '您需要的是' . $name . PHP_EOL;
echo '===get===' . PHP_EOL;
return $this->$name;
}
__isset()與__unset()
這兩個就很好理解了,從字面意思也可以看出,一個是在使用isset()時會觸發,而另一個則是在使用unset()時會觸發,
需要注意的是,__isset()是在isset()和empty()時都會進行觸發,都是在判斷屬性是否存在或者是否為空時可以進行一些操作,也是屬性封裝相關的操作函式,
public function __isset($name)
{
echo '===isset===' . PHP_EOL;
echo '呼叫isset()或empty()時來找我了' . PHP_EOL;
echo '您要找的是' . $name . PHP_EOL;
echo '===isset===' . PHP_EOL;
return property_exists($this, $name);
}
public function __unset($name)
{
echo '===unset===' . PHP_EOL;
echo '呼叫unset()時來找我' . PHP_EOL;
echo '您要找的是' . $name . PHP_EOL;
echo '===unset===' . PHP_EOL;
}
這篇文章主要介紹的是幾個非常常用的,而且在面試時出現頻率也是非常高的魔術方法,在下一篇中將會介紹其它一些出現頻率較低但更有意思的魔術方法,
完整代碼:https://github.com/zhangyue0503/php/blob/master/newblog/PHPMagic.php
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229356.html
標籤:PHP
上一篇:Java決策制定
