博客列表 >属性与方法访问拦截器

属性与方法访问拦截器

王佳祥
王佳祥原创
2020年07月29日 17:22:41896浏览

属性与方法访问拦截器

一、后期静态绑定应用场景

  • 动态绑定静态成员的调用者/调用上下文
  1. class Base
  2. {
  3. public static function index()
  4. {
  5. return __METHOD__;
  6. }
  7. //把Index方法放到另一个方法中
  8. public static function fetch()
  9. {
  10. return static::index();
  11. }
  12. }
  13. echo Base::fetch(),'<br>';
  14. //User类继承Base类
  15. class User extends Base
  16. {
  17. public static function index()
  18. {
  19. return __METHOD__;
  20. }
  21. }
  22. echo User::index(),'<br>';
  23. echo User::fetch();


二、构造方法的使用

  1. <?php
  2. //魔术方法
  3. //魔术方法:由一个事件/行为来自动的触发,不允许用户主动调用
  4. class Product
  5. {
  6. public $name = '手机';
  7. public $price = 3000;
  8. //构造方法,实现对类的初始化,并且在new的时候自动调用
  9. public function __construct($name,$price)
  10. {
  11. //1.生成一个对象
  12. //$this = new self($name,$price);
  13. //2.给这个对象初始化
  14. $this->name = $name;
  15. $this->price = $price;
  16. echo $this->getInfo();
  17. //3.返回这个对象
  18. //return $this;
  19. }
  20. //输出方法
  21. public function getInfo()
  22. {
  23. return $this->name.':'.$this->price.'元';
  24. }
  25. //析构方法
  26. public function __destruct()
  27. {
  28. //注销时执行或者在方法最后执行
  29. echo '我是析构方法';
  30. }
  31. }
  32. $product = new Product('中华',100);
  33. //echo ''.$product->name.':'.$product->price.'元<hr>';
  34. /* $product->name = '电脑';
  35. $product->price = 10000;
  36. echo $product->name.':'.$prodict->price.'<hr>'; */


三、属性访问拦截器

  • __get():当外部访问一个或者无权限访问的属性的时候会自动调用,__get()返回值是属性名称

  • __set():给无权限访问的属性赋值时会自动调用,__set()返回值是属性名称

  • __isset():当对不可访问属性调用 isset() 或 empty() 时自动调用

  • __unset():当对不可访问属性调用 unset() 时自动调用

  1. <?php
  2. //重载:“访问拦截器”
  3. //类:二类成员,属性和方法,所以也有两种重载:属性和方法重载
  4. //换个叫法:属性拦截器和方法拦截器
  5. class Product
  6. {
  7. private $name;
  8. private $price;
  9. //税率
  10. private $tax = 0.06;
  11. public function __construct($name,$price)
  12. {
  13. $this->name = $name;
  14. $this->price = $price;
  15. //echo $name;
  16. }
  17. //__get():当外部访问一个或者无权限访问的属性的时候会自动调用
  18. //外部访问私有属性或者受保护的属性
  19. //如果你类中定义有--get方法 会自动调用 参数就是你访问的属性值
  20. //get返回属性名称
  21. public function __get($name)
  22. {
  23. //根据属性名称生成对应的属性访问接口方法
  24. //生成方法名
  25. $method = 'get'.ucfirst($name);
  26. //echo $method;
  27. //调用这个处理属性访问的方法
  28. //方法存在就调用这个方法,不存在就返回null
  29. return method_exists($this, $method) ? $this->$method() : null;
  30. //return method_exists($this, $method) ? $this->$method() : null;
  31. }
  32. public function __set($name,$value)
  33. {
  34. $method = 'set'.ucfirst($name);
  35. return method_exists($this, $method) ? $this->$method($value) : null;
  36. }
  37. private function getName()
  38. {
  39. return mb_substr($this->name,0,5);
  40. }
  41. private function getPrice()
  42. {
  43. return $this->price + $this->price * $this->tax;
  44. }
  45. private function setName($value)
  46. {
  47. return $this->name = $value;
  48. }
  49. private function setPrice($value)
  50. {
  51. return $this->price =$value * (1 - $this->tax);
  52. }
  53. public function __isset($name)
  54. {
  55. echo '我是__isset()魔术方法';
  56. }
  57. public function __unset($name)
  58. {
  59. echo '我是__unset魔术方法';
  60. }
  61. }
  62. $product = new Product('组装电脑 cpu:i7 9700',5500);
  63. //这个方法实际中应该在类的内部调用
  64. //echo $product->name .':'.$product->price;
  65. echo $product->name,'...含税价:',$product->price.'元';
  66. /* echo '<hr>';
  67. echo $product->price; */
  68. $product->name = '手机';
  69. $product->price = 1000;
  70. echo '<hr>'.$product->name,'不含税:',$product->price.'元<hr>';
  71. var_dump(isset($product->name));
  72. echo '<hr>';
  73. unset($product->name);


