• 售前

  • 售后

热门帖子
入门百科

PHP耽误静态绑定的深入讲解

[复制链接]
米老鼠和蓝精鼠v 显示全部楼层 发表于 2021-10-25 19:06:55 |阅读模式 打印 上一主题 下一主题
前言
所谓耽误静态绑定,顾名思义,静态调用时::符号左侧的部分的的绑定是耽误,也就是说不再被解析为定义当火线法地点的类,而是在现实运行时盘算的。本文重要先容了关于PHP耽误静态绑定的相干内容,下面话不多说了,来一起看看详细的先容吧。
嗅到了坏的味道

这段时间看项目后台的PHP代码,看到了类似于以下的一段代码,我把它抽出来:
  1. <?php
  2. class DBHandler {
  3.   function get() {}
  4. }
  5. class MySQLHandler extends DBHandler {
  6.   // 这里一个create
  7.   public static function create() {
  8.    echo "MySQL";
  9.    return new self();
  10.   }
  11.   public function get() {
  12.    echo "MySQL get()";
  13.   }
  14. }
  15. class MemcachedHandler extends DBHandler {
  16.   // 这里又有一个create
  17.   public static function create() {
  18.    echo "Memcached";
  19.    return new self();
  20.   }
  21.   public function get() {
  22.    echo "Memcached get";
  23.   }
  24. }
  25. function get(DBHandler $handler) {
  26.   $handler->get();
  27. }
  28. $dbHandler = MySQLHandler::create();
  29. get($dbHandler);
  30. ?>
复制代码
有没有嗅到坏代码的味道?可以看到,在MySQLHandler和MemcachedHandler类中,都有一个create函数,除掉我的输出语句,发现它们一模一样,这就是代码冗余。是的,需要举行代码重构。
举行简朴的重构

代码重构无处不在,只要你想,你觉的有改进,就需要敲起键盘开始干活。来吧,对上面的代码举行重构,如下:
  1. <?php
  2. class DBHandler {
  3.   public static function create() {
  4.    echo "create";
  5.    return new self();
  6.   }
  7.   function get() {}
  8. }
  9. class MySQLHandler extends DBHandler {
  10.   public function get() {
  11.    echo "MySQL get()";
  12.   }
  13. }
  14. class MemcachedHandler extends DBHandler {
  15.   public function get() {
  16.    echo "Memcached get";
  17.   }
  18. }
  19. function get(DBHandler $handler) {
  20.   $handler->get();
  21. }
  22. $dbHandler = MySQLHandler::create();
  23. get($dbHandler);
  24. ?>
复制代码
将create函数移到DBHandler类中,看起来还不错,至少少了一坨那糟糕的代码。
貌似是错的

运行一下,却发现,并没有打印出我们盼望的
  1. MySQL get() 
复制代码
。什么情况?这说明,并没有调用MySQLHandler的get函数,但是代码显着调用了啊,这说明,
  1. new self()
复制代码
这句代码有问题。这有什么问题?这就需要说到今天总结的重点了————耽误静态绑定。
耽误静态绑定

在PHP5.3以后引入了耽误静态绑定。再看下面这段代码:
  1. <?php
  2. class A {
  3.   public static function who() {
  4.    echo __CLASS__;
  5.   }
  6.   public static function test() {
  7.    self::who();
  8.   }
  9. }
  10. class B extends A {
  11.   public static function who() {
  12.    echo __CLASS__;
  13.   }
  14. }
  15. B::test();
  16. ?>
复制代码
上面的代码输出了A,但是我希望它输出B,这就是问题的地点。这也是 self 和 __CLASS__ 的限定。利用 self:: 大概 __CLASS__ 对当前类的静态引用,取决于定义当火线法地点的类。以是,这就很好的表明了为什么上面的代码输出了A。但是,如果我们需要输出B呢?可以这么干:
  1. <?php
  2. class A {
  3.   public static function who() {
  4.    echo __CLASS__;
  5.   }
  6.   public static function test() {
  7.    static::who(); // 这里有变化,后期静态绑定从这里开始
  8.   }
  9. }
  10. class B extends A {
  11.   public static function who() {
  12.    echo __CLASS__;
  13.   }
  14. }
  15. B::test();
  16. ?>
复制代码
后期静态绑定本想通过引入一个新的关键字表示运行时最初调用的类来绕过限定。简朴地说,这个关键字能够让你在上述例子中调用 test() 时引用的类是 B 而不是 A。终极决定不引入新的关键字,而是利用已经预留的 static 关键字。
这就是后期静态绑定的根本————static关键字的另类用法。对于文章一开始的例子,可以这么改:
  1. return new static(); // 改变这里,后期静态绑定
复制代码
这种利用后期静态绑定,在利用PHP实现23中设计模式的时间,你会感到很轻松的。
总结

就是一个很简朴的知识点,但是却非常有效,总结起来,照旧查了一些资料,补充一下知识点。温故而知新。好了,希望对各人有帮助。如果各人有什么发起,让我的文章写的更好,只管提出来,我需要各人的帮助。
好了,以上就是这篇文章的全部内容了,希望本文的内容对各人的学习大概工作具有一定的参考学习价值,如果有疑问各人可以留言交流,谢谢各人对脚本之家的支持。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作