Facebook LinkedIn SourceForge Twitter RSS LastFM
logologo

Comment utiliser un objet PHP sans le déclarer ?

Geoffray Warnants|19/10/2008|5 commentaires

Pour illustrer ce que je voulais pouvoir faire en PHP, je me suis inspir du langage Java o on rencontre parfois ce genre d'appel :
// en Java
new Application(login, pwd).start();
La particularit est qu'on peut utiliser un objet sans avoir forcment besoin de le dclarer dans une variable. Ceci est souvent utilis dans le cas o cet objet n'est ncessaire qu' un unique endroit du programme. Malheureusement, PHP n'autorise pas cette syntaxe, ce qui nous contraint de scinder l'opration et de s'encombrer d'une variable intermdiaire qui nous est inutile.
// en PHP
$app = new Application($login, $pwd);
$app->start();
unset($app);

L'avantage de la premire solution, outre le fait apprci qu'elle offre une criture plus concise, rside dans la mise en vidence de l'inutilit de l'instance en dehors de cet unique appel, ce qui peut s'avrer d'une grande utilit pour une comprhension rapide du code par un tierce dveloppeur.

Pour pouvoir reproduire cette criture en PHP, j'ai cr la petite classe suivante (qui aurait trs bien pu n'tre qu'une simple fonction) :
class ClassLoader {
    public static function load($className, $arg=null) {
        $c = new ReflectionClass($className);
        return ($c->hasMethod('__construct') || $c->hasMethod($className)) ?
            $c->newInstanceArgs(array_splice(func_get_args(), 1)) :
            $c->newInstance();
    }
}
On peut alors crire :
ClassLoader::load('Application', $login, $pwd)->start();
Le principe devient intressant, mais la clart du code en a pris un sacr coup ! Pour simplifier, j'ai pens une nouveaut trs attendue de PHP 5.3 : la nouvelle mthode magique __callStatic, dont le comportement est identique la mthode __call bien connue, mais adapte aux mthodes statiques.
//  partir de PHP 5.3
class ClassLoader {
    public static function __callStatic($method, $args) {
        $c = new ReflectionClass($method);
        return ($c->hasMethod('__construct') || $c->hasMethod($method)) ?
            $c->newInstanceArgs($args) :
            $c->newInstance();
    }
}    
L'criture gagne ainsi nettement en simplicit :
ClassLoader::Application($login, $pwd)->start();
Il ne reste plus qu' finaliser la classe pour la rendre compatible PHP 5 et 6, ce qui ne pose pas de problme. Il sera juste laiss au dveloppeur le soin de raliser les appels adquats selon la version de PHP utilise, avec la seule petite restriction qu'en PHP 6, le chargement d'une ventuelle classe nomme "Load" devra invitablement se faire via l'criture PHP 5.
class ClassLoader {
    public static function load($className, $arg=null) {
        $c = new ReflectionClass($className);
        return ($c->hasMethod('__construct') || $c->hasMethod($className)) ?
            $c->newInstanceArgs(array_splice(func_get_args(), 1)) :
            $c->newInstance();
    }
    
    public static function __callStatic($className, $args) {
        return call_user_func_array(
            array(self, 'load'), array_merge(array($className),$args)
        );
    }
}

<<< Retour

Vos commentaires

4 commentaires posts

cialis price
19/05/2020 19:15Post par cialis price
I am really loving the theme/design of your blog.
Do you ever run into any browser compatibility issues?

A number of my blog audience have complained about my website not working correctly in Explorer but looks great in Safari.
Do you have any solutions to help fix this problem?
Matthieu
16/06/2009 18:56Post par Matthieu
Je propose tout simplement de créer une methode statique dans ta classe qui retourne une instance de la classe. ex :

<?php
// La class
class MaClass
{
private function __construct()
{

}

public static function init()
{
return new MaClass();
}

public function start()
{

}
}

// Utilisation
MaClass::init()->start();
?>

Non ?
Geoffray
05/02/2009 22:04Post par Geoffray
Tout à fait d'accord pour dire que la Réflexion ne soit pas une solution des plus performantes et que le bénéfice apporté par tout ce mécanisme ne soit pas des plus utiles. La démarche était plutôt destinée à explorer les possibilités pour éviter l'affectation de variable... sans grand succès.
John
03/02/2009 15:44Post par John
Et pourquoi ne pas déclarer ta méthode start() comme static dans ta classe ?

Si son comportement est tel qu'elle peut être utilisée hors de l'instanciation de la classe à  laquelle elle appartient, elle n'a pas de raison d'être déclarée autrement.

La solution qui consiste à utiliser la Reflexion est tellement lourde d'un point de vue compréhension du code et utilisation mémoire.

Appeller et utiliser tout une gestion de classe pour éviter une affection de variable...

Ragir cet article

*


(Ne sera pas publie, servira uniquement afficher votre gravatar)


(Lien en dur et dofollow)

zend framework