Late Static Bindings (Résolution statique à la volée)
Depuis PHP 5.3.0, PHP implémente une fonctionnalité appelée late static binding, en français la résolution statique à la volée, qui peut être utilisée pour référencer la classe appelée dans un contexte d'héritage statique.
Plus précisément, les résolutions statiques à la volée fonctionnent en enregistrant le nom de la classe dans le dernier "appel non transmis". Dans le cas des appels de méthodes statiques, il s'agit de la classe explicitement nommée (généralement, celle à gauche de l'opérateur ::) ; dans le cas de méthodes non statiques, il s'agit de la classe de l'objet. Un "appel transmis" est un appel statique déclenché par self::, parent::, static::, ou, tout en haut de la hierarchie des classes, forward_static_call(). La fonction get_called_class() peut être utilisée pour récupérer une chaine contenant le nom de la classe appelée, et static:: introduit son espace.
Cette fonctionnalité a été baptisée "late static bindings", avec un point de vue interne. "Late binding", littéralement résolution tardive, vient du fait que les éléments static:: ne seront pas résolus en utilisant la classe où la méthode a été définie, mais celle qui est active durant l'exécution. L'adjectif statique a été ajouté car ce problème s'applique (sans y être limité) aux méthodes statiques.
Limitations de self::
Les références statiques à la classe courante, avec self:: ou __CLASS__, sont résolues en utilisant la classe à laquelle appartiennent les fonctions, celle où elles ont été définies :
Exemple #1 Utilisation de self::
<?php
class A {
public static function qui() {
echo __CLASS__;
}
public static function test() {
self::qui();
}
}
class B extends A {
public static function qui() {
echo __CLASS__;
}
}
B::test();
?>
L'exemple ci-dessus va afficher :
A
Utilisation de la résolution statique à la volée
La résolution statique à la volée essaie de dépasser cette limitation en introduisant un mot clé qui fait référence à la classe qui a été appelée durant l'exécution. Pour faire simple, ce mot-clé vous permet de faire référence à B depuis test(), dans l'exemple précédent. Il a été décidé de ne pas introduire de nouveau mot clé, mais plutôt d'utiliser le mot static qui était déjà réservé.
Exemple #2 Utilisation simple de static::
<?php
class A {
public static function qui() {
echo __CLASS__;
}
public static function test() {
static::qui(); // Ici, résolution à la volée
}
}
class B extends A {
public static function qui() {
echo __CLASS__;
}
}
B::test();
?>
L'exemple ci-dessus va afficher :
B
Note:
Dans les contextes non statiques, la classe appelée sera celle de l'objet. Comme $this-> essayera d'appeler des méthodes privées depuis le même contexte, utiliser static:: pourrait donner des résultats différents. Notez aussi que static:: ne peut faire référence qu'à des attributs/méthodes statiques.
Exemple #3 Utilisation de static:: dans un contexte non statique
<?php
class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {
/* foo() sera copiée dans B, par conséquent son contexte sera toujours A
* et l'appel se fera sans problème */
}
class C extends A {
private function foo() {
/* La méthode originale est remplacée; le contexte est celui de C */
}
}
$b = new B();
$b->test();
$c = new C();
$c->test(); //échoue
?>
L'exemple ci-dessus va afficher :
success! success! success! Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9
Note:
La résolution des statiques à la volée va s'arrêter à un appel statique complètement résolu. D'un autre coté, les appels statiques en utilisant un mot-clé comme parent:: ou self:: vont transmettre l'information appelante.
Exemple #4 Appel avec ou sans transmission
<?php
class A {
public static function foo() {
static::qui();
}
public static function qui() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function qui() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function qui() {
echo __CLASS__."\n";
}
}
C::test();
?>L'exemple ci-dessus va afficher :
A C C
Version en cache
21/11/2024 22:50:37 Cette version de la page est en cache (à la date du 21/11/2024 22:50:37) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.Document créé le 30/01/2003, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/php-rf-language.oop5.late-static-bindings.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.
Références
Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.