Question

Quels sont exactement les liaisons statiques fin en PHP?

Était-ce utile?

La solution

Vous devez absolument lire Late Static Manchettes dans le manuel PHP. Cependant, je vais essayer de vous donner un résumé rapide.

En fait, cela se résume au fait que le mot-clé self ne suit pas les mêmes règles d'héritage. self résout toujours à la classe dans laquelle il est utilisé. Cela signifie que si vous faites une méthode dans une classe parent et appelez à partir d'une classe enfant, self ne sera pas référence à l'enfant comme on pouvait s'y attendre.

La liaison tardive statique introduit une nouvelle utilisation pour le mot-clé static, qui répond à cette lacune particulière. Lorsque vous utilisez static, il représente la classe où la première utilisation, par exemple. il lie 'à la classe d'exécution.

Ce sont les deux concepts de base derrière elle. La self façon, parent et static fonctionnent lorsque static est en jeu peut être subtile, donc plutôt que d'aller pour plus de détails, je vous recommande fortement que vous étudiez les exemples de pages de manuel. Une fois que vous comprenez les bases de chaque mot-clé, les exemples sont tout à fait nécessaire de voir quel genre de résultats que vous allez obtenir.

Autres conseils

A partir de PHP 5.3.0, PHP implémente une fonctionnalité appelée liaison tardive statique qui peut être utilisé pour faire référence à la classe appelée dans le contexte de l'héritage statique.

La liaison tardive statique tente de résoudre cette limitation en introduisant un mot-clé qui fait référence à la classe qui a été initialement appelé à l'exécution. Il a été décidé de ne pas introduire un nouveau mot-clé, mais plutôt utiliser static qui était déjà réservé.

Voyons un exemple:

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

Travaux de late static bindings en stockant la classe nommée dans le dernier « appel non-renvoi ». Dans le cas d'appels de méthode statique, c'est la classe explicitement nommée (généralement celle à gauche de l'opérateur ::); dans le cas d'appels de méthodes non statiques, il est de la classe de l'objet.

A "appel de transfert" est un statique qui est introduite par self::, parent::, static::, ou, si remontant dans la hiérarchie de classe, forward_static_call().

La get_called_class() fonction peut être utilisée pour récupérer une chaîne avec le nom de la classe appelée et static:: introduit son champ d'application.

Il n'y a pas très comportement évident:

Le code suivant produit '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

Cependant, si on enlève la déclaration de la fonction classname de la classe bêta, nous obtenons « alphaalpha » comme résultat.

Je cite le livre: « Maître PHP écrire le code de pointe ».

  

La liaison tardive statique est une fonctionnalité introduite avec php 5.3. Il permet   nous héritons des méthodes statiques d'une classe parent, et de faire référence à   la classe enfant appelé.

     

Cela signifie que vous pouvez avoir une classe abstraite avec des méthodes statiques, et   référence implémentations concrètes de la classe des enfants en utilisant les    :: statique méthode () notation au lieu de la méthode auto :: ().

Ne hésitez pas à jeter un oeil à la documentation officielle de PHP ainsi: http://php.net/manual/en/language. oop5.late-statique bindings.php


La façon la plus claire d'expliquer liaison statique tardive est un exemple simple. Jetez un oeil sur les deux définitions de classe ci-dessous, et lisez ce qui suit.

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

Nous voyons une classe parent (véhicule) et une classe enfant (voiture). La classe parent dispose de 2 méthodes publiques:

  • invokeDriveByStatic
  • invokeStopBySelf

La classe parent dispose également de 2 méthodes privées:

  • drive
  • stop

La classe enfant remplace 2 méthodes:

  • drive
  • stop

Maintenant, nous allons appeler les méthodes publiques:

  • invokeDriveByStatic
  • invokeStopBySelf

Demandez-vous: Quelle classe invokeDriveByStatic invoque / invokeStopBySelf? Le parent ou la classe enfant?

Jetez un oeil ci-dessous:

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

Le mot-clé static est utilisé dans un modèle de conception Singleton. Voir le lien: https://refactoring.guru/design-patterns/singleton/php/example

L'exemple le plus simple pour montrer la différence.
Remarque, self :: $ c

class A
{
    static $c = 7;

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

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

B::getVal(); // 7

La liaison tardive statique, note statique :: $ c

class A
{
    static $c = 7;

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

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

B::getVal(); // 8

Par exemple:

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

En regardant cela d'un « pourquoi devrais-je utiliser? » perspective, il est fondamentalement un moyen de changer le contexte dans lequel la méthode statique est interprété / run.

Avec self, le contexte est celui où vous avez défini la méthode à l'origine. Avec static, il est celui que vous appelez à partir.

Aussi, regardez si vous mettez à jour les variables statiques dans les classes d'enfants. J'ai trouvé ce (un peu) résultat inattendu où les mises à jour enfant B enfant 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
// )

Vous pouvez le fixer en déclarant la même variable dans chaque classe enfant, par exemple:

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;        
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top