博客列表 >PHP - 静态绑定/属性拦截器及连接数据库案例

PHP - 静态绑定/属性拦截器及连接数据库案例

晴天
晴天原创
2020年05月09日 22:28:29695浏览

1.静态继承上下文

  1. //静态继承上下文
  2. class A
  3. {
  4. public function demo()
  5. {
  6. //.....
  7. }
  8. }
  9. class B extends A{
  10. public function demo()
  11. {
  12. parent::demo();
  13. }
  14. }
  15. ## 上面便是一个继承上下文环境,若要改为静态继承上下文,直接在function前面加static 即可

2.后期静态绑定

  1. //后期静态绑定:也叫延迟静态绑定
  2. ## 后期静态绑定工作在静态继承上下文环境中
  3. //创建一个抽象类
  4. abstract class Creat
  5. {
  6. }
  7. //创建实现类
  8. class User extends Creat
  9. {
  10. public static function create(){
  11. return new static();
  12. }
  13. }
  14. class Product extends User
  15. {
  16. }
  17. var_dump(User::create());
  18. //输出 object(User)#1 (0) { }
  19. echo '<hr>';
  20. var_dump(Product::create());
  21. //输出 object(Product)#1 (0) { }
  22. ## 方法里面如果用new self() 他返回的是实现该方法的类的类名 、 使用 new static() 他返回的是调用该方法的类的类名
  1. <?php
  2. //我们可以把它上移到抽象类中
  3. ## 注意:抽象类不能实例化,所以使用new self() 是错误的
  4. //解决方案:将类的定义与类的调用完全分离开。使用后期静态绑定方案 static 关键字将self替换掉
  5. //创建一个抽象类
  6. abstract class Creat
  7. {
  8. public static function create(){
  9. // return new self();
  10. return new static();
  11. // self 始终与定义该方法(属性)的类进行绑定
  12. // static 始终与调用该方法(属性)的类进行绑定
  13. }
  14. }
  15. //创建实现类
  16. class User extends Creat
  17. {
  18. }
  19. class Product extends User
  20. {
  21. }
  22. var_dump(User::create());
  23. //输出 object(User)#1 (0) { }
  24. echo '<hr>';
  25. var_dump(Product::create());
  26. //输出 object(Product)#1 (0) { }

3.魔术方法

  1. <?php
  2. //魔术方法
  3. //语法:类中有一些方法总是使用双下划线开头,这就叫魔术方法
  4. // 调用者:由系统根据一定的条件或用户行为,自动调用/触发,禁止用户主动调用
  5. //构造方法:__construct(),是类的实例化过程中被自动调用,new的时候
  6. class Product{
  7. private $name;
  8. private $price;
  9. // 创建构造器:生成一个新对象
  10. public function __construct($name,$price)
  11. {
  12. ## $this是由PHP接管的对象,不能用户设置
  13. // $this = new self(); 此段省略即可
  14. ## 初始化这个新对象:给这个新对象添加属性并赋值,或自动执行某些操作方法
  15. $this->name = $name;
  16. $this->price = $price;
  17. $this->white();
  18. ## 返回这个刚创建并初始化的对象
  19. // return $this;
  20. ## 隐式返回当前新生的类实例,不用显示返回,自动完成
  21. }
  22. public function white()
  23. {
  24. echo $this->name.':'.$this->price;
  25. }
  26. }
  27. //只需将参数传入到类中即可
  28. $product = new Product('上衣',500);

4. 属性拦截器

名称 描述
__get 属性查询拦截器
__set 属性设置拦截器
__isset 属性检测拦截器
__unset 属性销毁拦截器

注意:__get可以单独使用,但是__set要同__get 一起使用方能生效

