1、类的拦截器

Class类中提供了5个方法,用于在访问未定义的成员函数 或 成员属性时被自动或主动触发。

而这5个方法又可以称之为类的魔术方法。

A、__get()

__get()魔术方法,主要用于,在访问未定义的属性时被自动调用。

其使用案例如下:

  1. <?php
  2. class Test {
  3. public function __get($name) {
  4. echo $name.'成员属性不存在!';
  5. }
  6. }
  7. $obj = new Test();
  8. $obj->name;

B、__set()

__set()魔术方法,主要用于,在给未定义的属性调用时主动赋值

其使用案例如下:

  1. <?php
  2. class Test {
  3. public function __set($name, $val) {
  4. echo '捕捉到向没有定义的成员属性进行赋值<br/>';
  5. $this->$name = $val;
  6. }
  7. }
  8. $obj = new Test();
  9. $obj->bbb = '你妹';
  10. echo $obj->bbb;

C、__isset()

__isset()魔术方法,比较特殊,主要用于在对未定义的属性调用isset()函数时被自动调用。

在class类中,对public权限的成员属性可以直接使用isset()函数检测值是否被设定。

但对于设置为 privateprotected 的成员属性则不行,需要在类里面加上一个 __isset() 方法:

  1. <?php
  2. class Test {
  3. private $bbb = '1';
  4. public function __isset($name) {
  5. echo '捕捉到使用isset()函数检测私有成员属性<br/>';
  6. return isset($this->$name);
  7. }
  8. }
  9. $obj = new Test();
  10. var_dump(isset($obj->bbb));

D、__unset()

__unset()魔术方法,与__isset()魔术方法一样主要用于在对未定义的属性调用unset()函数时被自动调用。

在class类中,对public权限的成员属性可以直接使用unset()函数销毁释放内存。

但对于设置为 privateprotected 的成员属性则不行,需要在类里面加上一个 __unset() 方法:

  1. <?php
  2. class Test {
  3. private $bbb = '1';
  4. public function __unset($name) {
  5. echo '捕捉到使用unset()函数销毁私有成员属性<br/>';
  6. return unset($this->$name);
  7. }
  8. }
  9. $obj = new Test();
  10. var_dump(unset($obj->bbb));

E、__call()

__call()魔术方法,主要用于在对一个未定义的成员函数调用时被自动调用。

同时在对于没有控制权限,例如被设置为privateprotected 的成员函数调用时,也会自动触发该魔术方法:

  1. <?php
  2. class Test {
  3. public function __call($name, $argument) {
  4. echo '调用不存在的方法名是:' . $name . '<br>参数是:';
  5. print_r($argument);
  6. echo '<br>';
  7. }
  8. private function bbb(){}
  9. }
  10. $obj = new Test();
  11. $obj->bbb();

注意,当需要对声明为static静态成员函数做调用监听时,需要使用__callStatic()魔术方法,他们两者的区别是:

  1. 1__call() 当要调用的方法不存在或权限不足时,会自动调用__call() 方法。
  2. 2__callStatic() 当调用的静态方法不存在或权限不足时,会自动调用__callStatic()方法。

在上面的课件内容中,我们不是曾经提到过,PHP的Class实现重载机制实际上有2种实现方式,而其中一种就是依靠__call()魔术方法。

在对象中调用一个不可访问的方法时,__call()会被自动调用

像上面的案例代码中,$name参数是要调用的方法名称 $argument参数是被调用方法的参数数组。

依赖这2个参数,我们就可以实现class的重载功能:

  1. <?php
  2. class demo{
  3. public function __call($name, $arguments){
  4. if($name == "method"){
  5. switch (count($arguments)) { #获得参数数组个数
  6. case 2:
  7. $this->method2($args[0],$args[1]);
  8. break;
  9. case 3:
  10. $this->method3($args[0],$args[1],$args[2]);
  11. break;
  12. }
  13. }
  14. }
  15. private function method2($var1, $var2){
  16. # code...
  17. }
  18. private function method3($var1, $var2, $var3){
  19. # code...
  20. }
  21. }
  22. # 调用
  23. $obj = new demo();
  24. $obj->method(1, 2);
  25. $obj->method(1, 2, 3);