四、方法拦截器

  • __call(方法名称,参数数组):调用当前类中不存在或者不可访问的方法时自动调用

  • __callStatic(方法名称,参数数组):调用当前类中不存在或者不可访问的静态方法时自动调用

  1. <?php
  2. //方法拦截器
  3. //当从类的外部,访问类中不存在或者无权限访问的方法的时候,会自动调用它
  4. class User
  5. {
  6. //方法拦截器也是一个魔术方法__call(方法名称,参数数组)
  7. public function __call($name,$arr)
  8. {
  9. echo '__call()魔术方法<br>';
  10. printf('方法名:%s(),参数[%s]',$name,implode(',',$arr));
  11. }
  12. //静态方法拦截器:__callStatic(方法名称,参数数组)
  13. public static function __callStatic($name,$arr)
  14. {
  15. echo '__callStatic()魔术方法<br>';
  16. printf('方法名:%s(),参数[%s]',$name,implode(',',$arr));
  17. }
  18. }
  19. $user = new User();
  20. //调用当前类中不存在或者不可访问的方法时自动调用__call()魔术方法
  21. $user->hello('cat','pig','dog');
  22. echo '<hr>';
  23. User::demo(1,2,3,4);


五、事件委托

  1. <?php
  2. //事件委托
  3. class Base
  4. {
  5. public function write(...$arr)
  6. {
  7. printf('方法名:%s(),参数[%s]',__METHOD__,implode(',',$arr));
  8. }
  9. public static function fetch(...$arr)
  10. {
  11. printf('方法名:%s().参数[%s]',__METHOD__,implode(',',$arr));
  12. }
  13. }
  14. //工作类
  15. class Work
  16. {
  17. //事件委托时,重定向到的类
  18. private $base;
  19. //将$base初始化
  20. public function __construct(Base $base)
  21. {
  22. $this->base = $base;
  23. }
  24. public function __call($name,$arr)
  25. {
  26. return call_user_func_array([$this->base,'write'],$arr);
  27. }
  28. public static function __callStatic($name, $args)
  29. {
  30. if (method_exists('Base', $name))
  31. return call_user_func_array(['Base', 'fetch'], $args);
  32. }
  33. }
  34. $base = new Base();
  35. $work = new Work($base);
  36. $work->write(1,2,3);
  37. echo '<hr>';
  38. $work::fetch('a','b','c');


六、方法委托实战

  1. <?php
  2. //方法委托实战:数据库查询构造器(链式查询)
  3. //查询类
  4. class Query
  5. {
  6. //连接对象
  7. protected $db;
  8. //数据表
  9. protected $tale;
  10. //字段列表
  11. protected $field;
  12. //记录数量
  13. protected $limit;
  14. //构造方法:连接数据库
  15. public function __construct($dsn,$username,$password)
  16. {
  17. $this->connect($dsn,$username,$password);
  18. }
  19. //连接数据库
  20. private function connect($dsn,$username,$password)
  21. {
  22. $this->db = new PDO($dsn,$username,$password);
  23. }
  24. //设置默认的数据表名称
  25. public function table($table)
  26. {
  27. $this->table = $table;
  28. return $this;
  29. }
  30. //设置默认的字段名称
  31. public function field($field)
  32. {
  33. $this->field = $field;
  34. return $this;
  35. }
  36. //链式方法:设置查询数量
  37. public function limit($limit)
  38. {
  39. $this->limit = $limit;
  40. return $this;
  41. }
  42. //生成查询语句
  43. protected function getSql()
  44. {
  45. return sprintf('SELECT %s FROM %s LIMIT %s',$this->field,$this->table,$this->limit);
  46. }
  47. //执行查询
  48. public function select()
  49. {
  50. return $this->db->query($this->getSql())->fetchAll(PDO::FETCH_ASSOC);
  51. }
  52. }
  53. //数据库操作类
  54. class DB
  55. {
  56. //静态方法委托
  57. public static function __callStatic($name,$arr)
  58. {
  59. //获取到查询类的对象:new Query()
  60. $dsn = 'mysql:host=localhost;dbname=tp5';
  61. $username = 'root';
  62. $password = 'wang1111';
  63. $query = new Query($dsn,$username,$password);
  64. return call_user_func([$query,$name], ...$arr);
  65. }
  66. }
  67. $result = DB::table('user')->field('id,name')->limit(3)->select();
  68. print_r($result);


七、学习总结

  • 只能理解大概意思,有好多语句并不知道为什么这样用,我理解的方法委托就是在一个类的方法中调用另一个类的方法,然后在类外部调用
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议