PHP 5.3 : LSB : Late Static Binding
27 octobre 2008 —Les exemples correspondant à ce point se trouvent dans le répertoire "late-static-binding".
PHP 5.3 introduit la notion "Late Static Binding" : tout ce qui est "statique" peut désormais être lié à l'exécution, et non plus à la compilation !
Sommaire :
- PHP 5.2 : Pas de Late Static Binding
- PHP 5.3 : Late State Binding
- Conserver le fonctionnement de PHP 5.2 en PHP 5.3
PHP 5.2 : Pas de Late Static Binding
Pour cadrer un peu les choses, je pense qu'il peut être judicieux de commencer par un exemple en PHP 5.2, illustrant le manque de LSB, et les problématiques posées.
Imaginons la classe Vehicule
, définie de la manière suivante :
class Vehicule {
public static function a() {
echo '<pre>' . __CLASS__ . '</pre>'; // Etape 3
}
public static function b() {
self::a(); // Etape 2 : PHP 5.2 => "self"
}
}
Et la classe Voiture
, qui défini un type spécifique de Vehicule
, et hérite donc de la première classe :
class Voiture extends Vehicule {
public static function a() {
echo '<pre>' . __CLASS__ . '</pre>';
}
}
Ces deux classes définissent toutes deux une méthode statique[1], nommée a
.
La classe-mère, quand à elle, défini en plus une seconde méthode statique, nommée b
, dont la classe Voiture
hérite.
Appelons cette méthode b
, statiquement, en passant par la classe fille :
Voiture::b(); // Etape 1
Les appels se font en trois étapes :
- Nous appelons la méthode
b
, définie dans la classe-mèreVehicule
, via la classe-filleVoiture
- Nous passons dans le corps de la méthode
Vehicule::b
, qui fait appel à la méthodeself::a
- PHP 5.2 ne fonctionne pas selon un mode tardif de résolution des données statiques ;
- Cela signifie que
self
correspond à la classe au sein de laquelleself
est utilisé... Ici,self
correspond donc àVehicule
(et non àVoiture
) - La méthode qui est appelée ensuite, via
self::a
, est doncVehicule::a
, et nonVoiture::a
- Et ce alors que nous avions commencé en appelant une méthode de la classe
Voiture
!
- Cela signifie que
Et le résultat final est l'affichage suivant :
Vehicule
Comme dit plus haut, le mot-clef self
désigne la classe au sein de laquelle il est utilisé ; ici, il s'agit de la classe Vehicule
; c'est dont la méthode Vehicule::a
qui a été finalement exécutée.
PHP 5.3 : Late State Binding
En réponse à cette limitation, à cause de laquelle jouer avec des méthodes et variables statiques en même temps que l'on travaille avec des classes héritant les unes des autres est particulièrement risqué en PHP <= 5.2, PHP 5.3 introduit la notion de "Late Static Binding".
Voyons ce qu'elle nous permet...
Pour commencer, voici une version révisée de notre classe Vehicule
, conçue pour tirer parti du LSB :
class Vehicule {
public static function a() {
echo '<pre>' . __CLASS__ . '</pre>';
}
public static function b() {
static::a(); // Etape 2 : PHP 5.3 LSB => "static"
}
}
La seule différence avec la version utilisée plus haut est l'emploi du mot-clef static
à la place du mot-clef self
lors de l'appel de la méthode a
.
La classe Voiture
, quant à elle, demeure définie de la même manière :
class Voiture extends Vehicule {
public static function a() {
echo '<pre>' . __CLASS__ . '</pre>'; // Etape 3
}
}
Et l'appel utilisé pour notre est toujours le même, passant par la classe Voiture
:
Voiture::b(); // Etape 1
Qu'obtenons-nous cette fois-ci ?
Ici encore, les appels se font en trois étapes :
- Nous appelons la méthode
b
, définie dans la classe-mèreVehicule
, via la classe-filleVoiture
- Nous passons dans le corps de la méthode
Vehicule::b
, qui fait appel à la méthodestatic::a
- PHP 5.3 peut fonctionner selon un mode tardif de résolution des données statiques ;
- Le mot-clef
static
, utilisé pour la résolution de classe, correspond à la classe appelée, et non à celle au sein de laquelle il est utilisé... Contrairement àself
. Ici,static
correspond donc àVoiture
- La méthode qui est appelée ensuite, via
static::a
, est doncVoiture::a
- Ce qui semble plus logique, puisque nous avions commencé par un appel à
Voiture::b
!
- Le mot-clef
Finalement, nous obtiendrons l'affichage suivant :
Voiture
Globalement, le Late Static Binding combiné à l'utilisation du mot-clef static
recyclé, permettent enfin de travailler de manière logique avec des méthodes statiques dans un contexte d'héritages.
Conserver le fonctionnement de PHP 5.2 en PHP 5.3
Cela dit, pour des raisons écidentes de compatibilité et de non cassage de code existant, le LSB ne change pas le fonctionnement qui était existant en PHP 5.2 !
Autrement dit, l'utilisation du mot-clef self
en PHP 5.3 donnera exactement le même type de comportement, et de résultats, que ce à quoi nous étions habitué en PHP <= 5.2 !
Note
[1] Le fait que la méthode définie dans les deux classes soit statique est le point important ici !