PHP延迟静态绑定
来源:互联网 发布:本地端口1080 编辑:程序博客网 时间:2024/04/30 01:33
这段时间看项目后台的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();?>
通过引入延迟静态绑定功能,可以使用static作用域关键字访问类的属性或者方法的==最终值==,通过使用静态作用域,可以强制PHP在最终的类中查找所有属性的值。除了这个延迟绑定行为,PHP还添加了get_called_class()函数,这允许检查继承的方法是从哪个派生类调用的。以下代码显示了使用get_called_class()函数获得当前的类调用场景的方法。
g<?phpclass ParentBase { public static function render() { return get_called_class(); }}class Decendant extends ParentBase {}echo Descendant::render();Descendant
这就是后期静态绑定的根本————static关键字的另类用法。对于文章一开始的例子,可以这么改:
return new static(); // 改变这里,后期静态绑定
这种使用后期静态绑定,在使用PHP实现23中设计模式的时候,你会感到很轻松的。
- 总结
就是一个很简单的知识点,但是却非常有用,总结起来,还是查了一些资料,补充一下知识点。温故而知新。好了,希望对大家有帮助。如果大家有什么建议,让我的文章写的更好,尽管提出来,我需要大家的帮助。
- 摘自:http://www.jellythink.com/archives/956
- php 静态延迟绑定
- PHP延迟静态绑定
- PHP延迟静态绑定
- PHP延迟静态绑定
- PHP延迟静态绑定
- PHP延迟静态绑定
- PHP延迟静态绑定
- php的延迟静态绑定
- PHP静态延迟绑定:static
- php的延迟静态绑定
- php的延迟静态绑定
- php中“延迟静态绑定”的使用
- php--继承与延迟静态绑定
- PHP中延迟静态绑定机制
- php中“延迟静态绑定”的使用
- PHP静态延迟绑定简单示例
- php中“延迟静态绑定”的使用
- PHP-学习笔记 延迟静态绑定
- 将DataReader转换为DataDatable
- 为wget、pip等命令【设置代理】
- ABAP自动刷新ALV列表
- 接口
- JAVA学习随笔4
- PHP延迟静态绑定
- 不创建临时变量,交换两个数的内容
- Java 基础知识 mySQL使用 (二)
- 拦截导弹(数据加强)
- VR中的图形畸变
- 时钟插件
- JAVA学习随笔5
- css基础篇(黑马+慕课网笔记整理)
- php借助mcript扩展实现对称加密