Domanda

Che cosa sono esattamente i binding fine statiche in PHP?

È stato utile?

Soluzione

È sicuramente bisogno di leggere tardo statici Attacchi nel manuale di PHP. Tuttavia, cercherò di darvi un breve riassunto.

In sostanza, si riduce al fatto che la parola chiave self non segue le stesse regole di eredità. self risolve sempre alla classe in cui viene utilizzato. Questo significa che se si effettua un metodo in una classe genitore e chiamare da una classe figlia, self non farà riferimento il bambino come ci si potrebbe aspettare.

Fine binding statico introduce un nuovo impiego per la parola chiave static, che affronta questo particolare difetto. Quando si utilizza static, rappresenta la classe in cui primo utilizzo, vale a dire. E 'lega' alla classe runtime.

Questi sono i due concetti di base dietro di esso. Il modo in cui self, parent e static funzionano quando static è in gioco può essere sottile, così piuttosto che andare per maggiori dettagli, vi consiglio vivamente di studiare gli esempi delle pagine di manuale. Una volta a capire le basi di ogni parola chiave, sono molto necessari per vedere che tipo di risultati che si vuole ottenere gli esempi.

Altri suggerimenti

Dal PHP 5.3.0, PHP implementa una funzione chiamata tardiva statica vincolante che può essere utilizzato per fare riferimento alla classe denominata nel contesto di ereditarietà statica.

tardivi tentativi statici vincolanti per risolvere questa limitazione con l'introduzione di una parola chiave che fa riferimento alla classe che è stato inizialmente chiamato in fase di esecuzione. Si è deciso di non introdurre una nuova parola chiave, ma piuttosto utilizzare static che era già riservati.

Vediamo un esempio:

<?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
?>

lavoro late static bindings memorizzando la classe denominata in ultima "chiamata non-forwarding". In caso di chiamate di metodo statico, questa è la classe esplicitamente nominato (di solito quello a sinistra del :: dell'operatore); in caso di chiamate di metodo non statici, è la classe dell'oggetto.

Una "chiamata" è uno statico che viene introdotto da self::, parent::, static::, o, se salendo nella gerarchia delle classi, forward_static_call().

La get_called_class() funzione può essere utilizzata per recuperare una stringa con il nome della classe chiamato e static:: presenta il suo ambito di applicazione.

Non è un comportamento molto evidente:

Il seguente codice produce 'alphabeta'.

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

Tuttavia, se togliamo la dichiarazione della funzione nomeclasse dalla classe versione beta, si ottiene 'alphaalpha' come il risultato.

cito dal libro: "PHP Maestro Scrivi codice d'avanguardia".

  

Fine binding statico è stata una caratteristica introdotta con PHP 5.3. Permette   noi ereditiamo metodi statici da una classe genitore, ea referenziamo   la classe figlia chiamato.

     

Questo significa che puoi avere una classe astratta con metodi statici, e   riferimento implementazioni concrete della classe figlio utilizzando il    :: metodo statico () la notazione invece del self :: metodo ().

Sentitevi liberi di dare un'occhiata alla documentazione ufficiale di PHP, nonché: http://php.net/manual/en/language. oop5.late-static-bindings.php


Il modo più chiaro per spiegare tardo binding statico è con un semplice esempio. Date un'occhiata a due definizioni di classi inferiori, e continuate a leggere.

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";
    }
}

Si vede una classe genitore (veicolo) e una classe figlia (Car). La classe padre ha 2 metodi pubblici:

  • invokeDriveByStatic
  • invokeStopBySelf

La classe genitore dispone inoltre di 2 metodi privati:

  • drive
  • stop

La Classe Bambino sovrascrive 2 metodi:

  • drive
  • stop

Ora si invocano i metodi pubblici:

  • invokeDriveByStatic
  • invokeStopBySelf

Chiedetevi: Quale classe invoca invokeDriveByStatic / invokeStopBySelf? La classe genitore o un figlio?

Date un'occhiata qui sotto:

// 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

La parola chiave static viene utilizzato in un modello di progettazione Singleton. Vedi link: https://refactoring.guru/design-patterns/singleton/php/example

L'esempio più semplice per mostrare la differenza.
Nota, self :: $ c

class A
{
    static $c = 7;

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

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

B::getVal(); // 7

Fine binding statico, nota statica :: $ c

class A
{
    static $c = 7;

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

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

B::getVal(); // 8

Ad esempio:

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

Guardando la cosa da una "perché dovrei usare questo?" prospettiva, è fondamentalmente un modo per cambiare il contesto da cui il metodo statico viene interpretata / run.

Con self, il contesto è quello in cui è stato definito il metodo di origine. Con static, è quello che si sta chiamando da.

Inoltre, attenzione se si aggiorna variabili statiche in classi figlie. Ho trovato questo (un po ') risultato inaspettato in cui bambino B aggiornamenti bambino 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
// )

È possibile risolvere il problema dichiarando la stessa variabile in ogni classe bambino, per esempio:

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;        
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top