appeler une méthode statique dans une classe?

166

comment appeler une méthode statique à partir d'une autre méthode dans la même classe?

$this->staticMethod();

ou

$this::staticMethod();
Ajsie
la source
13
Cela pourrait vous intéresser ( selfvs. $this): stackoverflow.com/questions/151969/php-self-vs-this
Felix Kling
Juste un FYI, votre premier exemple est une variable d'instance appelant une méthode statique, ce qui n'est pas possible car une méthode statique fait partie de la classe et n'est pas accessible via une variable d'instance.
joejoeson
vous pouvez supprimer le $ this maintenant s'il vous plaît, cela ne fonctionne pas si vous utilisez uniquement des méthodes statiques et qu'aucune instance n'existe.
malhal

Réponses:

322
self::staticMethod();

Plus d'informations sur le mot-clé Static.

jeroen
la source
...mais pourquoi? $ this-> staticMethod () fonctionne aussi. Pouvez-vous expliquer pourquoi self :: staticMethod () est plus correct (si c'est le cas)?
Ian Dunn
29
@Ian Dunn En termes simples, $thisn'existe que si un objet a été instancié et que vous ne pouvez l'utiliser qu'à $this->methodpartir d'un objet existant. Si vous n'avez pas d'objet mais appelez simplement une méthode statique et que dans cette méthode, vous souhaitez appeler une autre méthode statique de la même classe, vous devez utiliser self::. Donc, pour éviter les erreurs potentielles (et les avertissements stricts), il est préférable d'utiliser self.
jeroen
1
Merci! Dans laravel, j'ai découvert que j'appelais accidentellement la méthode statique sur un contrôleur étendu en utilisant $this, mais le problème n'a pas surgi jusqu'à ce que le code soit poussé vers stage. aucune erreur n'est revenue, la valeur était juste 0. soyez prudent avec cela, utilisezself::
blamb
44

Supposons que ce soit votre classe:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

De l'intérieur de la foo()méthode, regardons les différentes options:

$this->staticMethod();

Cela appelle donc staticMethod()une méthode d'instance, non? Ce ne est pas. C'est parce que la méthode est déclarée comme public staticl'interpréteur l'appellera comme une méthode statique, donc elle fonctionnera comme prévu. On pourrait soutenir que cela rend moins évident d'après le code qu'un appel de méthode statique est en cours.

$this::staticMethod();

Depuis PHP 5.3, vous pouvez utiliser $var::method()pour signifier <class-of-$var>::; c'est assez pratique, bien que le cas d'utilisation ci-dessus soit encore assez peu conventionnel. Cela nous amène donc à la manière la plus courante d'appeler une méthode statique:

self::staticMethod();

Maintenant, avant de commencer à penser que ::est l' opérateur d'appel statique, laissez-moi vous donner un autre exemple:

self::bar();

Cela imprimera baz = 1, ce qui signifie que $this->bar()et self::bar()fera exactement la même chose; c'est parce que ::c'est juste un opérateur de résolution de portée. Il est là pour faire parent::, self::et le static::travail et vous donnent accès à des variables statiques; la manière dont une méthode est appelée dépend de sa signature et de la manière dont l'appelant a été appelé.

Pour voir tout cela en action, consultez cette sortie 3v4l.org .

Jack
la source
self::bar()semble trompeur - est-ce maintenant obsolète? (en utilisant self::pour appeler une méthode d'instance plutôt qu'une méthode statique).
ToolmakerSteve
@ToolmakerSteve de quelle manière diriez-vous que c'est trompeur?
Ja͢ck
Logiquement parlant, il n'y en a pas selflors de l'appel d'une méthode statique. Par définition: la méthode statique est appelable de n'importe où, et ne reçoit pas de paramètre "self". Néanmoins, je vois la commodité de cette phpsyntaxe, pour que vous n'ayez pas à écrire MyClassName::. Je suis habitué aux langages statiquement typés, où le compilateur doit recevoir toutes les variables disponibles dans la portée actuelle, donc (l'équivalent de) self::peut être omis. Donc un seul a dit self instanceMethod; aucune raison de dire self staticMethod.
ToolmakerSteve
15

C'est une réponse très tardive, mais ajoute quelques détails sur les réponses précédentes

Lorsqu'il s'agit d'appeler des méthodes statiques en PHP à partir d'une autre méthode statique sur la même classe, il est important de faire la différence entre selfet le nom de la classe.

Prenez par exemple ce code:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

La sortie de ce code est:

Classe originale

Classe étendue

En effet, il fait selfréférence à la classe dans laquelle se trouve le code, plutôt qu'à la classe du code à partir duquel il est appelé.

Si vous souhaitez utiliser une méthode définie sur une classe qui hérite de la classe d'origine, vous devez utiliser quelque chose comme:

$class = get_called_class();
$class::function_name(); 
Joundill
la source
2
J'ai trouvé cela informatif. Un petit peu, je ne dirais pas que les autres réponses sont "trompeuses". Plus juste pour dire qu'ils sont "incomplets"; ils n'abordent pas la question (non posée) de ce que self::fait dans le (rare) cas où une méthode statique A appelle une autre méthode statique B, et B a été remplacé dans une sous-classe. À mon humble avis, il est moins déroutant de restreindre le remplacement de méthode aux méthodes «d'instance»; utilisez cette capacité avec parcimonie au niveau statique. En d'autres termes, les lecteurs de votre code s'attendent à un remplacement de méthode des méthodes d'instance (c'est l'essence du codage OO), mais pas des méthodes statiques.
ToolmakerSteve
1
Très utile et il est logique qu'une extension de la classe ne soit pas la classe d'origine. Par conséquent, il va de soi qu'il selfne serait pas utilisé dans ce cas. Vous avez déclaré une classe distincte en tant qu'extension de la première classe. L'utilisation selfdans la classe étendue ferait référence à la classe étendue. Cela ne contredit pas les autres réponses, mais cela aide certainement à démontrer la portée de self.
iyrin le
2

Dans la dernière version de PHP self::staticMethod();ne fonctionnera pas non plus. Cela jettera l'erreur standard stricte.

Dans ce cas, nous pouvons créer un objet de même classe et appeler par objet

voici l'exemple

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}
Nishad Up
la source
Vous pouvez le faire, mais si vous fun1ne l'utilisez pas self, il n'est pas logique d'en faire une méthode d'instance. La bonne façon de le faire en php est de déclarer public static function fun1, alors appeler en spécifiant la classe: Foo::fun1. Je suis certain que c'est la manière prévue de corriger cette erreur standard stricte.
ToolmakerSteve