Blogger Information
Blog 30
fans 0
comment 2
visits 29299
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP 属性拦截器与方法拦截器
司马青衫
Original
1204 people have browsed it

PHP 属性拦截器与方法拦截器

PHP 属性拦截器

  • 当从类的外部,访问类中不存在或无权限访问的属性的时候 会自动调用它

  • __get()读取一个不可访问的属性/不存在的属性时会自动调用

  • __set()设置一个不可访问的属性/不存在的属性时会自动调用
  • __isset()对一个不可访问的属性进行调用isset()时自动调用
  • __unset()对一个不可访问的属性进行调用unset()时自动调用

  • 实例演示方法拦截器的__isset()__unset()

  1. <?php
  2. class Test{
  3. private $val = 'private';
  4. public function __get($value){
  5. $method = 'get'.ucfirst($value);
  6. return method_exists($this, $method)?$this->$method():"{$value}属性不存在";
  7. }
  8. public function __set($value, $setValue){
  9. $method = 'set'.ucfirst($value);
  10. echo method_exists($this, $method)?$this->$method($setValue):"{$value}属性不存在";
  11. }
  12. public function __isset($value){
  13. return isset($this->$value);
  14. }
  15. public function __unset($value){
  16. unset($this->$value);
  17. }
  18. //为私有成员提供访问接口 来过滤访问请求
  19. private function getVal(){
  20. return "不可访问的属性值:{$this->val}";
  21. }
  22. private function setVal($setValue){
  23. $this->val = $setValue;
  24. return "设置了不可访问的属性值:{$this->val}";
  25. }
  26. }
  27. $test = new Test();
  28. //读取一个不可访问的属性/不存在的属性
  29. echo $test->val;
  30. echo '<br>';
  31. echo $test->aa;
  32. echo '<hr>';
  33. //设置一个不可访问的属性/不存在的属性
  34. $test->val = 'public';
  35. echo '<br>';
  36. $test->aa = 'xxx';
  37. echo '<hr>';
  38. echo 'isset()调用__isset():';
  39. var_dump(isset($test->val));
  40. echo '<hr>';
  41. echo 'unset()调用__unset():';
  42. unset($test->val);
  43. echo $test->val;

PHP 方法拦截器

  • 当从类的外部,访问类中不存在或无权限访问的方法的时候 会自动调用它
  • __call()拦截一般方法
  • __callStatic()拦截静态方法
  1. <?php
  2. class Test{
  3. //私有方法 类外不可访问
  4. private function getClassInfo(){
  5. return __CLASS__;
  6. }
  7. //私有静态方法
  8. private static function getMethodInfo(){
  9. return __METHOD__;
  10. }
  11. //方法拦截器 访问类中的方法
  12. public function __call($method, $args){
  13. return (method_exists($this, $method))?$this->$method():'此方法不存在';
  14. }
  15. //静态方法拦截器 访问类中的静态方法
  16. public static function __callStaic($method, $args){
  17. return (method_exists(self, $method))?self::$method():'此方法不存在';
  18. }
  19. }
  20. $test = new Test();
  21. echo $test->getClassInfo();
  22. echo '<hr>';
  23. echo $test->getMethodInfo();

PHP 方法委托—跨类访问

  • 使用方法拦截器将不在当前类中存在的方法重定向到另一个类中
  • 使用回调方式调用另一个类中的方法
  1. <?php
  2. class ATest{
  3. //私有方法 类外不可访问
  4. private function getClassInfo(){
  5. return __CLASS__;
  6. }
  7. //私有静态方法
  8. private static function getMethodInfo(){
  9. return __METHOD__;
  10. }
  11. //方法拦截器 访问类中的方法
  12. public function __call($method, $args){
  13. return (method_exists($this, $method))?$this->$method():'此方法不存在';
  14. }
  15. //静态方法拦截器 访问类中的静态方法
  16. public static function __callStaic($method, $args){
  17. return (method_exists(self, $method))?self::$method():'此方法不存在';
  18. }
  19. }
  20. class BTest{
  21. //事件委托时 重定向到其它类
  22. private $test;
  23. public function __construct(ATest $Atest){
  24. $this->test = $Atest;
  25. }
  26. //方法拦截器 访问类中的方法 重定向到其他类中访问方法
  27. public function __call($method, $args){
  28. //使用回调方式调用方法
  29. return call_user_func([$this->test, $method], $args);
  30. }
  31. //静态方法拦截器 访问类中的静态方法 重定向到其他类中访问方法
  32. public static function __callStaic($method, $args){
  33. //使用回调方式调用方法
  34. return call_user_func(['Atest', $method], $args);
  35. }
  36. }
  37. $atest = new ATest();
  38. $btest = new BTest($atest);
  39. echo $btest->getClassInfo();
  40. echo '<hr>';
  41. echo $btest->getMethodInfo();

