未加星标

PHP延迟静态绑定的深入讲解

字体大小 | |
[开发(php) 所属分类 开发(php) | 发布者 店小二05 | 时间 | 作者 红领巾 ] 0人收藏点击收藏

前言

所谓延迟静态绑定,顾名思义,静态调用时::符号左侧的部分的的绑定是延迟,也就是说不再被解析为定义当前方法所在的类,而是在实际运行时计算的。本文主要介绍了关php延迟静态绑定的相关内容,下面话不多说了,来一起看看详细的介绍吧。

嗅到了坏的味道

这段时间看项目后台的PHP代码,看到了类似于以下的一段代码,我把它抽出来:

<?php
class DBHandler {
function get() {}
}
class mysqlHandler extends DBHandler {
// 这里一个create
public static function create() {
echo "MySQL";
return new self();
}
public function get() {
echo "MySQL get()";
}
}
class MemcachedHandler extends DBHandler {
// 这里又有一个create
public static function create() {
echo "Memcached";
return new self();
}
public function get() {
echo "Memcached get";
}
}
function get(DBHandler $handler) {
$handler->get();
}
$dbHandler = MySQLHandler::create();
get($dbHandler);
?>

有没有嗅到坏代码的味道?可以看到,在MySQLHandler和MemcachedHandler类中,都有一个create函数,除掉我的输出语句,发现它们一模一样,这就是代码冗余。是的,需要进行代码重构。

进行简单的重构

代码重构无处不在,只要你想,你觉的有改进,就需要敲起键盘开始干活。来吧,对上面的代码进行重构,如下:

<?php
class DBHandler {
public static function create() {
echo "create";
return new self();
}
function get() {}
}
class MySQLHandler extends DBHandler {
public function get() {
echo "MySQL get()";
}
}
class MemcachedHandler extends DBHandler {
public function get() {
echo "Memcached get";
}
}
function get(DBHandler $handler) {
$handler->get();
}
$dbHandler = MySQLHandler::create();
get($dbHandler);
?>

将create函数移到DBHandler类中,看起来还不错,至少少了一坨那糟糕的代码。

貌似是错的

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

延迟静态绑定

在PHP5.3以后引入了延迟静态绑定。再看下面这段代码:

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>

上面的代码输出了A,但是我希望它输出B,这就是问题的所在。这也是 self 和 __CLASS__ 的限制。使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类。所以,这就很好的解释了为什么上面的代码输出了A。但是,如果我们需要输出B呢?可以这么干:

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 这里有变化,后期静态绑定从这里开始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>

后期静态绑定本想通过引入一个新的关键字表示运行时最初调用的类来绕过限制。简单地说,这个关键字能够让你在上述例子中调用 test() 时引用的类是 B 而不是 A。最终决定不引入新的关键字,而是使用已经预留的 static 关键字。

这就是后期静态绑定的根本――――static关键字的另类用法。对于文章一开始的例子,可以这么改:

return new static(); // 改变这里,后期静态绑定

这种使用后期静态绑定,在使用PHP实现23中设计模式的时候,你会感到很轻松的。

总结

就是一个很简单的知识点,但是却非常有用,总结起来,还是查了一些资料,补充一下知识点。温故而知新。好了,希望对大家有帮助。如果大家有什么建议,让我的文章写的更好,尽管提出来,我需要大家的帮助。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
您可能感兴趣的文章:PHP Static延迟静态绑定用法分析PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定PHP延迟静态绑定示例分享简单谈谈php延迟静态绑定php延迟静态绑定实例分析PHP静态延迟绑定和普通静态效率的对比

本文开发(php)相关术语:php代码审计工具 php开发工程师 移动开发者大会 移动互联网开发 web开发工程师 软件开发流程 软件开发工程师

主题: PHPSQLMySQLMemcached设计模式谢大变量
tags: get,function,绑定,public,static,静态,echo,class,DBHandler,延迟,PHP,#63,self,代码
分页:12
转载请注明
本文标题:PHP延迟静态绑定的深入讲解
本站链接:https://www.codesec.net/view/574921.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(php) | 评论(0) | 阅读(32)