PHP语言教程-魔术方法之属性重载和方法重载

[复制链接]
frankphper 发表于 2019-8-11 20:58:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 frankphper 于 2019-8-11 21:03 编辑

PHP魔术方法是以 __ 两个下划线开头的方法,具有魔术功能的一些方法,本文主要讲实现属性重载和方法重载的魔术方法。
属性重载
__set()魔术方法
__get()魔术方法
示例代码:
  1. <?php
  2. class User {
  3.     private $name;
  4.     private $age;
  5. }
  6. // 实例化User类
  7. $user = new User();
  8. // 调用类的私有属性
  9. echo $user->name;
复制代码
输出:
  1. PHP Fatal error:  Uncaught Error: Cannot access private property User::$name in /Users/frankphper/www/php/magic/demo1.php:9
复制代码
示例中我们调用了私有属性,程序运行时报了一个致命错误,大致意思是说不能访问私有属性name
我们在以上示例代码中的类定义代码里面增加以下代码:
  1. // 属性重载
  2.     public function __set($name, $value) {
  3.         echo "Setting $name to $value" . PHP_EOL;
  4.         $this->$name = $value;
  5.     }
  6.     public function __get($name) {
  7.         if (!isset($this->$name)) {
  8.             echo '未设置' . PHP_EOL;
  9.             // 设置默认值
  10.             $this->$name = 'guest' . PHP_EOL;
复制代码
输出:
  1. 未设置
  2. guest
复制代码
代码讲解:
我们在代码中增加了__set()和__get()两个魔术方法,再次运行代码,输出正常,没有报错。
当我们试图写入一个不存在或不可见的属性时,PHP就会执行对象(类)中的__set()魔术方法,方法必须接收两个参数,用来存放属性名和属性值。当我们试图读取一个不存在或者不可见的属性时,PHP就会执行对象(类)中的__get()魔术方法。__set()和__get()作用:1、直接在对象(类)的外部调用对象(类)的私有属性是会报错的,但是如果对象(类)中定义了__set()魔术方法,就可以很方便的调用对象(类)的私有属性,
因为魔术方法是自动调用的,不需要显式地调用
2、动态创建对象(类)的属性,如果对象(类)中定义了__set()和__get()魔术方法,
那么当调用对象属性取值时,即使这个属性不存在,也不会报错,从而提升了程序的健壮性。
方法重载__call()魔术方法__callStatic()魔术方法示例代码:
  1. <?php
  2. class User {
  3.     private $name;
  4.     private $age;
  5. }
  6. // 实例化User类
  7. $user = new User();
  8. // 调用类中不存在的方法
  9. $userInfo = $user->userInfo('lucy', 18);
复制代码
输出:
  1. PHP Fatal error:  Uncaught Error: Call to undefined method User::userInfo() in /Users/weirubo/www/php/magic/test.php:9
复制代码
示例中我们调用了不存在的方法,程序报了一个致命错误,大致意思是不能访问未定义的方法userInfo()我们在以上示例代码中的类定义代码里面增加以下代码:
  1. // 方法重载
  2.     public function __call($methodName, $params) {
  3.         echo '方法名:' . $methodName . PHP_EOL;
  4.         print_r($params);
  5.     }
复制代码
输出:
  1. 方法名:userInfo
  2. Array
  3. (
  4.     [0] => lucy
  5.     [1] => 18
  6. )
复制代码
代码讲解:
我们在代码中增加了__call()魔术方法,再次运行程序,输出正常,没有报错。当我们试图调用对象(类)中一个不存在或者不可见的方法时,PHP会执行对象(类)中的_call()魔术方法。__call()也必须接收两个参数,用来存放试图调用的方法名和要传递给该方法的参数。如果我们试图调用对象(类)中一个不存在或者不可见的静态方法时,PHP会执行对象(类)中的__callStatic()魔术方法。
__call()和__callStatic()作用:
1、防止调用不存在或者不可见的方法而报错
2、动态创建对象(类)的方法

总结:我们通过示例代码讲解了属性重载和方法重载的PHP魔术方法,在实际开发工作中,可以灵活使用这些魔术方法的特性,优雅地处理各种场景。
完整代码:
  1. <?php
  2. class User {
  3.     private $name;
  4.     private $age;

  5.     // 属性重载
  6.     public function __set($name, $value) {
  7.         echo "Setting $name to $value" . PHP_EOL;
  8.         $this->$name = $value;
  9.     }
  10.     public function __get($name) {
  11.         if (!isset($this->$name)) {
  12.             echo '未设置' . PHP_EOL;
  13.             // 设置默认值
  14.             $this->$name = 'guest' . PHP_EOL;
  15.         }
  16.         return $this->$name;
  17.     }
  18.     // 方法重载
  19.     /*public function __call($methodName, $params) {
  20.         echo '方法名:' . $methodName . PHP_EOL;
  21.         print_r($params);
  22.     }
  23.     public static function __callStatic($methodName, $params) {
  24.         echo '方法名:' . $methodName . PHP_EOL;
  25.         print_r($params);
  26.     }

  27.     private function work($doWork) {
  28.         echo $doWork . PHP_EOL;
  29.     }*/
  30. }
  31. // 实例化User类
  32. $user = new User();
  33. // 调用类的私有属性
  34. echo $user->name; // Fatal error: Uncaught Error: Cannot access private property User::$name in /Users/frankphper/www/php/magic/demo1.php:21
  35. // 调用类中不存在的属性
  36. // echo $user->sex . PHP_EOL; // PHP Notice:  Undefined property: User::$sex in /Users/frankphper/www/php/magic/demo1.php on line 26
  37. // 调用类中不存在的方法
  38. //$userInfo = $user->userInfo('lucy', 18); // PHP Fatal error:  Uncaught Error: Call to undefined method User::userInfo() in /Users/frankphper/www/php/magic/demo1.php:26
  39. // 调用类中不存在的静态方法
  40. //$user->work('coding'); // PHP Fatal error:  Uncaught Error: Call to private method User::work() from context '' in /Users/frankphper/www/php/magic/demo1.php:34
  41. //$user::eat('chicken');
复制代码







*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则