小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

PHP中的那些魔術方法(一)

 硬核項目經(jīng)理 2021-05-31

在PHP中,有一堆魔術方法,服務于類和對象。PHP雖然也是純種的面向對象語言,但是之前的PHP還真不是,所以有一些面向對象的標準實現(xiàn)并不完善,比如重載。但是,我們可以通過一些魔術方法來彌補,例如__call()方法就可以用來實現(xiàn)重載。

話不多說,我們一個一個的來看。

__construct()和__destruct()

這兩個是非常出名并且也是非常常用的魔術方法。__construct()是構造函數(shù)。在Java中,構造函數(shù)是與類名相同的方法名,而PHP在早期的版本中也是這樣的,但從5以后改成了__construct()方法來實現(xiàn),原因是當類名進行修改的時候,可以不用再去修改這個方法名了。當然,我們用與類名相同的方法名也是可以向下兼容的,不過最好不要這樣用。

__destruct()方法是析構函數(shù),不需要顯式的調用,系統(tǒng)會自動調用這個方法。而且析構函數(shù)不需要參數(shù),因為它不需要去調用嘛,系統(tǒng)自動調用的時候也是不會去帶參數(shù)的。

public function __construct()
{
echo '構造函數(shù)' . PHP_EOL;
}

public function __destruct()
{
echo '析構函數(shù)' . PHP_EOL;
}

__call()與__callStatic()

非常重要而且也是面試時經(jīng)常會問到的魔術方法。它們倆的作用其實差不多,都是用于未定義的方法,當使用這些未定義的方法時就會進入這兩個函數(shù)中。比如說我們調用$a->b();這個方法,但其實在$a的類模板中并沒有b()方法,這時就會進入__call()方法進行處理。__callStatic()則是通過靜態(tài)調用時如果沒有定義對應的方法,就進入到__callStatic()方法中,如A::b(),并沒有定義b()方法,這時就進入了__callStatic()中進行處理。

開頭說道,__call()可以實現(xiàn)類似于Java中的函數(shù)重載的能力。函數(shù)重載其實就是同名的函數(shù),但參數(shù)或返回值不同,在Java等強類型語言中可以方便的實現(xiàn),但PHP是弱類型語言,無法準確的定位方法的重載,使用__call()方法其實也需要很多的判斷,并不是非常的推薦一定要和Java一樣的去實現(xiàn)函數(shù)重載。我們還是需要根據(jù)語言的特性來對業(yè)務功能進行深入的分析后再進行對應的實現(xiàn)。

在Laravel框架中,使用的Facade模式,也就是門面模式,核心代碼就是使用了__callStatic()方法。有興趣的小伙伴可以自行查看下Laravel的源碼。

public function __call($name, $arguments)
{
echo '===call===' . PHP_EOL;
echo '未定義的方法找我' . PHP_EOL;
echo '您需要的是' . $name . ',參數(shù)是:';
print_r($arguments);
echo '===call===' . PHP_EOL;
}

public static function __callStatic($name, $arguments)
{
echo '===callStatic===' . PHP_EOL;
echo '未定義的靜態(tài)方法找我' . PHP_EOL;
echo '您需要的是' . $name . ',參數(shù)是:';
print_r($arguments);
echo '===callStatic===' . PHP_EOL;
}

$name參數(shù)是方法的名稱,如$a->b(),$name的值就是"b"。$arguments是參數(shù)數(shù)組,如$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()時會觸發(fā),而另一個則是在使用unset()時會觸發(fā)。

需要注意的是,__isset()是在isset()和empty()時都會進行觸發(fā)。都是在判斷屬性是否存在或者是否為空時可以進行一些操作,也是屬性封裝相關的操作函數(shù)。

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;
}

這篇文章主要介紹的是幾個非常常用的,而且在面試時出現(xiàn)頻率也是非常高的魔術方法。在下一篇中將會介紹其它一些出現(xiàn)頻率較低但更有意思的魔術方法。

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

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多