当前位置: 首页 > 后端技术 > PHP

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

时间:2023-03-30 02:51:04 PHP

在PHP中,有一堆为类和对象服务的魔术方法。PHP虽然也是纯面向对象的语言,但是以前的PHP确实不是,所以一些面向对象的标准实现并不完善,比如重载。不过,我们可以通过一些神奇的方法来弥补,比如可以使用__call()方法来实现重载。话不多说,我们一一来看。__construct()和__destruct()是两个非常著名和常用的魔术方法。\_\_construct()是构造函数。在Java中,构造函数是和类名一样的方法名,PHP早期版本也是这样,但是从5开始改成了\_\_construct()方法,因为修改类名的时候,您不再需要修改方法名称。当然,为了向后兼容,我们也可以使用与类名相同的方法名,但最好不要这样使用。\_\_destruct()方法是一个析构函数,不需要显式调用,系统会自动调用该方法。而析构函数不需要参数,因为它不需要被调用,系统自动调用时不会带参数。publicfunction__construct(){echo'constructor'.PHP_EOL;}publicfunction__destruct(){echo'destructor'.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的源码。公共函数__call($name,$arguments){echo'===call==='.PHP_EOL;echo'Undefinedmethodfindme'.PHP_EOL;echo'你需要的是'.$名字。',参数为:';print_r($参数);echo'===call==='.PHP_EOL;}publicstaticfunction__callStatic($name,$arguments){echo'===callStatic==='.PHP_EOL;echo'Undefinedstaticmethodfindme'.PHP_EOL;echo'你需要的是'.$名字。',参数为:';print_r($参数);回声'===callStatic==='。PHP_EOL;}$name参数为方法名,如$a->b(),$name的值为“b”。$arguments是一个参数数组,比如$a->b("1",2);然后$arguments=["1",2];__set()和__get()上面的\_\_call()方法针对的是未定义的方法。而\_\_set()和\_\_get()是不能被操作访问的属性。请注意,这不是指未定义的属性。如果属性定义为private,也可以通过这两个魔术方法来定义。当然,还包括未定义的属性。这两个属性其实可以对应Java中JavaBean的属性封装。比如$a->p=1;,两种情况:我们没有定义$p属性,我们定义了$p,但是它是私有的$p;以上两种情况适用于\_\_set()和\_\_get()魔术方法。公共函数__set($name,$value){echo'===set==='.PHP_EOL;echo'为不可访问的属性赋值时找我'.PHP_EOL;echo'你需要的是'.$名字。',值为:'.$价值。PHP_EOL;回声'===设置==='。PHP_EOL;如果($name=='a'){$this->$name=$value;}}公共函数__get($name){echo'===get==='。PHP_EOL;echo'在获取无法访问的属性分配时找到我'.PHP_EOL;echo'你需要的是'.$名字。PHP_EOL;echo'===get==='.PHP_EOL;return$this->$name;}__isset()和__unset()很容易理解。从字面意思可以看出,一个是用isset(),另一个是用unset()。需要注意的是\_\_isset()在isset()和empty()中都会被触发。它们都可以在判断属性是否存在或者是否为空时进行一些操作,也是属性封装相关的操作函数。公共函数__isset($name){echo'===isset==='.PHP_EOL;echo'调用isset()或empty()时来找我'.PHP_EOL;echo'你在找什么'.$name.PHP_EOL;echo'===isset==='.PHP_EOL;返回property_exists($this,$name);}publicfunction__unset($name){echo'===unset==='.PHP_EOL;'调用unset()时来找我'。PHP_EOL;echo'你在找什么'.$名字。PHP_EOL;回声'===未设置==='。PHP_EOL;}本文主要介绍几个很常用的,也是面试中使用频率很高的魔术方法。其他不太常见但更有趣的魔术方法将在下一篇文章中介绍。完整代码:https://github.com/zhangyue0503/php/blob/master/newblog/PHPMagic.php关注公众号:【硬核项目经理】获取最新文章添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费获取PHP、项目管理学习资料知乎、公众号、抖音、头条搜索【硬核项目经理】B站ID:482780532