PHP: Inner class
by Joris on juillet 27, 2010
Oui oui, c’est largement possible mais c’est pas ce qu’il y a de plus beau. Préférez utiliser le pattern Factory qui lui sera beaucoup plus propre et testable que des inner classes.
Mais parfois, créer une inner class peut rendre service justement pour tester une methode typée sans forcément passer par des frameworks de test.
Dans cet article, je vais vous montrer comment on peut facilement créer une inner class en utilisant la structure de langage eval(). Certes je ne suis pas fan de cette structure de langage et l’utilise jamais car elle est source de pas mal de fails mais elle est parfois utile si utilisée à bon escient.
Après tout, ça n’est qu’une question d’habitude…
Mise en oeuvre
Voici donc comment créer une inner class. Je travail avec PHP 5.3.2 mais cela n’a pas beaucoup d’importance, juste ayez une version >= 5.1 pour avoir le typage des méthodes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?php // inner_class.php // Class declaration class Foo { // Here is the type hinting method which accepts only Bar objects public function typeHintingMethod(Bar $instance) { return $instance->bar(); } // This method will create a Bar substitution object public function mockBar($string) { $string = addslashes($string); $source = <<< CLASS class Bar { public function bar() { return '$string'; } } CLASS; eval($source); return new Bar(); } } // Test $foo = new Foo; $bar = $foo->mockBar('I give a foobar!'); var_dump($foo->typeHintingMethod($bar)); ?> |
Résultat obtenu :
string 'I give a foobar!' (length=16)
Bon, ça n’a rien de fantastique mais c’est toujours bon à savoir… Donc oui, on peut faire des inner classes en PHP au moyen de ce petit hack
.

6 comments
Désolé mais je n’adhère pas du tout au concept, mais vraiment pas. Dans quel contexte as tu besoin d’inner-class en PHP? Je suis curieux
Si t’as besoin de Mock sinon, tu as l’excellent Mockery expliqué par l’un peu moins excellent Geoffrey : http://mirmodynamics.com/post/2010/06/07/De-qui-se-moque-t-on.
Cheers!
by Palleas on 27/07/2010 at 14:25. #
Je sais, c’est très
mockmoche cette technique… J’étais curieux de savoir si c’était possible et en effet, ça l’est…Merci pour le lien en tout cas
by Joris on 27/07/2010 at 14:35. #
sorry, je suis pas du tout dans l’truc…c’est quoi une inner class…?
by Delhia on 27/07/2010 at 15:48. #
Une inner class ne dois pas être accessible de l’extérieur, alors qu’avec eval (sauf erreur) elle l’est, non? Je ne vois pas l’intérêt par rapport à une déclaration en dur avant la class mère, surtout que je suis allergique à la fonction eval.
by Kermit on 27/07/2010 at 15:58. #
Ce genre de construction fut parfois utilisée dans les fonctions d’autoload. Lorsqu’une classe n’est pas chargée pour une raison quelconque (le fichier n’existe pas…), la fonction d’autoload pouvait créer une « fake » class à l’aide de eval() et ensuite lever une exception. Celle-ci était catchée par le code appelant sans que php aborte la requête pour cause de fatal error « class inexistante ».
Avec le possible chainage des autoloaders (spl_autoload_register) et des récents changements à propos des exceptions, cette technique hacky n’a plus lieu d’être dans le cadre de l’autoloading.
C’est vrai que le qualificatif « inner » est mal choisi. J’aurai plutôt dit « pseudo inline »
by metagoto on 27/07/2010 at 22:43. #
[...] PHP: Inner class [...]
by Two years of rand(0)-mies « rand(0) on 21/02/2011 at 16:26. #