4.1 属性查询拦截器

  1. <?php
  2. class User
  3. {
  4. private $name;
  5. private $price;
  6. public function __construct($name,$price)
  7. {
  8. $this->name = $name;
  9. $this->price = $price;
  10. }
  11. // 属性查询拦截器:拦截转发器:将拦截下来的值根据设置转发出去或拦截下来
  12. public function __get($property)
  13. {
  14. // return ($private === 'name') ? mb_substr($this->name,0,5) :'禁止访问';
  15. // 将传进来的参数前面加get 首字母大写 转发给对应的方法,专用于处理属性访问
  16. $method = 'get'.ucfirst($property);
  17. // 如果有该方法则转到,若没有返回没有该方法
  18. return method_exists($this,$method) ? $this->$method() : '没有该方法';
  19. }
  20. // 创建方法,返回name值
  21. private function getName()
  22. {
  23. // 只返回前五个字符
  24. return mb_substr($this->name,0,5);
  25. }
  26. }
  27. //传参
  28. $user = new User('联想笔记本电脑Y7000p',7999);
  29. echo $user->name;
  30. //输出 联想笔记本
  31. //访问原理,这里访问的不是name的值,而是被属性拦截器拦截下来经过处理转发到getName方法返回的数据

4.2 属性设置拦截器

  1. <?php
  2. //属性设置拦截器
  3. class User
  4. {
  5. private $name;
  6. private $price;
  7. // 创建构造器
  8. public function __construct($name, $price)
  9. {
  10. $this->name = $name;
  11. $this->price = $price;
  12. }
  13. // 属性查询拦截器:拦截转发器:将拦截下来的值根据设置转发出去或拦截下来
  14. public function __get($property)
  15. {
  16. // return ($private === 'name') ? mb_substr($this->name,0,5) :'禁止访问';
  17. // 将传进来的参数前面加get 首字母大写 转发给对应的方法,专用于处理属性访问
  18. $method = 'get'.ucfirst($property);
  19. // 如果有该方法则转到,若没有返回没有该方法
  20. return method_exists($this,$method) ? $this->$method() : '没有该方法';
  21. }
  22. // 创建方法,返回name值
  23. private function getName()
  24. {
  25. // 只返回前五个字符
  26. return mb_substr($this->name,0,5);
  27. }
  28. private function getPrice(){
  29. return $this->price;
  30. }
  31. //////////////////////////////////
  32. // 创建属性设置拦截器 set给两个值,第一个 属性名 第二个 新属性值
  33. public function __set($property,$value)
  34. {
  35. $method = 'Set'.ucfirst($property);
  36. // 转发设置请求
  37. return method_exists($this,$method) ? $this->$method($value) : null;
  38. }
  39. // 创建属性设置方法
  40. public function setName($value)
  41. {
  42. // 清一下空白字符
  43. $this->name = trim($value);
  44. }
  45. public function setPrice($value)
  46. {
  47. $this->price = $value * 0.2;
  48. }
  49. }
  50. $user = new User('联想笔记本电脑', 7999);
  51. echo $user->name; //输出联想笔记本
  52. echo $user->price;//输出 7999
  53. echo '<hr>';
  54. //更新name值
  55. $user->name = ' macbook ';
  56. //更新price值
  57. $user->price = 121121;
  58. echo $user->name; //输出 macbo 因为__get拦截器只返回五个字符
  59. echo $user->price;//输出 24224.2

4.3 属性检测/销毁拦截器

  1. <?php
  2. //属性设置拦截器
  3. class User
  4. {
  5. private $name;
  6. private $price;
  7. // 创建构造器
  8. public function __construct($name, $price)
  9. {
  10. $this->name = $name;
  11. $this->price = $price;
  12. }
  13. /* * * * * * * * * * * * */
  14. // 给一个属性查询拦截器 供销毁测试
  15. public function __get($property)
  16. {
  17. $method = 'get' . ucfirst($property);
  18. // 先检测有没有该方法
  19. return method_exists($this, $method) ? $this->$method() : 'djdsdhjkds';
  20. }
  21. private function getName()
  22. {
  23. return $this->name;
  24. }
  25. private function getPrice()
  26. {
  27. return $this->price;
  28. }
  29. /* * * * * * * * * * * * */
  30. // 属性检测拦截器
  31. public function __isset($property)
  32. {
  33. // 只让检测name值
  34. return $property === 'name' ? isset($this->name) : false;
  35. }
  36. //属性销毁拦截器
  37. public function __unset($property)
  38. {
  39. // 只让删除name值
  40. $property === 'name' ? $this->name = null : null;
  41. }
  42. }
  43. $user = new User('联想笔记本电脑', 7999);
  44. //检测一下是否存在
  45. var_dump(isset($user->name)); //输出 true
  46. //检测price
  47. var_dump(isset($user->price)); //输出 false
  48. echo $user->price;
  49. echo $user->name;
  50. echo '<hr>';
  51. //删除name值
  52. unset($user->name);
  53. echo $user->name; //成功
  54. //删除price值
  55. unset($user->price);
  56. echo $user->price; //正常输出 删除失败

