PHP魔术方法是以 __ 两个下划线开头的方法,具有魔术功能的一些方法,本文主要讲实现属性重载和方法重载的魔术方法。
属性重载__set()魔术方法
__get()魔术方法
示例代码:
1 2 3 4 5 6 7 8 9
| <?php class User { private $name; private $age; }
$user = new User();
echo $user->name;
|
输出:
1 2
| PHP Fatal error: Uncaught Error: Cannot access private property User::$name in /Users/frankphper/www/php/magic/demo1.php:9
|
示例中我们调用了私有属性,程序运行时报了一个致命错误,大致意思是说不能访问私有属性name 我们在以上示例代码中的类定义代码里面增加以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public function __set($name, $value) { echo "Setting $name to $value" . PHP_EOL; $this->$name = $value; } public function __get($name) { if (!isset($this->$name)) { echo '未设置' . PHP_EOL; $this->$name = 'guest' . PHP_EOL; } return $this->$name; }
|
输出:
代码讲解:
我们在代码中增加了__set() 和__get() 两个魔术方法,再次运行代码,输出正常,没有报错。 当我们试图写入一个不存在或不可见的属性时,PHP就会执行对象(类)中的__set() 魔术方法,方法必须接收两个参数,用来存放属性名和属性值。当我们试图读取一个不存在或者不可见的属性时,PHP就会执行对象(类)中的__get() 魔术方法。
__set() 和__get() 作用:
1、直接在对象(类)的外部调用对象(类)的私有属性是会报错的,但是如果对象(类)中定义了__set() 魔术方法,就可以很方便的调用对象(类)的私有属性,因为魔术方法是自动调用的,不需要显式地调用
2、动态创建对象(类)的属性,如果对象(类)中定义了__set() 和__get() 魔术方法, 那么当调用对象属性取值时,即使这个属性不存在,也不会报错,从而提升了程序的健壮性。
方法重载__call() 魔术方法__callStatic() 魔术方法
示例代码:
1 2 3 4 5 6 7 8 9
| <?php class User { private $name; private $age; }
$user = new User();
$userInfo = $user->userInfo('lucy', 18);
|
输出:
1 2
| PHP Fatal error: Uncaught Error: Call to undefined method User::userInfo() in /Users/weirubo/www/php/magic/test.php:9
|
示例中我们调用了不存在的方法,程序报了一个致命错误,大致意思是不能访问未定义的方法userInfo() 我们在以上示例代码中的类定义代码里面增加以下代码:
1 2 3 4 5
| public function __call($methodName, $params) { echo '方法名:' . $methodName . PHP_EOL; print_r($params); }
|
输出:
1 2 3 4 5 6
| 方法名:userInfo Array ( [0] => lucy [1] => 18 )
|
代码讲解:
我们在代码中增加了__call() 魔术方法,再次运行程序,输出正常,没有报错。当我们试图调用对象(类)中一个不存在或者不可见的方法时,PHP会执行对象(类)中的_call() 魔术方法。__call() 也必须接收两个参数,用来存放试图调用的方法名和要传递给该方法的参数。如果我们试图调用对象(类)中一个不存在或者不可见的静态方法时,PHP会执行对象(类)中的__callStatic() 魔术方法。
__call() 和__callStatic() 作用:
1、防止调用不存在或者不可见的方法而报错
2、动态创建对象(类)的方法
总结:我们通过示例代码讲解了属性重载和方法重载的PHP魔术方法,在实际开发工作中,可以灵活使用这些魔术方法的特性,优雅地处理各种场景。
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <?php class User { private $name; private $age;
public function __set($name, $value) { echo "Setting $name to $value" . PHP_EOL; $this->$name = $value; } public function __get($name) { if (!isset($this->$name)) { echo '未设置' . PHP_EOL; $this->$name = 'guest' . PHP_EOL; } return $this->$name; }
}
$user = new User();
echo $user->name;
|
|