Ab Version 5.3 unterstützt PHP late binding für statische Methoden. Obwohl es ein zweifellos nützliches Merkmal ist, gibt es nur einige Fälle, in denen seine Verwendung wirklich notwendig ist (z. B. das Active Record-Muster).Kann die späte statische Bindung in PHP überstrapaziert werden?
Betrachten Sie diese Beispiele:
1. Convenience Bauer (::create()
)
class SimpleObject
{
public function __construct() { /* ... */ }
public static function create()
{
return new static; // or: return new self;
}
}
Wenn diese Klasse erweitert werden kann (es jedoch von jeder Klasse im gleichen Paket nicht verlängert wird), sollte späte statische Bindung verwendet werden, um es einfach zu erweitern (ohne die ::create()
Methode neu schreiben zu müssen, und, was noch wichtiger ist, ohne sich daran erinnern zu müssen)?
Hinweis: Dieses Idiom wird verwendet, um die Unmöglichkeit zu umgehen, Methoden nur auf konstruierten Objekten aufzurufen: new SimpleObject()->doStuff()
ist in PHP ungültig.
2. Klasse Konstanten
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];
}
}
Der Grund static::
in diesem Beispiel zu verwenden, um ähnlich der vorhergehenden ist. Es wird nur verwendet, weil diese Klasse dazu verwendet werden kann, unterschiedlich geformte Tags zu vergleichen, indem sie einfach erweitert und die Konstante überschrieben wird.
Also, um alles zu verpacken, sind diese Anwendungen (und ähnliche) der späten statischen Bindung ein Overkill? Gibt es einen spürbaren Leistungseinbruch? Verringert die häufige Verwendung der späten Bindung auch die durch Opcode-Caches gegebene Gesamtleistungssteigerung?
Nun, die zweite könnte erreicht werden, indem man eine private Variable außer Kraft setzt und '$ this' verwendet, oder? Oder verstehe ich etwas falsch? – Franz
Ja, aber ich konnte einfach nicht zu einem besseren Beispiel kommen ... Es als "const" zu haben bedeutet, es nicht durch alle Instanzen zu kopieren. Und selbst wenn das Copy-on-Write von PHP dies optimieren würde, sieht es sicherlich als Klassenkonstante besser aus, da es sich tatsächlich um einen konstanten Wert in der gesamten Klasse handelt. –
... und eigentlich meinte ich, dass in diesem Fall die Verwendung von Instanzvariablen wie ein Workaround aussieht, während 'static ::' nicht funktioniert. –