Интроспекция и отражение в 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
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Все мы сидим в сточной канаве, но некоторые при этом смотрят на звезды Уайльд Оскар - (1854-1900) - английский писатель |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.