Blogger Information
Blog 119
fans 3
comment 1
visits 94631
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
拦截器、重载/拦截器
赵大叔
Original
678 people have browsed it

一、后期静态绑定

1.原理

后期静态绑定工作在: 静态继承上下文的环境中
new self替换为new static
self: 与定义类绑定
static: 与调用类绑定
不要再使用parent

演示:

  1. <?php
  2. // 动态绑定静态成员的调用上下文
  3. class Ba
  4. {
  5. // 静态方法: 允许重写
  6. public static function getpp()
  7. {
  8. return '当前调用方法: ' . __METHOD__;
  9. }
  10. public static function dupp()
  11. {
  12. // 后期静态绑定, 使用关键字: static, 将self 替换掉
  13. // return new self();
  14. // self: 与定义类绑定
  15. // static: 与调用类绑定
  16. return static::getpp();
  17. }
  18. }
  19. class Con extends Ba
  20. {
  21. // 重写父类中的静态方法: index()
  22. public static function getpp()
  23. {
  24. return '当前调用方法: ' . __METHOD__;
  25. }
  26. }
  27. // 客户端
  28. echo Ba::dupp();
  29. echo '<hr>';
  30. echo Con::dupp();

效果图:

二、属性重载/拦截器

演示:

  1. <?php
  2. // 拦截器: 属性拦截器, 方法拦截器
  3. // 使用场景: 当用户访问一个不存在的或无权限访问属性/方法时, 自动调用(属性拦截器实质也是一个方法)
  4. // 访问: 包括二个操作:就是读和写, 或者称为: 查询和设置
  5. // 属性拦截器: __set(), __get(), __isset(), __unset()
  6. class Staffs
  7. {
  8. private $name;
  9. private $salary;
  10. public function __construct($name, $salary)
  11. {
  12. $this->name = $name;
  13. $this->salary = $salary;
  14. }
  15. // 1. 属性查询拦截器
  16. // $property 参数,要获取的属性名称
  17. public function __get($property)
  18. {
  19. // return $property === 'name' ? $this->name : '无权访问';
  20. // 拦截转发器
  21. // 1. 先事先约定一些方法专用于处理属性访问
  22. $method = 'get' . ucfirst($property);
  23. // 2. 转发访问请求
  24. return method_exists($this, $method) ? $this->$method() : null;
  25. }
  26. private function getName()
  27. {
  28. return $this->name;
  29. }
  30. private function getSalary()
  31. {
  32. return $this->salary;
  33. }
  34. // 2. 属性设置拦截器
  35. public function __set($property, $value)
  36. {
  37. $method = 'set' . ucfirst($property);
  38. // 转发访问请求
  39. return method_exists($this, $method) ? $this->$method($value) : null;
  40. }
  41. private function setName($value)
  42. {
  43. $this->name = trim($value);
  44. }
  45. private function setSalary($value)
  46. {
  47. if ($value === null) unset($this->salary);
  48. else $this->salary = $value;
  49. }
  50. // 3. 属性检测拦截器
  51. public function __isset($property)
  52. {
  53. return $property === 'name' ? isset($this->name) : false;
  54. }
  55. // 4. 属性销毁拦截器
  56. public function __unset($property)
  57. {
  58. if ($property === 'salary') {
  59. $method = 'set' . ucfirst($property);
  60. // 转发访问请求
  61. if (method_exists($this, $method)) return $this->$method(null) ;
  62. }
  63. }
  64. }
  65. // 客户端
  66. $staffs = new Staffs('阮总', 98000);
  67. // 访问了一个无访问权限的类属性
  68. echo '姓名: ' .$staffs->name .'<br>';
  69. echo '工资: ' .$staffs->salary;
  70. echo '<hr>';
  71. $staffs->name = '冯总';
  72. $staffs->salary = 96000;
  73. echo '姓名: ' .$staffs->name .'<br>';
  74. echo '工资: ' .$staffs->salary;
  75. echo '<hr>';
  76. echo isset($staffs->name) ? '存在 <br>' : '不存在';
  77. echo isset($staffs->salary) ? '存在 <br>' : '不存在';
  78. echo '<hr>';
  79. unset($staffs->name);
  80. echo $staffs->name;
  81. unset($staffs->salary);
  82. echo $staffs->salary;

效果图:

三、方法重载/拦截器

演示:

  1. <?php
  2. // 方法拦截器, 其实比属性拦截器更有用
  3. // __call(), __callStatic()
  4. class User
  5. {
  6. // 方法拦截器
  7. public function __call($name, $arr)
  8. {
  9. printf('方法名: %s , 参数: [%s]', $name, implode(', ', $arr));
  10. }
  11. // 静态方法拦截器
  12. public static function __callStatic($name, $arr)
  13. {
  14. printf('静态方法名: %s , 参数: [%s]', $name, implode(', ', $arr));
  15. }
  16. }
  17. $user = new User();
  18. $user->khong(8, 9, 7, 8);
  19. echo '<br>';
  20. User::no(8,8,8,8);

效果图:

三、操作数据库构造器

  1. <?php
  2. // 方法拦截器实战:数据库查询构造器的实现
  3. class Query
  4. {
  5. // 数据库连接
  6. protected $db;
  7. // 表名
  8. protected $table;
  9. // 字段列表
  10. protected $field;
  11. // 查询数量
  12. protected $limit;
  13. // 查询条件
  14. protected $where;
  15. // 构造方法完成数据库的连接
  16. public function __construct($dsn, $username, $password)
  17. {
  18. $this->connect($dsn, $username, $password);
  19. }
  20. // PDO连接数据库的方法
  21. private function connect($dsn, $username, $password)
  22. {
  23. $this->db = new PDO($dsn, $username, $password);
  24. }
  25. public function table($table)
  26. {
  27. $this->table = $table;
  28. return $this;
  29. }
  30. public function field($field)
  31. {
  32. $this->field = $field;
  33. return $this;
  34. }
  35. public function limit($limit)
  36. {
  37. $this->limit = $limit;
  38. return $this;
  39. }
  40. public function id($id)
  41. {
  42. $this->id = $id;
  43. return $this;
  44. }
  45. public function getSql()
  46. {
  47. return sprintf('SELECT %s FROM %s WHERE id > %u LIMIT %s', $this->field, $this->table, $this->id, $this->limit);
  48. }
  49. public function select()
  50. {
  51. return $this->db->query($this->getSql())->fetchAll(PDO::FETCH_ASSOC);
  52. }
  53. }
  54. class DB
  55. {
  56. // 这里使用的静态方法拦截器
  57. public static function __callStatic($name, $arguments)
  58. {
  59. $dsn = 'mysql:host=localhost;dbname=phpedu';
  60. $query = new Query($dsn, 'root', 'root');
  61. // return call_user_func(函数/方法, 函数参数列表)
  62. // return call_user_func_array(函数/方法, 函数参数数组)
  63. return call_user_func([$query, $name], ...$arguments);
  64. }
  65. }
  66. $res=DB::table('staffs')->field('id, name, position')->id(3)->limit(5)->select();
  67. print_r($res);

效果图:

总结:这个拦截器、拦截器是第一次接触,挺蒙的,刷了3-4遍视频才看明白——只是看明白,要撑握只能后面慢慢练习了。

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:不错
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post