|
Table des matières
RéflexionIntroductionPHP 5 introduit API de réflexion complète qui permet de faire du “reverse-engineering” sur les classes, les interfaces, les fonctions et les méthodes tout comme les extensions. L’API de réflexion permet également d’obtenir les commentaires de la documentation pour les fonctions, les classes et les méthodes. L’API de réflexion est une extension orientée objet du Moteur Zend, constituée des classes suivantes :
<?php class Reflection { } interface Reflector { } class ReflectionException extends Exception { } class ReflectionFunction implements Reflector { } class ReflectionParameter implements Reflector { } class ReflectionMethod extends ReflectionFunction { } class ReflectionClass implements Reflector { } class ReflectionObject extends ReflectionClass { } class ReflectionProperty implements Reflector { } class ReflectionExtension implements Reflector { } ?>
Si nous exécutons le code de l’exemple ci-dessous :
<?php Reflection::export(new ReflectionClass('Exception')); ?>
public object construct(mixed object) public string toString() public static string export(mixed object, bool return) } ?> " | **ReflectionMethod**La classe ReflectionMethod vous permet de faire du “reverse-engineering” sur les méthodes des classes.
<?php class ReflectionMethod extends ReflectionFunction { public __construct(mixed class, string name) public string __toString() public static string export(mixed class, string name, bool return) public mixed invoke(stdclass object, mixed args) public mixed invokeArgs(stdclass object, array args) public bool isFinal() public bool isAbstract() public bool isPublic() public bool isPrivate() public bool isProtected() public bool isStatic() public bool isConstructor() public bool isDestructor() public int getModifiers() public ReflectionClass getDeclaringClass() // Inherited from ReflectionFunction final private __clone() public string getName() public bool isInternal() public bool isUserDefined() public string getFileName() public int getStartLine() public int getEndLine() public string getDocComment() public array getStaticVariables() public bool returnsReference() public ReflectionParameter[] getParameters() public int getNumberOfParameters() public int getNumberOfRequiredParameters() } ?> Pour connaître le fonctionnement d’une méthode, vous devez d’abord créer une instance de la classe ReflectionMethod. Vous pourrez ainsi appeler n’importe quelle méthode de cette instance.
<?php class Compteur { private static $c = 0; /** * Incrémentation d'un compteur * * @final * @static * @access public * @return int */ final public static function increment() { return self::$c; } } // Création d'une instance de la classe Reflection_Method $method = new ReflectionMethod('Compteur', 'increment'); // Affichage d'informations basiques printf( "===> La méthode %s%s%s%s%s%s%s '%s' (qui est %s)\n". " déclaré dans %s\n". " lignes %d à %d\n". " a les modificateurs %d[%s]\n", $method->isInternal() ? 'internal' : 'user-defined', $method->isAbstract() ? ' abstract' : '', $method->isFinal() ? ' final' : '', $method->isPublic() ? ' public' : '', $method->isPrivate() ? ' private' : '', $method->isProtected() ? ' protected' : '', $method->isStatic() ? ' static' : '', $method->getName(), $method->isConstructor() ? 'the constructor' : 'a regular method', $method->getFileName(), $method->getStartLine(), $method->getEndline(), $method->getModifiers(), implode(' ', Reflection::getModifierNames($method->getModifiers())) ); // Affichage du commentaire de la documentation printf("---> Documentation:\n %s\n", var_export($method->getDocComment(), 1)); // Affichage des variables statiques si elles existent if ($statics= $method->getStaticVariables()) { printf("---> Variales statiques : %s\n", var_export($statics, 1)); } // Invocation de la méthode printf("---> Résultat de l'invocation dans : "); var_dump($method->invoke(NULL)); ?>
**ReflectionProperty**La classe ReflectionProperty vous permet de faire du “reverse-engineering” sur les propriétés des classes.
<?php class ReflectionProperty implements Reflector { final private __clone() public __construct(mixed class, string name) public string __toString() public static string export(mixed class, string name, bool return) public string getName() public bool isPublic() public bool isPrivate() public bool isProtected() public bool isStatic() public bool isDefault() public int getModifiers() public mixed getValue(stdclass object) public void setValue(stdclass object, mixed value) public ReflectionClass getDeclaringClass() public string getDocComment() } ?>
Pour connaître le fonctionnement d’une propriété, vous devez d’abord créer une instance de la classe ReflectionProperty. Vous pourrez ainsi appeler n’importe quelle méthode de cette instance.
<?php class Chaine { public $length = 5; } // Création d'une instance de la classe ReflectionProperty $prop = new ReflectionProperty('Chaine', 'length'); // Affichage d'informations basiques printf( "===> Les propriétés %s%s%s%s '%s' (qui a %s)\n". " a les modificateurs %s\n", $prop->isPublic() ? ' public' : '', $prop->isPrivate() ? ' private' : '', $prop->isProtected() ? ' protected' : '', $prop->isStatic() ? ' static' : '', $prop->getName(), $prop->isDefault() ? 'déclaré au moment de la compilation' : 'créé au moment de l\'exécution', var_export(Reflection::getModifierNames($prop->getModifiers()), 1) ); // Création d'une instance de Chaine $obj= new Chaine(); // Récupération de la valeur courante printf("---> La veleur est : "); var_dump($prop->getValue($obj)); // Modification de la valeur $prop->setValue($obj, 10); printf("---> Définition de la valeur à 10, la nouvelle valeur est : "); var_dump($prop->getValue($obj)); // Affichage de l'objet var_dump($obj); ?>
**ReflectionExtension**La classe ReflectionExtension vous permet de faire du “reverse-engineering” sur les extensions. Vous pouvez connaître toutes les extensions chargées à l’exécution en utilisation la fonction get_loaded_extensions().
<?php class ReflectionExtension implements Reflector { final private __clone() public __construct(string name) public string __toString() public static string export(string name, bool return) public string getName() public string getVersion() public ReflectionFunction[] getFunctions() public array getConstants() public array getINIEntries() public ReflectionClass[] getClasses() public array getClassNames() } ?> Pour connaître le fonctionnement d’une extension, vous devez d’abord créer une instance de la classe ReflectionExtension. Vous pourrez ainsi appeler n’importe quelle méthode sur cette instance.
<?php // Création d'une instance de la classe ReflectionProperty $ext = new ReflectionExtension('standard'); // Affichage d'informations basiques printf( "Nom : %s\n". "Version : %s\n". "Fonctions : [%d] %s\n". "Entrées INI : [%d] %s\n" . "Classes : [%d] %s\n", $ext->getName(), $ext->getVersion() ? $ext->getVersion() : 'NO_VERSION', sizeof($ext->getFunctions()), var_export($ext->getFunctions(), 1), sizeof($ext->getConstants()), var_export($ext->getConstants(), 1), sizeof($ext->getINIEntries()), var_export($ext->getINIEntries(), 1), sizeof($ext->getClassNames()), var_export($ext->getClassNames(), 1) ); ?> Extension des classes de réflexionDans le cas où vous voudriez créer des versions spéciales des classes embarquées (par exemple pour créer du HTML colorisé lorsqu’il est exporté, pour avoir un accès facile aux variables des membres au lieu des méthodes ou pour avoir des méthodes utiles), vous devez étendre la classe.
<?php /** * Ma classe Reflection_Method * */ class My_Reflection_Method extends ReflectionMethod { public $visibility= ''; public function __construct($o, $m) { parent::__construct($o, $m); $this->visibility= Reflection::getModifierNames($this->getModifiers()); } } /** * Démo classe #1 * */ class T { protected function x() {} } /** * Démo classe #2 * */ class U extends T { function x() {} } // Affichage des informations var_dump(new My_Reflection_Method('U', 'x')); ?>
Travail collaboratifContribuez, en ajjoutant des elements a cette page de manuel : Merci de votre aide |