Blogger Information
Blog 55
fans 3
comment 0
visits 54032
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
属性与方法访问拦截器
王佳祥
Original
887 people have browsed it

属性与方法访问拦截器

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

  • 动态绑定静态成员的调用者/调用上下文
  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);


七、学习总结

  • 只能理解大概意思,有好多语句并不知道为什么这样用,我理解的方法委托就是在一个类的方法中调用另一个类的方法,然后在类外部调用
Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:如果对具体应用场景还不太理解, 就多多在网上搜集一些相关案例去看去模仿,去分析, 不付出大量的学习时间是不可能完全掌握的, 如果php是你接触的第一门编程语言,这很正常
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
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!