Starting with version 5.3, PHP supports late binding for static methods. While it's an undoubtedly useful feature, there are only several cases where its use is really necessary (e.g. the Active Record pattern).
Consider these examples:
1. Convenience constructors (::create()
)
class SimpleObject
{
public function __construct() { /* ... */ }
public static function create()
{
return new static; // or: return new self;
}
}
If this class may be extended (however, it's not extended by any class in the same package), should late static binding be used just to make extending it easier (without having to rewrite the ::create()
method, and, more importantly, without having to remember to do that)?
Note: this idiom is used to work around the impossibility to call methods on just constructed objects: new SimpleObject()->doStuff()
is invalid in PHP.
2. Class constants
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];
}
}
The reason to use static::
in this example is similar to the previous one. It's used just because this class can be made to match differently formed tags just by extending it and overriding the constant.
So, to wrap it all up, are these uses (and similar ones) of late static binding are an overkill? Is there any noticeable performance hit? Also, does frequent use of late binding reduce the overall performance boost given by opcode caches?
$this
, too, right? Or am I misunderstanding something? – Gilstrapconst
means avoiding copying it through all the instances. And even if PHP's copy-on-write would optimize this, it certainly looks better as a class constant, because it actually is a constant value class-wide. – Viceregentstatic::
doesn't. – Viceregentnew SimpleObject()->doStuff()
will not calldoStuff()
on your newly constructed object. But you don't require late static binding to do that, as PHP does support that. You just have to write it as(new SimpleObject())->doStuff()
. – Betweentimes