博主信息
博文 119
粉丝 3
评论 1
访问量 121251
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
拦截器、重载/拦截器
赵大叔
原创
938人浏览过

一、后期静态绑定

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遍视频才看明白——只是看明白,要撑握只能后面慢慢练习了。

批改老师:天蓬老师天蓬老师

批改状态:合格

老师批语:不错
本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
作者最新博文
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学