Zunächst führen wir das Konzept der späten statischen Bindung durch einen Code ein:
class A { public static function who() { echo __CLASS__, PHP_EOL; } public static function test() { self::who(); } } class B extends A { public static function who() { echo __CLASS__, PHP_EOL; } } B::test(); // A
In diesem Code verwenden wir das Schlüsselwort self, wenn wir Klasse B verwenden Die statische Methode test () verweist auf die Methode who () der Klasse A, sodass die Ausgabe A ist. Seien Sie nicht aufgeregt, das ist eine gewöhnliche statische Bindung. Was das Schlüsselwort self aufruft, hängt von der Klasse ab, in der es definiert ist. Mit anderen Worten: Unabhängig davon, wie Sie erben oder welche Unterklasse zum Aufrufen der test()-Methode verwendet wird, ruft das Schlüsselwort self die who()-Methode der Klasse A auf.
Was ist mit der späten statischen Bindung? Tatsächlich ist es ein bisschen wie ein instanziiertes Klassenobjekt. Jedes instanziierte Objekt ruft sich selbst auf, nicht die Attributmethode der übergeordneten Klasse. Gewöhnliche statische Aufrufe sind nicht so, aber in Wirklichkeit müssen wir statische Eigenschaftsmethoden auf die gleiche Weise aufrufen wie instanziierte Objekte. Zu diesem Zeitpunkt können wir das Schlüsselwort static verwenden, um eine späte statische Bindung zu implementieren.
class C { public static function who() { echo __CLASS__, PHP_EOL; } public static function test() { static::who(); } } class D extends C { public static function who() { echo __CLASS__, PHP_EOL; } } D::test(); // D
Wenn das Schlüsselwort static verwendet wird, ist das who(), das hier innerhalb der von Klasse D aufgerufenen test()-Methode aufgerufen wird, Klasse D selbst.
Die Definition in der offiziellen Dokumentation lautet wie folgt:
Bei einem statischen Methodenaufruf ist der Klassenname der explizit angegebene (normalerweise auf der linken Seite des ::-Operators); Aufruf, es ist Die Klasse, zu der dieses Objekt gehört.
Diese Funktion wird aus sprachinterner Sicht „Late Static Binding“ genannt. „Späte Bindung“ bedeutet, dass static:: nicht mehr in die Klasse aufgelöst 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).
Zusätzlich zu den Schlüsselwörtern self und static haben wir auch ein übergeordnetes Schlüsselwort. Die Bedeutung dieses Schlüsselworts ist offensichtlich und ruft den statischen Inhalt der übergeordneten Klasse auf. Zum Testen verwenden wir gleichzeitig drei Schlüsselwörter:
class E { public static function who() { echo __CLASS__, PHP_EOL; } public static function test() { self::who(); static::who(); } } class F extends E { public static function who() { echo __CLASS__, PHP_EOL; } } class G extends F { public static function who() { parent::who(); echo __CLASS__, PHP_EOL; } } G::test(); // E // F // G
Schauen wir uns abschließend zwei PHP-Methoden an. Eine davon ist die Methode get_claimed_class(), mit der ermittelt wird, welche Klasse gerade aufgerufen wird. In der statischen Methode können Sie anhand der aufrufenden Methode bestimmen, welche Klasse die aktuelle Klasse ist, um andere Geschäftslogikoperationen auszuführen. Die andere ist die Methode „forward_static_call()“, die zum Aufrufen statischer Methoden verwendet wird.
class H { public static function who() { echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL; } public static function test() { echo get_called_class(), PHP_EOL; forward_static_call('who', 'a', 'b'); // xxx:a,b forward_static_call(['I', 'who'], 'c', 'd'); // I:c,d forward_static_call_array(['H', 'who'], ['e', 'f']); // H:e,f } } class I extends H { public static function who() { echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL; } } function who() { echo 'xxx:' . join(',', func_get_args()), PHP_EOL; } H::test(); // H // xxx:a,b // I:c,d // H:e,f I::test(); // I // xxx:a,b // I:c,d // H:e,f
Beachten Sie, dass die globale Methode aufgerufen wird, wenn forward_static_call() keinen Klassennamen angibt. forward_static_call_array() übergibt Parameter mithilfe eines Arrays.
测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/202001/source/%E5%90%8E%E6%9C%9F%E9%9D%99%E6%80%81%E7%BB%91%E5%AE%9A%E5%9C%A8PHP%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8.php