Хабрахабр

[Из песочницы] Введение в PHP Reflection API

Привет, Хабр! Представляю вашему вниманию перевод статьи "Introduction to PHP Reflection API" автора Mustafa Magdi.

Как в PHP анализировать структуру данных

Вступление

Когда я начал программировать на PHP, то не знал о возможностях Reflection API. Главная причина в том, что мне не нужно было проектировать свои простые классы, модули или даже пакеты. Затем я обнаружил, что это играет главную роль во многих областях. В статье мы рассмотрим Reflection API по следующим пунктам:

  1. Что такое Reflection API
  2. Установка и конфигурирование
  3. Использование
  4. Заключение
  5. Рекомендации

1. Что такое Reflection API

reflection) означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения. В информатике отражение или рефлексия (холоним интроспекции, англ. — Wikipedia.

Что означает возможность остановить и взглянуть внутрь своего кода (reverse-engineering)? Давайте посмотрим на следующий фрагмент кода:

/** * Class Profile */
class Profile

}

Класс Profile — чёрный ящик. Используя Reflection API вы сможете прочитать, что там находится внутри:

// инициализация
$reflectionClass = new ReflectionClass('Profile'); // получить имя класса
var_dump($reflectionClass->getName());
=> output: string(7) "Profile" // получить документацию класса
var_dump($reflectionClass->getDocComment());
=> output:
string(24) "/** * Class Profile */"

Таким образом ReflectionClass выступает аналитиком для нашего класса Profile, и в этом состоит главная идея Reflection API.

PHP даёт вам ключ к любому запертому ящику, таким образом мы имеем ключи
для следующего:

ReflectionClass: сообщает информацию о классе.
ReflectionFunction: сообщает информацию о функции.
ReflectionParameter: извлекает информацию о параметрах функции или метода.
ReflectionClassConstant: сообщает информацию о константе класса.

Полный список вы можете изучить на php.net

2. Установка и конфигурирование

Для использования классов Reflection API нет необходимости что-либо устанавливать или настраивать, так как они входят в состав ядра PHP.

3. Примеры использования

Далее представлено несколько примеров того, как мы можем использовать Reflection API:

Пример 1:
Получить родительский класс для определённого класса:

// дочерний класс
class Child extends Profile
{
} $class = new ReflectionClass('Child'); // получаем список всех родителей
print_r($class->getParentClass()); // ['Profile']

Пример 2:
Получить документацию метода getUserName():

$method = new ReflectionMethod('Profile', 'getUserName');
var_dump($method->getDocComment());
=> output:
string(33) "/** * @return string */"

Пример 3:
Может использоваться как instanceOf и is_a() для валидации объектов:

$class = new ReflectionClass('Profile');
$obj = new Profile();
var_dump($class->isInstance($obj)); // bool(true)
// такой же как
var_dump(is_a($obj, 'Profile')); // bool(true)
// такой же как
var_dump($obj instanceof Profile); // bool(true)

Пример 4:
В некоторых ситуациях вы можете застрять с unit-тестированием и задаться вопросом: «Как я могу протестировать закрытую функцию?!»

Не беспокойтесь, вот хитрость:

// добавим закрытый метод getName()
private function getName(): string
{ return 'Foo';
}
$method = new ReflectionMethod('Profile', 'getUserName');
// проверим является ли метод закрытым и сделаем его доступным
if ($method->isPrivate()) { $method->setAccessible(true);
}
echo $method->invoke(new Profile()); // Foo

Предыдущие примеры довольно просты, но есть другие примеры, в которых вы можете увидеть, как Reflection API используется более обширно:

  • Генератор документации к API: пакет lavarel-apidoc-generator широко использует ReflectionClass и ReflrectionMethod для получения и последующей обработки информации о блоках документации классов и методов, и оформления этих блоков кода.
  • Dependency Injection Container: проверить всю тему вы можете здесь

4. Заключение

PHP предоставляет полноценный Reflection API, который помогает легко достичь различные области ООП-структур.

5. Ссылки

От переводчика:

Также можно посмотреть пример использования Reflection API в пакете Codeception в классе Stub.
Этот класс через рефлексию помогает мо́кать методы и свойства в unit-тестах.

Использовать рекомендуется в тестах или во время отладки, но если можно обойтись без него, то лучше так и сделать. Следует добавить, что Reflection API работает довольно медленно, по этому не стоит сильно увлекаться. это ещё и не безопасно. И категорически не рекомендуется использовать в рабочем коде проекта, т.к.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть