- Интроспекция и отражение в PHP
- Функции интроспекции PHP
- Reflection API
- 5 последних уроков рубрики «PHP»
- Фильтрация данных с помощью zend-filter
- Контекстное экранирование с помощью zend-escaper
- Подключение Zend модулей к Expressive
- Совет: отправка информации в Google Analytics через API
- Подборка PHP песочниц
- Введение
- User Contributed Notes
Интроспекция и отражение в PHP
В данном уроке описывается использование функции интроспекции в PHP и Reflection API для получения информации о классах, интерфейсах, свойствах и методах. Такие действия нужны для составления полной картины о коде в момент выполнения и создания сложных приложений.
Интроспекция является общим свойством для любого языка программирования, который позволяет программисту манипулировать объектами классов. Она очень полезна в тех случаях, когда во время разработки неизвестно, какой класс или метод нужно использовать.
Интроспекция в PHP позволяет проверить классы, интерфейсы, методы и свойства. В PHP имеется большое количество функций, которые можно использовать для решения таких задач. Мы представим краткий обзор некоторых классов, методов и функций PHP с примерами их использования. Также в уроке будет представлен API, который имеет функционал очень близкий к интроспекции — Reflection API.
Функции интроспекции PHP
В первом примере демонстрируются полезные функции интроспекции PHP. Их можно использовать для получения основной информации о классе — имя, имя родительского класса и так далее.
- class_exists() – проверяет определение класса
- get_class() – возвращает имя класса объекта
- get_parent_class() – возвращает имя родительского класса объекта
- is_subclass_of() – проверяет, имеется ли в родителях объекта заданный класс
Пример кода PHP, который содержит определение для классов Introspection и Child , а также выводит информацию, полученную с помощью перечисленных выше функций:
> class Child extends Introspection < public function description() < echo "Я класс " . get_class($this) , ".\n"; echo "Я потомок класса " . get_parent_class($this) , ".\n"; >> if (class_exists("Introspection")) < $introspection = new Introspection(); echo "Имя класса : " . get_class($introspection) . "\n"; $introspection->description(); > if (class_exists("Child")) < $child = new Child(); $child->description(); if (is_subclass_of($child, "Introspection")) < echo "Да, " . get_class($child) . " является подклассом Introspection.\n"; >else < echo "Нет, " . get_class($child) . " не является подклассом Introspection.\n"; >>
Выше приведенный код выведет:
Имя класса: Introspection Я супер класс для класса Child. Я класс Child. Я потомок класса Introspection. Да, Child является подклассом Introspection.
Вы можете определить, будет или нет определяться класс с помощью метода class_exists() , который получает в качестве аргумента строку с именем проверяемого класса и опциональное логическое значение, которое определяет автоматическую загрузку.
Методы get_class() и get_parent_class() возвращают имя класса объекта или его родителя соответственно. Оба метода принимают в качестве аргумента объекты.
Метод is_subclass_of() получает объект и строку, в которой содержится имя родительского класса, а возвращает логическое значение результата проверки принадлежности объекта родительскому классу.
Во втором примере определяется интерфейс ICurrencyConverter и класс GBPCurrencyConverter и выводится информация с помощью ниже перечисленных функций.
- get_declared_classes() – возвращает список всех объявленных классов
- get_class_methods() – возвращает имена методов класса
- get_class_vars() – возвращает свойства класса
- interface_exists() – проверяет, определен или нет интерфейс
- method_exists() – проверяет, определен или нет метод
class GBPCurrencyConverter implements ICurrencyConverter < public $name = "GBPCurrencyConverter"; public $rates = array("USD" =>0.622846, «AUD» => 0.643478); protected $var1; private $var2; function __construct() <> function convert($currency, $amount) < return $rates[$currency] * $amount; >> if (interface_exists(«ICurrencyConverter»)) < echo "Интерфейс ICurrencyConverter определен.\n"; >$classes = get_declared_classes(); echo «Доступны следующие классы:\n»; print_r($classes); if (in_array(«GBPCurrencyConverter», $classes))
Интерфейс ICurrencyConverter определен. Доступны следующие классы: Array ( [0] => stdClass [1] => Exception [2] => ErrorException [3] => Closure [4] => DateTime [5] => DateTimeZone [6] => DateInterval [7] => DatePeriod . [154] => GBPCurrencyConverter ) Определен класс GBPCurrencyConverter. Доступны следующие методы: Array ( [0] => __construct [1] => convert ) Доступны следующие свойства: Array ( [name] => GBPCurrencyConverter [rates] => Array ( [USD] => 0.622846 [AUD] => 0.643478 ) ) Метод convert() есть в классе GBPCurrencyConverter: bool(true)
Метод interface_exists() очень похож на метод class_exists() , который обсуждался ранее. Он проверяет, определен или нет заданный интерфейс. В качестве параметров он получает имя интерфейса и логическую переменную для автозазгрузки (опционально).
Метод get_declared_classes() возвращает массив имен всех определенных классов. В зависимости от загруженных библиотек результат может быть разным.
Метод get_class_method() получает экземпляр объекта или строку с именем нужного класса в качестве аргумента, а возвращает массив имен методов, которые определены в классе.
Обратите внимание на различие определенных в классе ICurrencyConverter свойств и списком, возвращаемым методом get_class_vars() (вывелись только $name и $rates ). Частные и защищенные свойства пропускаются.
Reflection API
PHP поддерживает отражение с помощью Reflection API. Reflection API предлагает существенно больше классов и методов для решения задач отражения. Класс ReflectionClass является основным классом API и используется для получения информации о классах, интерфейсах, методах и всех компонентов классов. Отражение очень легко применять в своем коде.
Ниже приводится пример использования отражения с определениями интерфейса ICurrencyConverter и классов Child и GBPCurrencyConverter :
getParentClass(); echo $child->getName() . » является подклассом » . $parent->getName() . «.\n»; $reflection = new ReflectionClass(«GBPCurrencyConverter»); $interfaceNames = $reflection->getInterfaceNames(); if (in_array(«ICurrencyConverter», $interfaceNames)) < echo "GBPCurrencyConverter реализует ICurrencyConverter.\n"; >$methods = $reflection->getMethods(); echo «Доступны следующие мтоды:\n»; print_r($methods); if ($reflection->hasMethod(«convert»))
Код выдаст следующий результат:
Child является подклассом Introspection. GBPCurrencyConverter реализует ICurrencyConverter. Доступны следующие методы: Array ( [0] => ReflectionMethod Object ( [name] => __construct [class] => GBPCurrencyConverter ) [1] => ReflectionMethod Object ( [name] => convert [class] => GBPCurrencyConverter ) ) Метод convert() есть в классе GBPCurrencyConverter.
Метод getInterfaceNames() возвращает массив с именами интерфейсов, которые реализует класс. Метод getParentClass() может вернуть объект ReflectionClass , представляющий родительский класс, или значение false , если родителя нет. Для получения имени объекта ReflectionClass используется метод getName().
Метод getMethods() возвращает массив имен методов и может принимать опциональный аргумент — битовую маску из значений ReflectionMethod::IS_STATIC , IS_PUBLIC , IS_PROTECTED , IS_PRIVATE , IS_ABSTRACT , и IS_FINAL для фильтрации списка.
Reflection API предоставляет разработчику отличную реализацию отражения, с помощью которой можно создавать очень сложные приложения, такие как ApiGen.
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: phpmaster.com/introspection-and-reflection-in-php/
Перевел: Сергей Фастунов
Урок создан: 31 Мая 2012
Просмотров: 20710
Правила перепечатки
5 последних уроков рубрики «PHP»
Фильтрация данных с помощью zend-filter
Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.
Контекстное экранирование с помощью zend-escaper
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
Подключение Zend модулей к Expressive
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
Совет: отправка информации в Google Analytics через API
Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.
Введение
PHP включает в себя полноценный Reflection API, который предоставляет возможность проводить интроспекцию классов, интерфейсов, функций, методов и модулей. Кроме того, Reflection API позволяет получать doc-блоки комментариев функций, классов и методов.
Обратите внимание, что определённая часть внутреннего API не содержит кода, который необходим для работы модуля Reflection. Например, внутренний PHP-класс может не иметь reflection-данных для своих свойств. Однако это известные ошибки и впоследствии такие классы будут исправлены.
User Contributed Notes
- Reflection
- Введение
- Установка и настройка
- Предопределённые константы
- Примеры
- Расширение
- Reflection
- ReflectionClass
- ReflectionClassConstant
- ReflectionEnum
- ReflectionEnumUnitCase
- ReflectionEnumBackedCase
- ReflectionZendExtension
- ReflectionExtension
- ReflectionFunction
- ReflectionFunctionAbstract
- ReflectionMethod
- ReflectionNamedType
- ReflectionObject
- ReflectionParameter
- ReflectionProperty
- ReflectionType
- ReflectionUnionType
- ReflectionGenerator
- ReflectionFiber
- ReflectionIntersectionType
- ReflectionReference
- ReflectionAttribute
- Reflector
- ReflectionException