Seit PHP 5.3.0 hat PHP eine Funktion namens „späte statische Bindung“ hinzugefügt, die verwendet wird, um statisch aufgerufene Klassen im Vererbungsbereich zu referenzieren.
Um genau zu sein, besteht das Arbeitsprinzip der späten statischen Bindung darin, den Klassennamen im vorherigen „Nicht-Weiterleitungsaufruf“ zu speichern. Bei einem statischen Methodenaufruf ist der Klassenname der explizit angegebene (normalerweise auf der linken Seite des ::-Operators); bei einem nicht statischen Methodenaufruf ist es die Klasse, zu der das Objekt gehört. Der sogenannte „Weiterleitungsaufruf“ bezieht sich auf statische Aufrufe, die auf folgende Weise erfolgen: self::, parent::, static:: und forward_static_call(). Sie können die Funktion get_claimed_class() verwenden, um den Klassennamen der aufgerufenen Methode abzurufen, und static:: weist auf deren Gültigkeitsbereich hin.
Diese Funktion wird aus sprachinterner Sicht „Late Static Binding“ genannt. „Späte Bindung“ bedeutet, dass static:: nicht mehr in die Klasse geparst wird, in der die aktuelle Methode definiert ist, sondern zur tatsächlichen Laufzeit berechnet wird. Es kann auch als „statische Bindung“ bezeichnet werden, da es für Aufrufe statischer Methoden verwendet werden kann (aber nicht darauf beschränkt ist). Einschränkungen von
self::
Verwenden Sie self:: oder __CLASS__ für einen statischen Verweis auf die aktuelle Klasse, abhängig von der Klasse, in der die aktuelle Methode definiert ist:
Beispiel Nr. 1 selbst: : Verwendung
<?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(); ?>
Die obige Routine gibt Folgendes aus:
A
Verwendung einer späten statischen Bindung
Die späte statische Bindung wollte ursprünglich eine einführen Das neue Schlüsselwort stellt die Klasse dar, die die Laufzeit zunächst aufruft, um die Einschränkung zu umgehen. Einfach ausgedrückt ermöglicht Ihnen dieses Schlüsselwort, beim Aufruf von test() im obigen Beispiel auf Klasse B statt auf Klasse A zu verweisen. Es wurde schließlich beschlossen, keine neuen Schlüsselwörter einzuführen, sondern das bereits reservierte statische Schlüsselwort zu verwenden.
Beispiel #2 statisch:: Einfache Verwendung
<?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(); ?>
Die obige Routine gibt Folgendes aus:
B
Hinweis:
in einer nicht In der statischen Umgebung ist die aufgerufene Klasse die Klasse, zu der die Objektinstanz gehört. Da $this-> versucht, private Methoden im gleichen Bereich aufzurufen, kann static:: zu unterschiedlichen Ergebnissen führen. Ein weiterer Unterschied besteht darin, dass static:: nur mit statischen Eigenschaften verwendet werden kann.
Beispiel Nr. 3 mit statischer Aufladung::
<?php class A { private function foo() { echo "success!\n"; } public function test() { $this->foo(); static::foo(); } } class B extends A { /* foo() will be copied to B, hence its scope will still be A and * the call be successful */ } class C extends A { private function foo() { /* original method is replaced; the scope of the new one is C */ } } $b = new B(); $b->test(); $c = new C(); $c->test(); //fails ?>
Die obige Routine gibt Folgendes aus:
success! success! success! Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9
Hinweis:
Später Die Auflösung von statischer Aufladung Bindungen werden fortgesetzt, bis ein vollständig aufgelöster statischer Aufruf erhalten wird. Wenn andererseits ein statischer Anruf mit parent:: oder self:: erfolgt, werden die Anrufinformationen weitergeleitet.
Beispiel #4 Anrufe weiterleiten und nicht weiterleiten
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."\n"; } } class C extends B { public static function who() { echo __CLASS__."\n"; } } C::test(); ?>
Die obige Routine gibt Folgendes aus:
A C C