Travailler avec une classe de bibliothèque PHP, et j'aimerais envelopper toutes ses fonctions publiques dans une sous-classe ... quelque chose du long des lignes de: en bouillant, je «D Préférez-vous ne pas avoir à remplacer chaque méthode Superclass avec le même code d'emballage, s'il y a un moyen [un peu élégant / propre] de tout faire au même endroit. P> est-ce possible? Je soupçonne que je suis en métaprogramming Terre ici et je ne sais même pas si PHP offre une telle bête, mais je me suis dit que je vous demanderais ... p> p>
4 Réponses :
Vous recherchez peut-être le motif de décorateur:
class A { function do1(){ } } class DecoratorForA extends A { private A original; public DecoratorForA( A original ) { this.original = original; } function do1(){ //<-- override keyword in php? stuffBefore(); original->do1(); stuffAfter(); } }
Oh, maintenant je l'ai lu correctement, devinez que vous ne cherchez pas cela.
Il essaie de trouver un moyen simple d'appliquer généralement le motif de décorateur sans i> écrire une magnitude de code de la chaudron. Vous venez de donner ses besoins un nom, pas une solution ...
Correct, je cherchais une application de métaprogrammation du motif de décorateur ... Merci pour votre contribution, cependant!
Si les noms de sous-classe de la sous-classe peuvent différer légèrement des noms de méthode d'origine de la base de base, vous pouvez écrire une enveloppe générique avec Si vous pouvez faire les méthodes de base de base Si vous ne EM> BESOIN EM> pour étendre la classe, l'approche de Maeger est parfaitement parfaite. Veuillez noter que __Call () et Call_user_func_array () imposent une certaine surcharge. P> __ appel () code>. Si les noms de méthode doivent correspondre, je ne vois pas comment vous pourriez atteindre votre objectif sans écraser manuellement chaque méthode. Peut-être que vous pourriez utiliser le Funcall Pecl pour le faire - mais vous devrez être capable de charger ce pecl en premier lieu. P>
protégée code>, la
__ appel () code> approche de sous-classe fonctionnera. P>
C'est une chose importante à souligner - merci. Je n'ai pas (je pense que je n'ai pas besoin d'étendre la classe, alors je prévois que l'approche proxy fonctionnera. (Dépendra de la manière dont le routage de CodeDigniter est effectué sous la hotte)
Vous pouvez le faire facilement avec le __Call code>
Méthode magique et a La classe "Proxy" générique qui n'hérite pas directement de la classe de base.
Voici une mise en œuvre complète (proche) d'une classe de proxyage qui enveloppe l'objet que vous le transmettez. Il sera invoqué certains "avant" et "après" CODE autour de chaque appel de méthode. P>
class MyProxy { function __construct($object) { $this->object = $object; } function __call($method, $args) { // Run before code here // Invoke original method on our proxied object call_user_func_array(array($this->object, $method), $args); // Run after code here } } $base = new BaseClass(); $proxy = new MyProxy($base); $proxy->doSomething(); // invoke $base->doSomething();
Une façon de contourner le problème de type consiste à examiner la manière dont la version PHP de Mockito, Phockito, génère des classes simulées. github.com/hafriedlander/phockito/blob/master/phockito.php# L 170
Qu'en est-il si une méthode a un paramètre de référence? "Fonction publique (et sortie $) {}"
Si je vous comprends bien, vous souhaitez étendre une classe, mais ne permettez aucune des méthodes du parent à être appelées. Au lieu de cela, vous souhaitez appeler toutes les méthodes dans une méthode de la nouvelle classe.
Alors pourquoi voulez-vous même hériter en premier lieu? Cela ressemble beaucoup à ce que vous devriez simplement créer un adaptateur / décorateur pour votre base de base. P>
Pour clarifier - il n'y a que certaines méthodes de
basoclass code> que vous souhaitez remplacer dans
sous-classe code>, pas tous?
@ S992, pas exactement - je cherchais un moyen d'appliquer le même code d'emballage à chaque méthode de la classe de base. On dirait que la méthode de la magie __Call de PHP fera le travail avec une enveloppe proxy, merci @meagar!
Gotcha, la question n'était pas exactement claire. Si la réponse de MEAGAR vous a aidé, vous devriez l'accepter. :)
Ce que vous voulez s'appelle AOP. Il existe des réalisations de AOP dans PHP: Extension PHP-AOP, Allez! Bibliothèque AOP, TYPO3 Flow AOP.