Aller au contenu | Aller au menu | Aller à la recherche

lundi 27 octobre 2008

PHP 5.3 : LSB : 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 :

Lire la suite...

vendredi 24 octobre 2008

PHP 5.3 : __callStatic : appel magique de méthodes statiques

Les exemples correspondant à ce point se trouvent dans le répertoire "callStatic".

PHP 5.x nous permettait d’utiliser plusieurs méthodes magiques, dont, pour n’en citer que quelques unes, __get, __set, et __call.
Cette dernière permet d’appeler, pour un objet, une méthode non définie dans la classe : dans ce cas là, c’est la méthode __call qui sera appelée, en recevant en paramètre le nom de la méthode demandée par le code exécuté, et les paramètres qui avaient été passés à celle-ci.

Mais __call ne permet pas de gérer les appels statiques vers des méthodes inexistantes.

En réponse à ce manque, PHP 5.3 introduit une nouvelle méthode magique, dont le but est d’intercepter les appels statiques à des méthodes inexistantes.
Cette nouvelle méthode magique s’appelle, fort logiquement, __callStatic.


A titre d’exemple, imaginons la classe suivante, qui définit une méthode methode et une méthode statique methodeStatique, ainsi que les méthodes magiques __call et __callStatic :

class A {
    public static function __callStatic($name, $args) {
        echo "<pre>__callStatic A::{$name}("
            . implode(', ', $args) . ")</pre>";
    }
    public static function methodeStatique($p1) {
        echo "<pre>A::methodeStatique($p1)</pre>";
    }
    public function __call($name, $args) {
        echo "<pre>__call A::{$name}("
            . implode(', ', $args) . ")</pre>";
    }
    public function methode($p1) {
        echo "<pre>A::methode($p1)</pre>";
    }
}

Tous les exemples suivants se baseront sur une instance de cette classe, à laquelle nous accèderons via un objet nommé $obj :

$obj = new A();


Pour commencer, appelons une méthode existante, en non-statique :

$obj->methode('param1');

Comme attendu depuis à peu près toujours, nous obtenons l’affichage suivant :

A::methode(param1)


Continuons avec un appel de méthode inexistante, en non-statique :

$obj->test('param1', 'param2');

La méthode appelée n’existant pas dans la définition de la classe, et l’appel ne se faisant pas de manière statique, on passe par la méthode magique __call, et obtient l’affichage suivant :

__call A::test(param1, param2)


A présent, passons à un appel de méthode existante, en statique :

A::methodeStatique('param1');

En tout logique, nous obtenons l’affichage suivant :

A::methodeStatique(param1)


Et, pour finir, et en arriver à la nouveauté de PHP 5.3, appelons une méthode inexistante, en statique :

A::test('param1', 'param2');

Dans ce cas, puisque nous réalisons un appel statique, que la méthode appelée n’existe pas, et qu’une méthode __callStatic est définie, c’est celle-ci qui est appelée, et nous obtenons l’affichage suivant :

__callStatic A::test(param1, param2)

En PHP 5.2 et inférieurs, par contre, nous aurions pris une Fatal Error :

__callStatic-php-5.2-fatal-error.png


jeudi 23 octobre 2008

PHP 5.3 : Appels statiques dynamiques

Les exemples correspondant à ce point se trouvent dans le répertoire "dynamic-static-call".

Imaginons la classe suivante, qui contient une méthode nommée methode[1], et une méthode statique nommée methodeStatique[2] :

class A {
    public static function methodeStatique($p1) {
        echo "<pre>A::methodeStatique($p1)</pre>";
    }
    public function methode($p1) {
        echo "<pre>A::method($p1)</pre>";
    }
}


Il nous arrive fréquemment, déjà en PHP <= 5.2 d’utiliser le type de syntaxe suivante, où nous appelons une méthode sans connaitre son nom au moment de l’écriture du script :

$className = 'A';
$methodName = 'methode';
$obj = new $className();
$obj->$methodName('param1');

Au moment de l’exécution de cette portion de code, la variable $methodName vaut methode, et c’est donc la méthode de ce nom qui est appelée, provoquant l’affichage suivant :

A::methode(param1)


Mais, en PHP <= 5.2, il n’est pas possible d’utiliser le même type de syntaxe pour un méthode statique.
Typiquement, si on prend la portion de code suivante :

$staticMethodName = 'methodeStatique';
$className::$staticMethodName('param1');

Nous obtenons, avec PHP <= 5.2, une parse error :

dynamic-static-call-5.2.png

En PHP 5.3, par contre, cet appel dynamique de méthode statique fonctionne, et nous obtenons l’affichage attendu[3] :

A::methodeStatique(param1)


Notes

[1] Non, pas original…

[2] Je vous avais dit : pas original !

[3] Du moins, l’affichage auquel nous aurions déjà eu tendance à nous attendre ^^