Frage

Was genau ist Späte statische Bindung in PHP?

War es hilfreich?

Lösung

Sie müssen auf jeden Fall Späte statische Bindung lesen in dem PHP-Handbuch. Ich werde jedoch versuchen Sie eine kurze Zusammenfassung zu geben.

Im Grunde läuft es auf die Tatsache, dass das self Schlüsselwort nicht den gleichen Regeln der Vererbung folgt. self löst sich immer auf die Klasse, in der sie verwendet wird. Dies bedeutet, dass wenn Sie eine Methode in einer übergeordneten Klasse zu machen und es von einem Kind Klasse aufrufen, self wird das Kind nicht verweisen wie man erwarten könnte.

Späte statische Bindung stellt eine neue Verwendung für das static Schlüsselwort, das dieses besondere Manko behebt. Wenn Sie static verwenden, stellt es die Klasse, wo Sie es zuerst verwenden, das heißt. es bindet 'auf die Laufzeitklasse.

Das sind die beiden grundlegenden Konzepte dahinter. Die Art und Weise self, parent und static arbeiten, wenn static im Spiel ist subtil sein kann, so anstatt zu gehen, um Details, würde ich empfehlen, dass Sie die Manpage Beispiele zu studieren. Sobald Sie die Grundlagen der einzelnen Keywords zu verstehen, sind die Beispiele durchaus notwendig, um zu sehen, was für Ergebnisse, die Sie bekommen werden.

Andere Tipps

Ab PHP 5.3.0, PHP implementiert eine Funktion späte statische Bindung aufgerufen, die verwendet werden kann, die gerufene Klasse im Rahmen der statischen Vererbung zu verweisen.

Späte statische Versuche verbindlich diese Einschränkung zu lösen, indem ein Schlüsselwort, das verweist auf die Klasse einzuführen, die ursprünglich zur Laufzeit aufgerufen wurden. Es wurde beschlossen, nicht ein neues Schlüsselwort einzuführen, sondern static verwenden, die bereits reserviert wurde.

Lassen Sie uns ein Beispiel sehen:

<?php
    class Car
    {
        public static function run()
        {
            return static::getName();
        }

        private static function getName()
        {
            return 'Car';
        }
    }

    class Toyota extends Car
    {
        public static function getName()
        {
            return 'Toyota';
        }
    }

    echo Car::run(); // Output: Car
    echo Toyota::run(); // Output: Toyota
?>

late static bindings Arbeit durch die Klasse in der letzten „Nicht-Anrufweiterschaltung“ genannt zu speichern. Bei statischen Methodenaufrufen, ist dies die Klasse explizit genannt (in der Regel auf der linken Seite des :: operator); bei nicht-statischer Methode Anrufe, es ist die Klasse des Objekts.

A "Anrufweiterschaltung" ist ein statische, die von self:: eingeführt wird, parent::, static::, oder, wenn in der Klassenhierarchie steigen, forward_static_call().

Die Funktion get_called_class() verwendet werden kann, eine Zeichenfolge mit dem Namen der aufgerufenen Klasse abzurufen und static:: stellt seinen Umfang.

Es ist nicht sehr offensichtlich Verhalten:

Der folgende Code erzeugt 'alpha'.

class alpha {

    function classname(){
        return __CLASS__;
    }

    function selfname(){
        return self::classname();
    }

    function staticname(){
        return static::classname();
    }
}

class beta extends alpha {

    function classname(){
        return __CLASS__;
    }
}

$beta = new beta();
echo $beta->selfname(); // Output: alpha
echo $beta->staticname(); // Output: beta

Wenn wir jedoch die Erklärung der Funktion Klassennamen aus der Beta-Klasse entfernen, wir bekommen ‚alphaalpha‘ als Ergebnis.

Ich zitiere aus dem Buch: „PHP-Master-Schreib topaktuelle Code“.

  

Späte statische Bindung war ein Feature mit PHP 5.3 eingeführt. Es erlaubt   wir zu vererben statischen Methoden von einer übergeordneten Klasse und zu Referenz   das Kind Klasse aufgerufen wird.

     

Diese Mittel können Sie eine abstrakte Klasse mit statischen Methoden haben, und   Verweisen Sie auf die konkrete Implementierungen des Kindes Klasse durch die Verwendung von    static :: Methode () Notation anstelle der Selbst :: Methode ().

