web-dev-qa-db-fra.com

Remplacement des constantes de classe par rapport aux propriétés

Je voudrais mieux comprendre pourquoi, dans le scénario ci-dessous, il existe une différence dans la façon dont les constantes de classe sont héritées par rapport aux variables d'instance.

<?php
class ParentClass {
    const TEST = "ONE";
    protected $test = "ONE";

    public function showTest(){
        echo self::TEST;
        echo $this->test;
    }
}

class ChildClass extends ParentClass {
    const TEST = "TWO";
    protected $test = "TWO";

    public function myTest(){
        echo self::TEST;
        echo $this->test;
    }
}

$child = new ChildClass();
$child->myTest();
$child->showTest();

Sortie:

TWO
TWO
ONE
TWO

Dans le code ci-dessus, ChildClass n'a pas de méthode showTest (), donc la méthode ParentClass showTest () est utilisée par héritage. Les résultats montrent que, puisque la méthode s'exécute sur ParentClass, la version ParentClass de la constante TEST est en cours d'évaluation, alors qu'elle est évaluée dans le contexte ChildClass via l'héritage, la variable membre ChildClass $ test est en cours d'évaluation.

J'ai lu la documentation, mais je ne vois aucune mention de cette nuance. Quelqu'un peut-il nous éclairer?

88
Tom Auger

self:: N'est pas compatible avec l'héritage et fait toujours référence à la classe dans laquelle il est exécuté. Si vous utilisez php5.3 +, vous pouvez essayer static::TEST comme static:: est sensible à l'héritage.

La différence est que static:: utilise la "liaison statique tardive". Trouvez plus d'informations ici:

http://php.net/manual/en/language.oop5.late-static-bindings.php

Voici un script de test simple que j'ai écrit:

<?php

class One
{
    const TEST = "test1";

    function test() { echo static::TEST; }
}
class Two extends One
{
    const TEST = "test2";
}

$c = new Two();

$c->test();

sortie

test2
175
David Farrell

En PHP, self fait référence à la classe dans laquelle la méthode ou la propriété appelée est définie. Donc dans votre cas, vous appelez self dans ChildClass, donc il utilise la variable de cette classe. Ensuite, vous utilisez self dans ParentClass, il fera donc référence à la variable de cette classe.

si vous voulez toujours que la classe enfant remplace le const de la classe parent, ajustez le code suivant dans votre classe parent à ceci:

public function showTest(){
    echo static::TEST;
    echo $this->test;
}

Notez le mot clé static. Il s'agit d'une "liaison statique tardive". Maintenant, votre classe parent appellera la constante de votre classe enfant.

14
w00