话不多说,我们一个一个的来看。
__construct()和__destruct()
这两个是非常出名并且也是非常常用的魔术方法。__construct()是布局函数。在Java中,布局函数是与类名相同的方法名,而PHP在早期的版本中也是这样的,但从5往后改成了__construct()方法来实现,缘故原由是当类名进行修正的时候,可以不用再去修正这个方法名了。当然,我们用与类名相同的方法名也是可以向下兼容的,不过最好不要这样用。

__destruct()方法是析构函数,不须要显式的调用,系统会自动调用这个方法。而且析构函数不须要参数,由于它不须要去调用嘛,系统自动调用的时候也是不会去带参数的。
publicfunction__construct(){echo'布局函数'.PHP_EOL;}publicfunction__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的源码。
publicfunction__call($name,$arguments){echo'===call==='.PHP_EOL;echo'未定义的方法找我'.PHP_EOL;echo'您须要的是'.$name.',参数是:';print_r($arguments);echo'===call==='.PHP_EOL;}publicstaticfunction__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()魔术方法。
publicfunction__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;}}publicfunction__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()时都会进行触发。都是在判断属性是否存在或者是否为空时可以进行一些操作,也是属性封装干系的操作函数。
publicfunction__isset($name){echo'===isset==='.PHP_EOL;echo'调用isset()或empty()时来找我了'.PHP_EOL;echo'您要找的是'.$name.PHP_EOL;echo'===isset==='.PHP_EOL;returnproperty_exists($this,$name);}publicfunction__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