5. 方法拦截器

  1. <?php
  2. // 方法拦截器
  3. // __call(), __callSTatic()
  4. // 就是创建一个方法
  5. class User
  6. {
  7. //创建方法拦截器
  8. public function __call($name, $arguments)
  9. {
  10. // implode 将数组转为字符串
  11. printf('方法名:%s --- 参数:%s ', $name, implode(',', $arguments));
  12. }
  13. // 创建静态方法拦截器
  14. public static function __callStatic($name,$arguments)
  15. {
  16. printf('方法名:%s --- 参数:%s ', $name, implode(',', $arguments));
  17. }
  18. }
  19. $user = new User();
  20. $user->demo(1, 2, 3, 4); // 输出 方法名:demo --- 参数:1,2,3,4
  21. echo '<hr>';
  22. //静态访问
  23. User::demo(1,2,3,3) // 输出 方法名:demo --- 参数:1,2,3,3

6. 小案例:利用构造器和拦截器实现链接数据库并查询

  1. <?php
  2. //利用构造器 方法拦截器实现数据库查询
  3. class Datebase
  4. {
  5. // 数据库链接
  6. protected $db;
  7. //表名
  8. protected $table;
  9. //字段列表
  10. protected $field;
  11. //查询条数
  12. protected $limit;
  13. //构造方法实现数据库链接
  14. public function __construct($dsn, $username, $password)
  15. {
  16. // 转发给connect
  17. $this->connect($dsn, $username, $password);
  18. }
  19. //创建PDO链接
  20. private function connect($dsn, $username, $password)
  21. {
  22. // 用PDO方式链接
  23. $this->db = new PDO($dsn, $username, $password);
  24. }
  25. // 写入表名
  26. public function table($table)
  27. {
  28. $this->table = $table;
  29. return $this;
  30. }
  31. // 字段列表
  32. public function field($field)
  33. {
  34. $this->field = $field;
  35. return $this;
  36. }
  37. //查询条数
  38. public function limit($limit)
  39. {
  40. $this->limit = $limit;
  41. return $this;
  42. }
  43. // 创建查询数据库字段
  44. public function getSql()
  45. {
  46. return sprintf('SELECT %s FROM %s LIMIT %s', $this->field, $this->table, $this->limit);
  47. }
  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. // TODO: Implement __callStatic() method.
  60. $dsn = 'mysql:host=localhost;dbname=php11.edu';
  61. $datebase = new Datebase($dsn,'php11.edu','php11.edu');
  62. return call_user_func([$datebase,$name],...$arguments);
  63. }
  64. }
  65. $res = DB::table('staffs')
  66. ->field('id,name,age')
  67. ->limit(5)
  68. ->select();
  69. print_r($res);
  70. //输出Array
  71. //(
  72. // [0] => Array
  73. // (
  74. // [id] => 1
  75. // [name] => 侯亮平
  76. // [age] => 40
  77. // )
  78. //
  79. // [1] => Array
  80. // (
  81. // [id] => 2
  82. // [name] => 祁同伟
  83. // [age] => 46
  84. // )
  85. //
  86. // [2] => Array
  87. // (
  88. // [id] => 3
  89. // [name] => 高育良
  90. // [age] => 57
  91. // )
  92. //
  93. // [3] => Array
  94. // (
  95. // [id] => 4
  96. // [name] => 李达康
  97. // [age] => 51
  98. // )
  99. //
  100. // [4] => Array
  101. // (
  102. // [id] => 5
  103. // [name] => 沙瑞金
  104. // [age] => 56
  105. // )
  106. //
  107. //)

7. 总结

方法拦截器中 若使用__set必须先创建__get;
数据库案例 学了数据库后终于可以看明白了~~

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议