【发布时间】:2010-12-21 10:54:24
【问题描述】:
从 5.3 版开始,PHP 支持 late binding 用于静态方法。虽然它无疑是一个有用的功能,但只有少数情况下确实需要使用它(例如 Active Record 模式)。
考虑以下示例:
1.便利构造函数 (::create())
class SimpleObject
{
public function __construct() { /* ... */ }
public static function create()
{
return new static; // or: return new self;
}
}
如果这个类可以扩展(但是,它没有被同一个包中的任何类扩展),是否应该使用后期静态绑定来使其更容易扩展(无需重写 ::create() 方法,以及更多重要的是,不必记住这样做)?
注意:这个习惯用法是用来解决不能在刚刚构造的对象上调用方法的问题:new SimpleObject()->doStuff() 在 PHP 中是无效的。
2。类常量
class TagMatcher
{
const TAG_PATTERN = '/\<([a-z\-]+?)\>/i';
private $subject;
public function construct($subject) { $this->subject = $subject; }
public function getAllTags()
{
$pattern = static::TAG_PATTERN;
preg_match_all($pattern, $this->subject);
return $pattern[1];
}
}
本例中使用static::的原因与上一个类似。之所以使用它,是因为该类可以通过扩展它并覆盖常量来匹配不同格式的标签。
那么,总结一下,后期静态绑定的这些用途(和类似用途)是不是有点矫枉过正?是否有明显的性能影响?另外,频繁使用后期绑定是否会降低操作码缓存带来的整体性能提升?
【问题讨论】:
-
嗯,第二个也可以通过覆盖私有变量并使用
$this来实现,对吧?还是我误会了什么? -
是的,但我想不出一个更好的例子……将它作为
const意味着避免在所有实例中复制它。即使 PHP 的写时复制会对此进行优化,它作为类常量当然看起来更好,因为它实际上是类范围内的常量值。 -
-
你是对的,
new SimpleObject()->doStuff()不会在你新建的对象上调用doStuff()。但是您不需要后期静态绑定来执行此操作,因为 PHP 确实 支持它。你只需要把它写成(new SimpleObject())->doStuff()。
标签: php late-binding late-static-binding