是否有可能在PHP中过度使用后期静态绑定?

Ign*_*s R 14 php late-binding late-static-binding

从5.3版开始,PHP支持静态方法的后期绑定.虽然这是一个无疑是有用的功能,但只有几种情况需要使用它(例如Active Record模式).

考虑这些例子:

1.便利施工人员(::create())

class SimpleObject
{
    public function __construct() { /* ... */ }

    public static function create()
    {
        return new static; // or: return new self;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这个类可能被扩展(但是,它没有被同一个包中的任何类扩展),那么应该使用延迟静态绑定来使它更容易扩展(无需重写::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];
    }
}
Run Code Online (Sandbox Code Playgroud)

static::在此示例中使用的原因与前一个类似.它的使用只是因为这个类可以通过扩展它并覆盖常量来匹配不同形式的标签.


那么,要将它们全部包装起来,这些后期静态绑定的使用(以及类似的)是否过度杀伤?是否有明显的性能影响?此外,频繁使用后期绑定是否会降低操作码缓存的整体性能提升?

Ewa*_*odd 16

那么,要将它们全部包装起来,这些后期静态绑定的使用(以及类似的)是否过度杀伤?是否有明显的性能影响?此外,频繁使用后期绑定是否会降低操作码缓存的整体性能提升?

后期静态绑定的引入修复了PHP的对象模型中的一个缺陷.这不是关于性能,而是关于语义.

例如,每当方法的实现不使用时,我喜欢使用静态方法$this.仅仅因为方法是静态的并不意味着你有时候不想覆盖它.在PHP 5.3之前,行为是如果你覆盖静态方法没有标记错误,但PHP会继续并静默使用父版本.例如,下面的代码在PHP 5.3之前打印'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();
?>
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是一个老线程,但通过谷歌找到它.无论PHP版本如何,您的示例代码都应该实际打印"A".要激活后期静态绑定,请使用static关键字.例如.替换self :: who(); with static :: who(); 它应该打印'B' (12认同)