## Späte statische Bindung

PHP unterstützt späte statische Bindung ("Late static binding"). Hiermit kann die aufgerufene Klasse im Kontext statischer Vererbung referenziert werden.

Genauer gesagt funktioniert späte statische Bindung durch das Speichern der Klasse, die im letzten "nicht weiterleitenden Aufruf" angegeben wurde. Im Fall von statischen Methodenaufrufen ist dies die explizit angegebene Klasse (üblicherweise diejenige auf der linken Seite des Operators `::`); im Fall von nicht statischen Methodenaufrufen ist es die Klasse des Objekts. Ein "weiterleitender Aufruf" ist ein statischer, der durch `self::`, `parent::`, `static::` oder, in der Klassenhierarchie nach oben gehend, durch forward_static_call() eingeleitet wurde. Die Funktion get_called_class() kann benutzt werden, um eine Zeichenkette mit dem Namen der aufgerufenen Klasse abzufragen, und `static::` führt ihren Geltungsbereich ein.

Diese Funktionalität wurde in Hinblick auf die interne Perspektive als "späte statische Bindung" benannt. "Späte Bindung" bezieht sich auf die Tatsache, dass `static::` nicht über die Klasse, in der die aufgerufene Methode definiert ist, aufgelöst wird, stattdessen wird diese mit Hilfe von Laufzeitinformationen bestimmt. Die Benennung als "statische Bindung" beruht darauf, dass dieser Mechanismus unter anderem für statische Methodenaufrufe genutzt werden kann.

### Beschränkungen von `self::`

Statische Referenzen auf die aktuelle Klasse wie `self::` oder `__CLASS__` werden mit Hilfe der Klasse, zu der die Methode gehört, also in welcher sie definiert ist, aufgelöst.

Beispiel #1 Nutzung von `self::`

    <?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();

    ?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

    A

### Nutzung später statischer Bindung

Späte statische Bindung versucht diese Beschränkung zu umgehen, indem ein neues Schlüsselwort eingeführt wird, das die Klasse referenziert, die tatsächlich zur Laufzeit genutzt wurde. Im Grunde genommen also ein Schlüsselwort, das es im vorherigen Beispiel ermöglicht die Klasse `B` aus der aufgerufenen Methode `test()` zu referenzieren. Es wurde entschieden, kein neues Schlüsselwort einzuführen, sondern statt dessen `static` zu verwenden, das bereits als reserviertes Schlüsselwort existierte.

Beispiel #2 Einfache Nutzung von `static::`

    <?php

    class A
    {
        public static function who()
        {
            echo __CLASS__;
        }

        public static function test()
        {
            static::who(); // Hier kommt die späte statische Bindung
        }
    }

    class B extends A
    {
        public static function who()
        {
            echo __CLASS__;
        }
    }

    B::test();

    ?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

    B

> Hinweis:

> In nicht statischen Kontexten ist die aufgerufene Klasse die Klasse des Objekt-Exemplars. Da `$this->` versucht private Methoden im gleichen Geltungsbereich aufzurufen, kann die Verwendung von `static::` andere Ergebnisse liefern. Ein weiterer Unterschied ist, dass `static::` sich nur auf statische Eigenschaften beziehen kann.

Beispiel #3 Nutzung von `static::` außerhalb eines statischen Kontexts

    <?php

    class A
    {
        private function foo()
        {
            echo "Erfolg!\n";
        }

        public function test()
        {
            $this->foo();
            static::foo();
        }
    }

    class B extends A
    {
        /* foo() wird nach B kopiert, weshalb ihr Geltungsbereich immer noch A ist
        * und der Aufruf erfolgreich sein wird */
    }

    class C extends A
    {
        private function foo()
        {
            /* ursprüngliche Methode wird ersetzt; der Geltungsbereich der neuen ist C */
        }
    }

    $b = new B();
    $b->test();

    $c = new C();
    try {
        $c->test();
    } catch (Error $e) {
        echo $e->getMessage();
    }

    ?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

    Erfolg!
    Erfolg!
    Erfolg!
    Call to private method C::foo() from scope A

> Hinweis:

> Die Auflösung später statischer Bindungen endet mit einem vollständig aufgelösten statischen Aufruf ohne Alternative. Statische Aufrufe, die Schlüsselworte wie `parent::` oder `self::` nutzen, geben dagegen die Aufrufinformationen weiter.

> Beispiel #4 Weitergegebene und nicht weitergegebene Aufrufe

>     <?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();

>     ?>

> Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

>     A
>     C
>     C

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open