1、类的拦截器
Class类中提供了5个方法,用于在访问未定义的成员函数 或 成员属性时被自动或主动触发。
而这5个方法又可以称之为类的魔术方法。
A、__get()
__get()
魔术方法,主要用于,在访问未定义的属性时被自动调用。
其使用案例如下:
<?php
class Test {
public function __get($name) {
echo $name.'成员属性不存在!';
}
}
$obj = new Test();
$obj->name;
B、__set()
__set()
魔术方法,主要用于,在给未定义的属性调用时主动赋值
其使用案例如下:
<?php
class Test {
public function __set($name, $val) {
echo '捕捉到向没有定义的成员属性进行赋值<br/>';
$this->$name = $val;
}
}
$obj = new Test();
$obj->bbb = '你妹';
echo $obj->bbb;
C、__isset()
__isset()
魔术方法,比较特殊,主要用于在对未定义的属性调用isset()
函数时被自动调用。
在class类中,对public权限的成员属性可以直接使用isset()
函数检测值是否被设定。
但对于设置为 private
或 protected
的成员属性则不行,需要在类里面加上一个 __isset()
方法:
<?php
class Test {
private $bbb = '1';
public function __isset($name) {
echo '捕捉到使用isset()函数检测私有成员属性<br/>';
return isset($this->$name);
}
}
$obj = new Test();
var_dump(isset($obj->bbb));
D、__unset()
__unset()
魔术方法,与__isset()
魔术方法一样主要用于在对未定义的属性调用unset()
函数时被自动调用。
在class类中,对public权限的成员属性可以直接使用unset()
函数销毁释放内存。
但对于设置为 private
或 protected
的成员属性则不行,需要在类里面加上一个 __unset()
方法:
<?php
class Test {
private $bbb = '1';
public function __unset($name) {
echo '捕捉到使用unset()函数销毁私有成员属性<br/>';
return unset($this->$name);
}
}
$obj = new Test();
var_dump(unset($obj->bbb));
E、__call()
__call()
魔术方法,主要用于在对一个未定义的成员函数调用时被自动调用。
同时在对于没有控制权限,例如被设置为private
或 protected
的成员函数调用时,也会自动触发该魔术方法:
<?php
class Test {
public function __call($name, $argument) {
echo '调用不存在的方法名是:' . $name . '<br>参数是:';
print_r($argument);
echo '<br>';
}
private function bbb(){}
}
$obj = new Test();
$obj->bbb();
注意,当需要对声明为static
静态成员函数做调用监听时,需要使用__callStatic()
魔术方法,他们两者的区别是:
1、__call() 当要调用的方法不存在或权限不足时,会自动调用__call() 方法。
2、__callStatic() 当调用的静态方法不存在或权限不足时,会自动调用__callStatic()方法。
在上面的课件内容中,我们不是曾经提到过,PHP的Class实现重载机制实际上有2种实现方式,而其中一种就是依靠__call()
魔术方法。
在对象中调用一个不可访问的方法时,__call()
会被自动调用
像上面的案例代码中,$name
参数是要调用的方法名称 $argument
参数是被调用方法的参数数组。
依赖这2个参数,我们就可以实现class的重载功能:
<?php
class demo{
public function __call($name, $arguments){
if($name == "method"){
switch (count($arguments)) { #获得参数数组个数
case 2:
$this->method2($args[0],$args[1]);
break;
case 3:
$this->method3($args[0],$args[1],$args[2]);
break;
}
}
}
private function method2($var1, $var2){
# code...
}
private function method3($var1, $var2, $var3){
# code...
}
}
# 调用
$obj = new demo();
$obj->method(1, 2);
$obj->method(1, 2, 3);