PHP 方法委托/方法拦截器实战

  • 实例演示查询构造器中的inset()update()delete()方法
  1. <?php
  2. class query{
  3. //连接对象
  4. protected $bd;
  5. //数据表
  6. protected $table;
  7. //字段列表
  8. protected $field;
  9. //记录数量
  10. protected $limit;
  11. //条件
  12. protected $condition;
  13. //构造方法:连接数据库
  14. public function __construct($dsn, $username, $password){
  15. $this->connect($dsn, $username, $password);
  16. }
  17. //连接数据库
  18. private function connect($dsn, $username, $password){
  19. $this->bd = new PDO($dsn, $username, $password);
  20. }
  21. //设置默认的数据表名称
  22. public function table($table){
  23. $this->table = $table;
  24. return $this;
  25. }
  26. //设置默认的字段名称
  27. public function field($field){
  28. $this->field = $field;
  29. return $this;
  30. }
  31. //设置数量
  32. public function limit($limit){
  33. $this->limit = $limit;
  34. return $this;
  35. }
  36. //设置条件
  37. public function condition($condition){
  38. $this->condition = $condition;
  39. return $this;
  40. }
  41. //生成数据库操作语句
  42. protected function getSql($operation){
  43. switch(strtolower($operation)){
  44. case 'select':
  45. $sql = sprintf('SELECT %s FROM %s LIMIT %s', $this->field, $this->table, $this->limit);
  46. break;
  47. case 'insert':
  48. $sql = sprintf('INSERT %s SET %s', $this->table, $this->field);
  49. break;
  50. case 'update':
  51. $sql = sprintf('UPDATE %s SET %s WHERE %s', $this->table, $this->field, $this->condition);
  52. break;
  53. case 'delete':
  54. $sql = sprintf('DELETE FROM %s WHERE %s', $this->table, $this->condition);
  55. break;
  56. }
  57. return $sql;
  58. }
  59. //执行
  60. public function execute($operation){
  61. switch(strtolower($operation)){
  62. case 'select':
  63. $result = $this->bd->query($this->getSql($operation))->fetchAll(PDO::FETCH_ASSOC);
  64. break;
  65. case 'insert':
  66. case 'update':
  67. case 'delete':
  68. $result = $this->bd->exec($this->getSql($operation));
  69. break;
  70. }
  71. return $result;
  72. }
  73. }
  74. //数据库操作类
  75. class DB{
  76. //静态方法委托
  77. public static function __callStatic($name, $args){
  78. //获取到查询类的对象
  79. $dsn = 'mysql:host=localhost;dbname=db_users';
  80. $username = 'root';
  81. $password = 'root';
  82. $query = new query($dsn, $username, $password);
  83. //直接跳转到query类中的具体方法来调用
  84. return call_user_func([$query, $name], ...$args);
  85. }
  86. }
  87. //查询
  88. $result = DB::table('user')->field('id,username,age')->limit(3)->execute('select');
  89. print_r($result);
  90. echo '<hr>';
  91. //插入
  92. $username = 'pdo';
  93. $password = md5('pdo');
  94. $age = 10;
  95. $insertInfo = sprintf("username='%s', password='%s', age='%d'", $username, $password, $age);
  96. $result = DB::table('user')->field($insertInfo)->execute('insert');
  97. echo "新增了{$result}条数据<br>";
  98. $updateInfo = sprintf("username='%s', password='%s', age='%d'", $username, $password, $age);
  99. $condition = 'id=61';
  100. $result = DB::table('user')->field($updateInfo)->condition($condition)->execute('update');
  101. echo "更新了{$result}条数据<br>";
  102. $condition = 'id=61';
  103. $result = DB::table('user')->condition($condition)->execute('delete');
  104. echo "删除了{$result}条数据<br>";

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