API отражения в PHP похож на пакет java.lang.reflect в Java. Он состоит из ряда встроенных классов, которые могут анализировать свойства, методы и классы. В некоторых отношениях она похожа на объектные функции, такие как get_class_vars(), но более гибкая и может предоставить больше информации. API отражения также работает с последними объектно-ориентированными функциями PHP, такими как управление доступом, интерфейсы и абстрактные классы. Старые функции класса не так просты в использовании с этими новыми функциями. Друзья, которые видели исходный код фреймворка, должны иметь определенное представление о механизме отражения PHP, таком как внедрение зависимостей, пул объектов, загрузка классов, некоторые шаблоны проектирования и т. д., все используют механизм отражения.
Частичные классы API отражения
Используя эти классы в Reflection API, можно получить доступ к расширенной информации об объектах, функциях и сценариях во время выполнения. Эту информацию можно использовать для анализа классов или построения фреймворков.
добрый | описывать |
Отражение | Предоставляет статическую функцию export() для получения сводной информации о классе. |
Класс отражения | Информация о классе и инструменты |
ОтражениеМетод | Информация о методе класса и инструменты |
ОтражениеПараметр | Информация о параметрах метода |
ОтражениеСвойство | информация об атрибутах класса |
ОтражениеФункция | Информация о функциях и инструменты |
ОтражениеРасширение | Информация о расширении PHP |
Исключение отражения | класс ошибки |
Получить информацию о классе
В нашей работе мы использовали некоторые функции для проверки атрибутов класса, например: get_class_methods, getProduct и т.д. Эти методы имеют большие ограничения для получения подробной информации о классе.
Мы можем получить информацию о классе через класс API отражения: экспорт статического метода, предоставляемый Reflection и ReflectionClass, экспорт может предоставить почти всю информацию о классе, включая статус контроля доступа к атрибутам и методам, параметры, необходимые для каждого метода, и каждый Позиция метода в документе скрипта. Вывод статического метода экспорта этих двух классов инструментов одинаков, но использование отличается.
Сначала создайте простой класс
<?php класс Студент { общественное имя $; защищенный возраст; частный секс; публичная функция __construct($name, $age, $sex) { $this->setName($name); $this->setAge($age); $this->setSex($sex); } общедоступная функция setName($name) { $это->имя = $имя; } защищенная функция setAge($age) { $this->age = $возраст; } приватная функция setSex($sex) { $this->sex = $sex; } }
Используйте ReflectionClass::export() для получения информации о классе
ReflectionClass::export('Студент');
Распечатать результат:
Вывод ReflectionClass::export()
Класс ReflectionClass предоставляет множество инструментов и методов, список которых в официальном руководстве выглядит следующим образом:
Класс отражения
Используйте Reflection::export() для получения информации о классе
$prodClass = новый ReflectionClass('Студент'); Отражение:: экспорт ($ prodClass);
распечатать результат
Вывод Reflection::export()
После создания объекта ReflectionClass вы можете использовать класс инструментов Reflection для вывода соответствующей информации класса Student. Reflection::export() может форматировать и экспортировать экземпляр любого класса, реализующего интерфейс Reflector.
проверить класс
Инструментальный класс ReflectionClass, который мы изучили ранее, знает, что этот класс предоставляет множество инструментальных методов для получения информации о классе. Например, мы можем получить тип класса Student, можно ли его инстанцировать
Функция инструмента
функция classData(ReflectionClass $class) { $детали = ''; $name = $class->getName(); // возвращает имя класса для проверки if ($class->isUserDefined()) { // проверяем, определен ли класс пользователем $details .= "$имя определяется пользователем" . PHP_EOL; } if ($class->isInternal()) { // проверяем, определен ли класс внутри расширения или ядра $details .= "$имя встроено" . PHP_EOL; } if ($class->isInterface()) { // проверяем, является ли класс интерфейсом $details .= "$name — интерфейс" . PHP_EOL; } if ($class->isAbstract()) { // проверяем, является ли класс абстрактным $details .= "$name является абстрактным классом" . PHP_EOL; } if ($class->isFinal()) { // проверяем, объявлен ли класс окончательным $details .= "$name — конечный класс" . PHP_EOL; } if ($class->isInstantiable()) { // проверяем, можно ли создать экземпляр класса $details .= "$name может быть создано" . PHP_EOL; } еще { $details .= "Невозможно создать экземпляр $name" . PHP_EOL; } вернуть $детали; } $prodClass = новый ReflectionClass('Студент'); распечатать данные класса ($ prodClass);
распечатать результат
Студент определяется пользователем Студент может быть создан
В дополнение к получению соответствующей информации о классе вы также можете получить соответствующую информацию об исходном коде, такую как имя файла пользовательского класса и начальную и конечную строки класса в файле, предоставленном объектом ReflectionClass.
функция getClassSource (ReflectionClass $ class) { $path = $class->getFileName(); // Получить абсолютный путь к файлу класса $lines = @file($path); // Получить массив всех строк в файле $from = $class->getStartLine(); // Указываем начальную строку класса $to = $class->getEndLine(); // Указываем конечную строку класса $len = $to - $from + 1; return implode(array_slice($lines, $from - 1, $len)); } $prodClass = новый ReflectionClass('Студент'); var_dump (getClassSource ($ prodClass)); распечатать результат строка 'класс Студент { общественное имя $; защищенный возраст; частный секс; публичная функция __construct($name, $age, $sex) { $this->setName($name); $this->setAge($age); $this->setSex($sex); } общедоступная функция setName($name) { $это->имя = $имя; } защищенная функция setAge($age) { $this->age = $возраст; } приватная функция setSex($sex) { $this->sex = $sex; } } ' (длина = 486)
Мы видим, что getClassSource принимает в качестве параметра объект ReflectionClass и возвращает исходный код соответствующего класса. Эта функция игнорирует обработку ошибок, на практике следует проверять аргументы и коды результатов!
Метод проверки
Подобно проверке классов, объекты ReflectionMethod можно использовать для проверки методов в классах.
Есть два способа получить объект ReflectionMethod:
Первый — получить массив объектов ReflectionMethod через ReflectionClass::getMethods() Преимущество этого метода в том, что ему не нужно заранее знать имя метода, и он вернет объекты ReflectionMethod всех методов в классе. .
Во-вторых, создать экземпляр объекта напрямую с помощью класса ReflectionMethod.Таким образом, можно получить только один объект метода класса, а имя метода должно быть известно заранее.
Служебные методы для объектов ReflectionMethod:
ОтражениеМетод
ReflectionClass::getMethods()
Мы можем получить массив объектов ReflectionMethod через ReflectionClass::getMethods().
$prodClass = новый ReflectionClass('Студент'); $methods = $prodClass->getMethods(); var_dump ($ методы);
распечатать результат
массив (размер=4) 0 => & объект (ReflectionMethod) [2] public 'name' => string '__construct' (длина = 11) public 'class' => string 'Студент' (длина = 7) 1 => & объект (метод отражения) [3] public 'name' => строка 'setName' (длина = 7) public 'class' => string 'Студент' (длина = 7) 2 => & объект (метод отражения) [4] public 'name' => string 'setAge' (длина = 6) public 'class' => string 'Студент' (длина = 7) 3 => & объект (метод отражения) [5] public 'name' => string 'setSex' (длина = 6) public 'class' => string 'Студент' (длина = 7)
Видно, что мы получили массив объектов Student's ReflectionMethod, каждый элемент — это объект, который имеет два публичных свойства, name — имя метода, а class — класс, которому он принадлежит. Мы можем вызывать методы объекта для получения информации о методе.
ОтражениеМетод
Напрямую используйте класс ReflectionMethod для получения информации о методах класса.
$method = новый ReflectionMethod('Студент', 'setName'); var_dump ($ метод);
распечатать результат
объект (ReflectionMethod) [1] public 'name' => строка 'setName' (длина = 7) public 'class' => string 'Студент' (длина = 7)
Уведомление
В PHP5 ReflectionMethod::retursReference() не вернет true, если проверяемый метод возвращает только объекты (даже если объекты присваиваются или передаются по ссылке). ReflectionMethod::returnsReference() возвращает значение true, только если проверяемый метод был явно объявлен для возврата ссылок (с символом & перед именем метода).
Проверить параметры метода
В PHP5 при объявлении метода класса можно ограничить тип объекта в параметре, поэтому возникает необходимость проверять параметры метода.
Подобно проверке методов, объект ReflectionParameter может использоваться для проверки методов в классе.Этот объект может сообщить вам имя параметра, может ли переменная быть передана по ссылке, а также сообщить вам о подсказках типа параметра и о том, является ли метод принимает нулевые значения в качестве параметров.
Есть также два способа получения объектов ReflectionParameter, которые очень похожи на получение объектов ReflectionMethod:
Первый — вернуть массив объектов ReflectionParameter с помощью метода ReflectionMethod::getParameters(), который может получить все объекты параметров метода.
Второй — напрямую использовать класс ReflectionParameter для создания экземпляров и получения объектов.Этот метод может получать объекты только с одним параметром.
Вспомогательные методы для объектов ReflectionParameter:
ОтражениеПараметр
ReflectionMethod::getParameters()
Как и метод get, этот метод возвращает массив, содержащий объекты ReflectionParameter для каждого параметра метода.
$method = новый ReflectionMethod('Студент', 'setName'); $params = $method->getParameters(); var_dump ($ параметры);
распечатать результат
массив (размер=1) 0 => & объект (параметр отражения) [2] public 'name' => строка 'name' (длина = 4)
ОтражениеПараметр
Давайте посмотрим на этот метод.Для лучшего понимания я модифицирую метод setName класса Student и добавляю два параметра a, b
... общедоступная функция setName($name, $a, $b) { $это->имя = $имя; } ...
Во-первых, давайте посмотрим на метод построения класса ReflectionParameter.
public ReflectionParameter::__construct (строка $функция, строка $параметр)
Вы можете видеть, что класс получает два параметра при создании экземпляра:
$функция: когда вам нужно получить функцию как общедоступную, вам нужно только передать имя функции. Когда функция является методом класса, необходимо передать массив в формате: массив('класс', 'функция').
$parameter: этот параметр можно передать двумя способами: первый — это имя параметра (без символа $), а второй — индекс параметра. Примечание. Будь то имя параметра или индекс, параметр должен существовать, иначе будет сообщено об ошибке.
Вот пример:
$params = new ReflectionParameter(array('Студент', 'setName'), 1); var_dump ($ параметры);
распечатать результат
объект (параметр отражения) [1] public 'name' => строка 'a' (длина = 1)
Давайте определим другую функцию для тестирования
функция foo($a, $b, $c) { } $reflect = новый параметр отражения ('foo', 'c'); var_dump ($ отражение);
распечатать результат
объект (параметр отражения) [2] public 'name' => строка 'c' (длина = 1)
эпилог
API отражения PHP очень мощный, он может получить подробную информацию о классе. Мы можем написать класс через API отражения для динамического вызова объекта Module, который может свободно загружать сторонние плагины и интегрировать их в существующие системы. Нет необходимости жестко встраивать сторонний код в исходный код. Хотя использование отражения в реальной разработке относительно невелико, понимание API отражения очень полезно для понимания структуры кода и разработки бизнес-моделей в работе. Этот пост в блоге писался с перерывами в течение длительного времени (в основном из-за лени!), если есть какие-то ошибки и недочеты, прошу меня поправить и подсказать! !