Sie können ferner einen Blick auf die offizielle PHP-Dokumentation zu nehmen, wie gut: http://php.net/manual/en/language. oop5.late-static-bindings.php


Der klarste Weg zu erklären Späte statische Bindung mit einem einfachen Beispiel. Werfen Sie einen Blick auf die beiden Klassendefinitionen unten und lesen Sie weiter.

class Vehicle {
    public static function invokeDriveByStatic() {
        return static::drive(); // Late Static Binding
    }
    public static function invokeStopBySelf() {
        return self::stop(); // NOT Late Static Binding
    }
    private static function drive(){
        return "I'm driving a vehicle";
    }
    private static function stop(){
        return "I'm stopping a vehicle";
    }
}

class Car extends Vehicle  {
    protected static function drive(){
        return "I'm driving a CAR";
    }
    private static function stop(){
        return "I'm stopping a CAR";
    }
}

Wir sehen eine Übergeordnete Klasse (Fahrzeug) und eine Kinderklasse (Auto). Die Parent-Klasse hat zwei öffentliche Methoden:

  • invokeDriveByStatic
  • invokeStopBySelf

Die Parent-Klasse hat auch 2 private Methoden:

  • drive
  • stop

Die Child-Klasse überschreibt 2 Methoden:

  • drive
  • stop

Jetzt ist invoke die öffentlichen Methoden lassen:

  • invokeDriveByStatic
  • invokeStopBySelf

Fragen Sie sich: Welche Klasse aufruft invokeDriveByStatic / invokeStopBySelf? Der Elternteil oder Kind Klasse?

Werfen Sie einen Blick unter:

// This is NOT Late Static Binding
// Parent class invokes from Parent. In this case Vehicle.
echo Vehicle::invokeDriveByStatic(); // I'm driving a vehicle
echo Vehicle::invokeStopBySelf(); // I'm stopping a vehicle

// This is Late Static Binding.
// Child class invokes an inherited method from Parent.
// Child class = Car, Inherited method = invokeDriveByStatic().
// ...
// The inherited method invokes a method that is overridden by the Child class.
// Overridden method = drive()
echo Car::invokeDriveByStatic(); // I'm driving a CAR

// This is NOT Late Static Binding
// Child class invokes an inherited method from Parent.
// The inherited method invokes a method inside the Vehicle context.
echo Car::invokeStopBySelf(); // I'm stopping a vehicle

Das static Schlüsselwort wird in einem Singleton-Entwurfsmuster verwendet. Siehe Link: https://refactoring.guru/design-patterns/singleton/php/example

Das einfachste Beispiel den Unterschied zeigen.
Beachten Sie, self :: $ c

class A
{
    static $c = 7;

    public static function getVal()
    {
        return self::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 7

Späte statische Bindung, note static :: $ c

class A
{
    static $c = 7;

    public static function getVal()
    {
        return static::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 8

Zum Beispiel:

abstract class Builder {
    public static function build() {
        return new static;
    }
}

class Member extends Builder {
    public function who_am_i() {
         echo 'Member';
    }
}

Member::build()->who_am_i();

Betrachtet man es von einem „warum sollte ich diese verwenden?“ Perspektive, es ist im Grunde eine Möglichkeit, den Kontext zu ändern, von dem die statischen Methode interpretiert / ausgeführt wird.

Mit self, ist der Kontext, die, wo Sie die Methode ursprünglich definiert. Mit static, dann ist es die, die Sie aus sind aufgerufen wird.

Auch sehen, wenn Sie statische Variablen in Klassen Kind aktualisieren. Ich fand diese (etwas) unerwartetes Ergebnis in dem Kind B Updates Kind C:

class A{
    protected static $things;
}

class B extends A {
    public static function things(){
        static::$things[1] = 'Thing B';
        return static::$things; 
    }
}

class C extends A{
    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}

print_r(C::things());
// Array (
//   [2] => Thing C
// )

B::things();

print_r(C::things()); 
// Array (
//    [2] => Thing C
//    [1] => Thing B
// )

Sie können das Problem beheben, indem Sie die gleiche Variable in jedem Kind Klasse deklarieren, zum Beispiel:

class C extends A{
    protected static $things; // add this and B will not interfere!

    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top