cvs: phpdoc-ru /language/oop5 reflection.xml

From: Date: Tue, 15 Apr 2008 20:56:54 +0000
Subject: cvs: phpdoc-ru /language/oop5 reflection.xml
Groups: php.doc.ru 
Request: Send a blank email to doc-ru+get-924@lists.php.net to get a copy of this message
santiago Tue Apr 15 20:56:54 2008 UTC Added files: /phpdoc-ru/language/oop5 reflection.xml Log: add new translation by Alexey Romanenko

http://cvs.php.net/viewvc.cgi/phpdoc-ru/language/oop5/reflection.xml?view=markup&rev=1.1 Index: phpdoc-ru/language/oop5/reflection.xml +++ phpdoc-ru/language/oop5/reflection.xml <?xml version="1.0" encoding="utf-8" ?> <!-- $Revision: 1.1 $ --> <sect1 xml:id="language.oop5.reflection" xmlns="http://docbook.org/ns/docbook"> <title>Рефлексия</title> <sect2 xml:id="language.oop5.reflection.toc"> <title>Содержание</title> <simplelist> <member><link linkend="language.oop5.reflection.introduction">Введение</link></member> <member><link linkend="language.oop5.reflection.reflector">Интерфейс Reflector</link></member> <member><link linkend="language.oop5.reflection.reflectionexception">Класс ReflectionException</link></member> <member><link linkend="language.oop5.reflection.reflectionfunction">Класс ReflectionFunction</link></member> <member><link linkend="language.oop5.reflection.reflectionparameter">Класс ReflectionParameter</link></member> <member><link linkend="language.oop5.reflection.reflectionclass">Класс ReflectionClass</link></member> <member><link linkend="language.oop5.reflection.reflectionobject">Класс ReflectionObject</link></member> <member><link linkend="language.oop5.reflection.reflectionmethod">Класс ReflectionMethod</link></member> <member><link linkend="language.oop5.reflection.reflectionproperty">Класс ReflectionProperty</link></member> <member><link linkend="language.oop5.reflection.reflectionextension">Класс ReflectionExtension</link></member> <member><link linkend="language.oop5.reflection.extending">Расширение классов рефлексии</link></member> </simplelist> </sect2> <sect2 xml:id="language.oop5.reflection.introduction"> <title>Введение</title> <para> PHP 5 имеет полный набор API рефлексии, который предоставляет возможность перепроектировать классы, интерфейсы, функции и методы, в том числе и расширения. В дополнение к этому, API рефлексии предлагает пути восстановления комментариев для функций, классов и методов. </para> <para> API рефлексии - это объектно-ориентированное расширение для Zend Engine, состоящее из следующих классов: </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class Reflection { } interface Reflector { } class ReflectionException extends Exception { } class ReflectionFunction extends ReflectionFunctionAbstract implements Reflector { } class ReflectionParameter implements Reflector { } class ReflectionMethod extends ReflectionFunctionAbstract implements Reflector { } class ReflectionClass implements Reflector { } class ReflectionObject extends ReflectionClass { } class ReflectionProperty implements Reflector { } class ReflectionExtension implements Reflector { } ?> ]]> </programlisting> </informalexample> <note> <simpara> Более подробно эти классы рассматриваются в следующих частях. </simpara> </note> <para> Если мы выполним код из примера ниже: <example> <title>Основное использование API рефлексии</title> <programlisting role='php'> <![CDATA[ <?php Reflection::export(new ReflectionClass('Exception')); ?> ]]> </programlisting> &example.outputs; <screen> <![CDATA[ Class [ <internal> class Exception ] { - Constants [0] { } - Static properties [0] { } - Static methods [0] { } - Properties [6] { Property [ <default> protected $message ] Property [ <default> private $string ] Property [ <default> protected $code ] Property [ <default> protected $file ] Property [ <default> protected $line ] Property [ <default> private $trace ] } - Methods [9] { Method [ <internal> final private method __clone ] { } Method [ <internal, ctor> public method __construct ] { - Parameters [2] { Parameter #0 [ <optional> $message ] Parameter #1 [ <optional> $code ] } } Method [ <internal> final public method getMessage ] { } Method [ <internal> final public method getCode ] { } Method [ <internal> final public method getFile ] { } Method [ <internal> final public method getLine ] { } Method [ <internal> final public method getTrace ] { } Method [ <internal> final public method getTraceAsString ] { } Method [ <internal> public method __toString ] { } } } ]]> </screen> </example> </para> </sect2> <sect2 xml:id="language.oop5.reflection.reflector"> <title><classname>Reflector</classname></title> <para> <classname>Reflector</classname> это интерфейс, который имплементирует все экспортируемые классы Reflection. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php interface Reflector { public string __toString() public static string export() } ?> ]]> </programlisting> </informalexample> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionexception"> <title><classname>ReflectionException</classname></title> <para> <classname>ReflectionException</classname> расширяет стандартный класс <link linkend="language.exceptions">Exception</link> и его выбрасывает Reflection API. Никаких специальных методов или свойств здесь не представлено. </para> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionfunction"> <title><classname>ReflectionFunction</classname></title> <para> Класс <classname>ReflectionFunction</classname> позволяет вам перепроектировать функции. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class ReflectionFunction extends ReflectionFunctionAbstract implements Reflector { final private __clone() public void __construct(string name) public string __toString() public static string export(string name, bool return) public string getName() public bool isInternal() public bool isDisabled() public bool isUserDefined() public string getFileName() public int getStartLine() public int getEndLine() public string getDocComment() public array getStaticVariables() public mixed invoke([mixed args [, ...]]) public mixed invokeArgs(array args) public bool returnsReference() public ReflectionParameter[] getParameters() public int getNumberOfParameters() public int getNumberOfRequiredParameters() } ?> ]]> </programlisting> </informalexample> <para> Родительский класс <classname>ReflectionFunctionAbstract</classname> имеет такие же методы, за исключением <function>invoke</function>, <function>invokeArgs</function>, <function>export</function> и <function>isDisabled</function>. </para> <note> <simpara> <function>getNumberOfParameters</function> и <function>getNumberOfRequiredParameters</function> были добавлены в PHP 5.0.3, а <function>invokeArgs</function> был добавлен в PHP 5.1.0. </simpara> </note> <para> Анализируя функцию, сначала вы должны создать экземпляр класса <classname>ReflectionFunction</classname>. Затем, в этом объекте вы сможете вызывать любой из методов этого класса, упомянутых выше. </para> <example> <title>Использование класса <classname>ReflectionFunction</classname></title> <programlisting role='php'> <![CDATA[ <?php /** * Простой счетчик * * @return int */ function counter() { static $c = 0; return $c++; } // Создание экземпляра класса ReflectionFunction $func = new ReflectionFunction('counter'); // Вывод основной информации printf( "===> Функция %s '%s'\n". " объявлена в %s\n". " строки с %d по %d\n", $func->isInternal() ? 'internal' : 'user-defined', $func->getName(), $func->getFileName(), $func->getStartLine(), $func->getEndline() ); // Печать комментария документации printf("---> Документация:\n %s\n", var_export($func->getDocComment(), 1)); // Печать статической переменной, если она существует if ($statics = $func->getStaticVariables()) { printf("---> Статическая переменная: %s\n", var_export($statics, 1)); } // Вызов функции printf("---> Результат вызова в: "); var_dump($func->invoke()); // вы можете предпочесть для использования метод export() echo "\nReflectionFunction::export() результат:\n"; echo ReflectionFunction::export('counter'); ?> ]]> </programlisting> </example> <note> <simpara> Метод <function>invoke</function> принимает переменное число аргументов, которые передаются в функцию, также, как в <function>call_user_func</function>. </simpara> </note> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionparameter"> <title><classname>ReflectionParameter</classname></title> <para> Класс <classname>ReflectionParameter</classname> возвращает информацию о параметрах функции или метода. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class ReflectionParameter implements Reflector { final private __clone() public void __construct(string function, string parameter) public string __toString() public static string export(mixed function, mixed parameter, bool return) public string getName() public bool isPassedByReference() public ReflectionClass getDeclaringClass() public ReflectionClass getClass() public bool isArray() public bool allowsNull() public bool isPassedByReference() public bool isOptional() public bool isDefaultValueAvailable() public mixed getDefaultValue() } ?> ]]> </programlisting> </informalexample> <note> <para> <function>getDefaultValue</function>, <function>isDefaultValueAvailable</function> и <function>isOptional</function> были добавлены в PHP 5.0.3, а <function>isArray</function> был добавлен в PHP 5.1.0. <function>getDeclaringFunction</function> и <function>getPosition</function> были добавлены в PHP 5.2.3. </para> </note> <para> Анализируя параметры функции, сначала вы должны создать экземпляр класса <classname>ReflectionFunction</classname> или <classname>ReflectionMethod</classname> и затем использовать их метод <function>getParameters</function> для получения массива параметров. </para> <example> <title>Использование класса <classname>ReflectionParameter</classname></title> <programlisting role='php'> <![CDATA[ <?php function foo($a, $b, $c) { } function bar(Exception $a, &$b, $c) { } function baz(ReflectionFunction $a, $b = 1, $c = null) { } function abc() { } // Создание экземпляра класса ReflectionFunction // с параметром, заданным из командной строки. $reflect = new ReflectionFunction($argv[1]); echo $reflect; foreach ($reflect->getParameters() as $i => $param) { printf( "-- Параметр #%d: %s {\n". " Класс: %s\n". " Допускать NULL: %s\n". " Передан по ссылке: %s\n". " Обязательный?: %s\n". "}\n", $i, $param->getName(), var_export($param->getClass(), 1), var_export($param->allowsNull(), 1), var_export($param->isPassedByReference(), 1), $param->isOptional() ? 'да' : 'нет' ); } ?> ]]> </programlisting> </example> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionclass"> <title><classname>ReflectionClass</classname></title> <para> Класс <classname>ReflectionClass</classname> позволяет вам перепроектировать классы и интерфейсы. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class ReflectionClass implements Reflector { final private __clone() public void __construct(string name) public string __toString() public static string export(mixed class, bool return) public string getName() public bool isInternal() public bool isUserDefined() public bool isInstantiable() public bool hasConstant(string name) public bool hasMethod(string name) public bool hasProperty(string name) public string getFileName() public int getStartLine() public int getEndLine() public string getDocComment() public ReflectionMethod getConstructor() public ReflectionMethod getMethod(string name) public ReflectionMethod[] getMethods() public ReflectionProperty getProperty(string name) public ReflectionProperty[] getProperties() public array getConstants() public mixed getConstant(string name) public ReflectionClass[] getInterfaces() public bool isInterface() public bool isAbstract() public bool isFinal() public int getModifiers() public bool isInstance(stdclass object) public stdclass newInstance(mixed args) public stdclass newInstanceArgs(array args) public ReflectionClass getParentClass() public bool isSubclassOf(ReflectionClass class) public array getStaticProperties() public mixed getStaticPropertyValue(string name [, mixed default]) public void setStaticPropertyValue(string name, mixed value) public array getDefaultProperties() public bool isIterateable() public bool implementsInterface(string name) public ReflectionExtension getExtension() public string getExtensionName() } ?> ]]> </programlisting> </informalexample> <note> <simpara> <function>hasConstant</function>, <function>hasMethod</function>, <function>hasProperty</function>, <function>getStaticPropertyValue</function> и <function>setStaticPropertyValue</function> были добавлены в PHP 5.1.0, а <function>newInstanceArgs</function> был добавлен в PHP 5.1.3. </simpara> </note> <para> Анализируя класс, сначала вы должны создать экземпляр класса <classname>ReflectionClass</classname>. Затем, вы сможете в этом объекте вызвать любой из методов, описанных выше. </para> <example> <title>Использование класса <classname>ReflectionClass</classname></title> <programlisting role='php'> <![CDATA[ <?php interface Serializable { // ... } class Object { // ... } /** * Класс счетчик */ class Counter extends Object implements Serializable { const START = 0; private static $c = Counter::START; /** * Вызвать счетчик * * @access public * @return int */ public function count() { return self::$c++; } } // Создание экземпляра класса ReflectionClass $class = new ReflectionClass('Counter'); // Вывод основной информации printf( "===> %s%s%s %s '%s' [extends %s]\n" . " объявлен в %s\n" . " строки с %d по %d\n" . " имеет модификаторы %d [%s]\n", $class->isInternal() ? 'internal' : 'user-defined', $class->isAbstract() ? ' abstract' : '', $class->isFinal() ? ' final' : '', $class->isInterface() ? 'interface' : 'class', $class->getName(), var_export($class->getParentClass(), 1), $class->getFileName(), $class->getStartLine(), $class->getEndline(), $class->getModifiers(), implode(' ', Reflection::getModifierNames($class->getModifiers())) ); // Печать комментария из документации printf("---> Документация:\n %s\n", var_export($class->getDocComment(), 1)); // Печать тех интерфейсов, которые имплементируют этот класс printf("---> Имплементация:\n %s\n", var_export($class->getInterfaces(), 1)); // Печать констант класса printf("---> Константы: %s\n", var_export($class->getConstants(), 1)); // Печать свойств класса printf("---> Свойства: %s\n", var_export($class->getProperties(), 1)); // Печать методов класса printf("---> Методы: %s\n", var_export($class->getMethods(), 1)); // Если есть возможность создать экземпляр класса, то создаем его if ($class->isInstantiable()) { $counter = $class->newInstance(); echo '---> $counter инстанцирован? '; echo $class->isInstance($counter) ? 'да' : 'нет'; echo "\n---> new Object() инстанцирован? "; echo $class->isInstance(new Object()) ? 'да' : 'нет'; } ?> ]]> </programlisting> </example> <note> <simpara> Метод <function>newInstance</function> принимает переменное число аргументов, которые передаются в функцию, также, как в <function>call_user_func</function>. </simpara> </note> <note> <simpara> <literal>$class = new ReflectionClass('Foo'); $class-&gt;isInstance($arg)</literal> эквивалентно <literal>$arg instanceof Foo</literal> или <literal>is_a($arg, 'Foo')</literal>. </simpara> </note> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionobject"> <title><classname>ReflectionObject</classname></title> <para> Класс <classname>ReflectionObject</classname> позволяет перепроектировать объекты. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class ReflectionObject extends ReflectionClass { final private __clone() public void __construct(mixed object) public string __toString() public static string export(mixed object, bool return) } ?> ]]> </programlisting> </informalexample> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionmethod"> <title><classname>ReflectionMethod</classname></title> <para> Класс <classname>ReflectionMethod</classname> позволяет перепроектировать методы. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class ReflectionMethod extends ReflectionFunctionAbstract implements Reflector { public void __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() // Унаследовано из ReflectionFunctionAbstract 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() } ?> ]]> </programlisting> </informalexample> <para> Анализируя метод, сначала вы должны создать экземпляр класса <classname>ReflectionMethod</classname>. Затем, вы сможете в этом объекте вызвать любой из методов, описанных выше. </para> <example> <title>Использование класса <classname>ReflectionMethod</classname></title> <programlisting role='php'> <![CDATA[ <?php class Counter { private static $c = 0; /** * Увеличение счетчика * * @final * @static * @access public * @return int */ final public static function increment() { return ++self::$c; } } // Создание экземпляра класса ReflectionMethod $method = new ReflectionMethod('Counter', 'increment'); // Вывод основной информации printf( "===> %s%s%s%s%s%s%s метод '%s' (which is %s)\n" . " объявлен в %s\n" . " строки с %d по %d\n" . " имеет модификаторы %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())) ); // Печать комментария из документации printf("---> Документация:\n %s\n", var_export($method->getDocComment(), 1)); // Печать статической переменной, если она существует if ($statics= $method->getStaticVariables()) { printf("---> Статическая переменная: %s\n", var_export($statics, 1)); } // Вызов метода printf("---> Результат вызова в: "); var_dump($method->invoke(NULL)); ?> ]]> </programlisting> </example> <note> <simpara> Попытка вызова закрытого, защищенного или абстрактного метода приведет к выбросу исключения из метода <function>invoke</function>. </simpara> </note> <note> <simpara> Для статических методов, описанных выше, вы должны передать NULL в качестве первого аргумента в <function>invoke</function>. Для нестатических методов нужно передать экземпляр класса. </simpara> </note> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionproperty"> <title><classname>ReflectionProperty</classname></title> <para> Класс <classname>ReflectionProperty</classname> позволяет перепроектировать свойства класса. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class ReflectionProperty implements Reflector { final private __clone() public void __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() } ?> ]]> </programlisting> </informalexample> <note> <simpara> <function>getDocComment</function> был добавлен в PHP 5.1.0. </simpara> </note> <para> Анализируя свойство, сначала вы должны создать экземпляр класса <classname>ReflectionProperty</classname>. Затем, вы сможете вызвать любой из методов, описанных выше, в этом объекте. </para> <example> <title>Использование класса <classname>ReflectionProperty</classname></title> <programlisting role='php'> <![CDATA[ <?php class String { public $length = 5; } // Создание экземпляра класса ReflectionProperty $prop = new ReflectionProperty('String', 'length'); // Print out basic information printf( "===> %s%s%s%s свойство '%s' (которое было %s)\n" . " имеет модификаторы %s\n", $prop->isPublic() ? ' public' : '', $prop->isPrivate() ? ' private' : '', $prop->isProtected() ? ' protected' : '', $prop->isStatic() ? ' static' : '', $prop->getName(), $prop->isDefault() ? 'объявлено во время компиляции' : 'создано во время выполнения', var_export(Reflection::getModifierNames($prop->getModifiers()), 1) ); // Создание экземпляра String $obj= new String(); // Получение текущего значения printf("---> Значение: "); var_dump($prop->getValue($obj)); // Изменение значения $prop->setValue($obj, 10); printf("---> Установка значения 10, новое значение равно: "); var_dump($prop->getValue($obj)); // Дамп объекта var_dump($obj); ?> ]]> </programlisting> </example> <note> <simpara> Попытка вызова закрытого или защищенного свойства класса приведет к выбросу исключения. </simpara> </note> </sect2> <sect2 xml:id="language.oop5.reflection.reflectionextension"> <title><classname>ReflectionExtension</classname></title> <para> Класс <classname>ReflectionExtension</classname> позволяет вам перепроектировать расширения. Вы можете восстановить все загруженные расширения во время выполнения используя <function>get_loaded_extensions</function>. </para> <informalexample> <programlisting role="php"> <![CDATA[ <?php class ReflectionExtension implements Reflector { final private __clone() public void __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() public string info() } ?> ]]> </programlisting> </informalexample> <para> Анализируя расширение, сначала вы должны создать экземпляр класса <classname>ReflectionExtension</classname>. Затем, вы сможете вызвать любой из методов, описанных выше, в этом объекте. </para> <example> <title>Использование класса <classname>ReflectionExtension</classname></title> <programlisting role='php'> <![CDATA[ <?php // Создание экземпляра класса ReflectionProperty $ext = new ReflectionExtension('standard'); // Вывод основной информации printf( "Имя : %s\n" . "Версия : %s\n" . "Функции : [%d] %s\n" . "Константы : [%d] %s\n" . "Директивы INI : [%d] %s\n" . "Классы : [%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) ); ?> ]]> </programlisting> </example> </sect2> <sect2 xml:id="language.oop5.reflection.extending"> <title>Расширение классов рефлексии</title> <para> В случае, когда вы захотите создать специализированные версии встроенных классов (например, для создания подсветки HTML при экспорте удобно иметь легкодоступные переменные взамен методов, либо утилиты методов), вы можете пойти дальше и расширить их. </para> <example> <title>Расширение встроенных классов</title> <programlisting role='php'> <![CDATA[ <?php /** * Свой класс Reflection_Method */ class My_Reflection_Method extends ReflectionMethod { public $visibility = array(); public function __construct($o, $m) { parent::__construct($o, $m); $this->visibility = Reflection::getModifierNames($this->getModifiers()); } } /** * Демо-класс #1 * */ class T { protected function x() {} } /** * Демо-класс #2 * */ class U extends T { function x() {} } // Вывод информации var_dump(new My_Reflection_Method('U', 'x')); ?> ]]> </programlisting> </example> <note> <simpara> Внимание! Если вы переписываете конструктор, то не забудьте вызывать конструктор родителя _перед_ любым кодом, который вы затем вставите. В случае невыполнения этого условия результат будет следующим: <literal> Fatal error: Internal error: Failed to retrieve the reflection object </literal> </simpara> </note> </sect2> </sect1> <!-- Keep this comment at the end of the file Local variables: mode: sgml sgml-omittag:t sgml-shorttag:t sgml-minimize-attributes:nil sgml-always-quote-attributes:t sgml-indent-step:1 sgml-indent-data:t indent-tabs-mode:nil sgml-parent-document:nil sgml-default-dtd-file:"../../manual.ced" sgml-exposed-tags:nil sgml-local-catalogs:nil sgml-local-ecat-files:nil End: vim600: syn=xml fen fdm=syntax fdl=2 si vim: et tw=78 syn=sgml vi: ts=1 sw=1 -->
« previous php.doc.ru (#924) next »