Интроспекция и отражение в 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
, а также выводит информацию, полученную с помощью перечисленных выше функций:
<?php class Introspection { public function description() { echo "Я супер класс для класса Child.\n"; } } 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()
– проверяет, определен или нет метод
<?php interface ICurrencyConverter { public function convert($currency, $amount); } 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)) { print "Определен класс GBPCurrencyConverter.\n"; $gbpConverter = new GBPCurrencyConverter(); $methods = get_class_methods($gbpConverter); echo "Доступны следующие методы:\n"; print_r($methods); $vars = get_class_vars("GBPCurrencyConverter"); echo "Доступны следующие свойства:\n"; print_r($vars); echo "Метод convert() есть в классе GBPCurrencyConverter: "; var_dump(method_exists($gbpConverter, "convert")); }
Код выдаст результат:
Интерфейс 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
:
<?php $child = new ReflectionClass("Child"); $parent = $child->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")) { echo "Метод convert() есть в классе GBPCurrencyConverter.\n"; }
Код выдаст следующий результат:
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.
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/fuhahFmWZ9Y/lessons.php


Поделиться статьей:
Акция: Закажи любой сайт до окончания акции и получи скидку + подбор семантического ядра + поисковую оптимизацию сайта Это позволит Вам получать еще больше трафика и соответственно клиентов из Интернета!
До конца акции осталось
0
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
0
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
0
9
8
7
6
5
4
3
2
1
0
|
Узнайте подробности акции у менеджеров компании по телефонам: 8-924-200-7194 г.Хабаровск 8-800-550-9899 Бесплатно по России (с 3 до 11 по Мск) |
Новые статьи и публикации
- 2018-04-19 » Алгоритмы Google: всё, что о них нужно знать
- 2018-04-17 » Выпуск №102: Формирование семантического ядра для рекламной кампании. Редизайн и SEO. Все о доменных именах. Промоакции в Google AdWords. Сайты для гос.учреждений.
- 2018-04-11 » Формирование семантического ядра для рекламной кампании
- 2018-04-03 » Редизайн при сохранении позиций: рекомендации по SEO
- 2018-03-27 » Картинки на сайте: как правильно работать с атрибутами Alt и Title
- 2018-03-22 » Выпуск №101: Правильный контент для интернет-магазина. Партизанский маркетинг и Продвижение в Youtube.
- 2018-03-21 » Доменные имена: всё, что о них нужно знать
- 2018-03-16 » Как ранжироваться в топе YouTube: практические советы
- 2018-03-14 » Расширение «Промоакция»: новое предложение Google AdWords
- 2018-03-12 » Конструкторы для сайтов: простые и эффективные решения
- 2018-03-04 » Сайты для муниципальных образований и бюджетных учреждений
- 2018-03-02 » Продвижение сайта: цена вопроса
- 2018-02-22 » Переход сайта на протокол https
- 2018-02-22 » SSL сертификаты - Защита передаваемых данных и доверие пользователей
- 2018-02-19 » Партизанский маркетинг: особенности и преимущества
- 2018-02-14 » Правильный контент для интернет-магазина − увеличение продаж в два раза
- 2018-02-14 » Выпуск №100: Особенности турбо-страниц и немного про то, как превратить текст в видео.
- 2018-02-08 » В Директе появятся видеодополнения по умолчанию
- 2018-02-06 » Особенности турбо-страниц
- 2018-01-31 » Научитесь составлять цепляющие заголовки по методике 4U за 5 минут!
- 2018-01-26 » Рекламные методы продвижения бизнеса
- 2018-01-17 » Выпуск №99: Способы продвижения бизнеса в интернете и мифы о создании сайтов
- 2018-01-17 » Способы продвижения бизнеса в интернете
- 2018-01-11 » Продвижение бизнеса в интернете
- 2017-12-30 » Выпуск №98: SEO-продвижение: итоги-2017, прогнозы-2018
- 2017-12-27 » Как развить бизнес в интернете?
- 2017-12-27 » Четыре рекламных объявления в спецразмещении
- 2017-12-20 » Развитие бизнеса в сети интернет
- 2017-12-18 » Принципы размещения контекстной рекламы в РСЯ и КМС
- 2017-12-15 » Бэкап сайта
Предоставляем полный комплекс услуг по созданию, обслуживанию и продвижению сайтов по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.