Menu

PHP static : méthodes, propriétés et self ou static

Une méthode ou une propriété static appartient à la classe, pas à un objet : vous l'appelez avec ClassName::method() et la lisez avec ClassName::$count, sans new. self:: ou static:: (liaison statique tardive), new static, les variables statiques dans les fonctions, et quand static est le mauvais outil.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Une méthode ou une propriété static appartient à la classe elle-même plutôt qu'à un objet. Vous appelez une méthode statique avec ClassName::method() et lisez une propriété statique avec ClassName::$property, sans créer d'objet au préalable. Dans la classe, self:: désigne les mêmes membres.

Il n'y a aucun new Temperature(). Les membres statiques sont utiles pour des fonctions utilitaires qui n'ont pas besoin d'état d'objet (conversions, fabriques, validation) et pour des données qui appartiennent à la classe dans son ensemble, comme un compteur.

Les propriétés statiques sont partagées par tous les objets

Une propriété normale a une valeur par objet. Une propriété statique a une seule valeur pour toute la classe, donc chaque objet voit la même. Ici, chaque nouveau User incrémente un compteur partagé et reçoit l'identifiant suivant :

Notez le $ dans self::$nextId : les propriétés statiques le gardent après ::, contrairement aux constantes (self::MAX). Une propriété statique ne vit que le temps d'une requête PHP. Sur un site web classique (PHP-FPM ou Apache), elle repart de zéro à chaque chargement de page, ce n'est donc pas un endroit où stocker des données entre visiteurs.

Les méthodes statiques n'ont pas de $this

Une méthode statique s'exécute sans objet, donc $this n'existe pas dedans. Une méthode statique peut appeler d'autres méthodes statiques avec self::, mais ne peut pas lire les propriétés normales. Appeler une méthode normale de façon statique échoue aussi :

Le sens inverse ne pose pas de problème : une méthode normale peut appeler des méthodes statiques, comme le fait withSeparator() avec self::make().

self ou static : la liaison statique tardive

self:: désigne la classe où le code est écrit. static:: désigne la classe sur laquelle la méthode a été appelée à l'exécution. La différence n'apparaît qu'avec l'héritage, et elle compte surtout pour les méthodes de fabrique :

Post::createWithSelf() renvoie un Model, ce que l'appelant ne voulait presque jamais. static se résout en Post car c'est la classe nommée dans l'appel ; PHP appelle cela la liaison statique tardive (late static binding). Utilisez static:: et new static() dans les méthodes destinées à être héritées, et self:: quand vous voulez vraiment cette classe précise. La même règle s'applique aux constantes : static::TABLE prend le TABLE propre d'un enfant, alors que self::TABLE lit toujours celui de la classe où le code est écrit.

Les propriétés statiques héritées sont partagées

Une classe enfant partage la propriété statique de son parent, sauf si elle déclare la sienne. C'est la surprise classique de static : deux sous-classes qui comptent dans un même nombre.

Apples n'a pas de $count à elle, donc Apples::$count est Counter::$count, et les deux affichent 2. Pears redéclare la propriété et compte de son côté. Une propriété statique déclarée dans un trait se comporte autrement : chaque classe qui utilise le trait en reçoit une copie séparée.

Les variables statiques dans les fonctions

static a un second sens dans le corps d'une fonction : une variable statique garde sa valeur entre les appels. La valeur initiale n'est affectée que la première fois que la fonction s'exécute :

Le second slowSquare(12) saute le calcul. Comme les propriétés statiques, ces valeurs sont réinitialisées à la fin de chaque requête. La page sur les variables traite de la portée des variables en général.

Quand static est le mauvais choix

Les méthodes statiques sont pratiques, et c'est ce qui pousse à en abuser. Une classe dont toutes les méthodes lisent et écrivent des propriétés statiques est un état global avec un nom de classe dessus : tous les appelants le partagent, les tests ne peuvent pas en obtenir une copie neuve, et vous ne pouvez pas le remplacer par une autre implémentation.

Les bons usages de static : des fonctions utilitaires pures sans état (Slug::make()), des constructeurs nommés (Color::fromHex()) et des constantes de classe. Si une méthode a besoin de données qui pourraient différer d'un usage à l'autre, elle réclame un objet.

Questions fréquentes

Comment appeler une méthode statique en PHP ?

Avec le nom de la classe et :: : MathHelper::square(4). Dans la même classe, utilisez self::square(4) ou static::square(4). Aucun objet n'est nécessaire, et il n'y a pas de $this dans une méthode statique.

Quelle est la différence entre self et static en PHP ?

self:: désigne toujours la classe où le code est écrit. static:: désigne la classe sur laquelle la méthode a réellement été appelée, qui peut être une classe enfant ; c'est la liaison statique tardive. Donc dans la méthode create() d'un parent, new self() construit toujours le parent, alors que new static() construit l'enfant qui l'a appelée.

Qu'est-ce qu'une propriété statique en PHP ?

Une propriété déclarée public static int $count = 0; appartient à la classe, donc il y a une seule valeur partagée par tous les objets de cette classe (et de ses enfants, sauf si un enfant la redéclare). Lisez-la et écrivez-la avec ClassName::$count ou self::$count ; notez le $.

Peut-on appeler une méthode statique sur un objet en PHP ?

Oui. $obj->square(4) et $obj::square(4) appellent tous deux la méthode statique de la classe de l'objet, mais il n'y a toujours pas de $this dedans. C'est l'inverse qui échoue : appeler une méthode non statique avec ClassName::method() lève une Error depuis PHP 8.

Peut-on utiliser $this dans une méthode statique ?

Non. Une méthode statique s'exécute sans objet, donc $this n'y est pas défini et l'utiliser lève une Error (« Using $this when not in object context »). Utilisez self:: ou static:: pour atteindre les autres membres statiques.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

COMMENCER