php Отражения (Reflection). Что это? Механизм создания.
Primary tabs
Отражения в php - это набор классов (Reflection***), позволяющий разработчику исследовать пользовательские и предопределённые классы.
Отражения хранят информацию о классах / методах / свойствах.
В частности статья является ответом на эти вопросы:
-
При создании отражения некоторого класса (ReflectionClass), отражения его параметров(ReflectionParameter) и методов (ReflectionMethod) формируются сразу же, автоматически или только при их явном вызове ( например ReflectionClass::getPMethods())?
Давайте рассмотрим механизм создания отражения класса. Что происходит в самом начале? Создаётся объект класса ReflectionClass:
$className = 'MyClass'; $obj = new ReflectionClass($className);
Как видно из документации класса ReflectionClass, объект $obj содержит только одно свойство - name, в котором хранится название класса, информацию о котором хранит отражение:
echo $obj->name; // MyClass
Думаю, можно сделать вывод, что объекты ReflectionMethod и ReflectionProperty (обратите внимание, что класс ReflectionParameter, упомянутый в вопросе, относится к параметрам функции, а не свойствам класса), хранящие данные о методах и свойствах класса создаются при вызове методов ReflectionClass::getProperties() и ReflectionClass::getMethods() соответственно, а не при инстанцировании ReflectionClass.
-
С чем связана, такая несколько на мой взгляд странная система наследования свойств и методов в отражениях, при которой метод getMethods() возвращает список всех методов класса, в том числе и закрытых, унаследованных от базового, а метод getProperties() закрытых свойств родительского объекта не наследует?
Действительно, логично, что приватные свойства не наследуются, поэтому не возвращаются методом getProperties(). А вот почему наследуются приватные методы - не понятно. (данный факт указан в "PHP в подлиннике" Д. Котеров, стр. 577, и проверен на практике :)))
Кстати, вызвать унаследованные приватные методы с помощью метода invoke() не получится :
Uncaught ReflectionException: Trying to invoke private method ...
Ниже код для исследования:
<?php error_reporting(E_ALL); ini_set('display_errors', true); class Base { public $basePublicProp; protected $baseProtectedProp; private $basePrivateProp; public function basePublicMethod() { echo "Привет, я ".__METHOD__."<br>"; } protected function baseProtectedMethod() { echo "Привет, я ".__METHOD__."<br>"; } private function basePrivateMethod() { echo "Привет, я ".__METHOD__."<br>"; } } class myClass extends Base { public $publicProp; protected $protectedProp; private $privateProp; public function publicMethod() { echo "Привет, я ".__METHOD__."<br>"; } protected function protectedMethod() { echo "Привет, я ".__METHOD__."<br>"; } private function privateMethod() { echo "Привет, я ".__METHOD__."<br>"; } } $className = 'MyClass'; echo "<p>Создаём объект отражения для класса MyClass... <br><br>"; $obj = new ReflectionClass($className); // 1) echo "Как видим, объект ReflectionClass имеет только одно " ."свойство, name: <br>"; echo "<pre>"; print_r($obj); echo "</pre>"; echo "<br> вот его значение: "; echo $obj->name; // 2) echo "</p><hr><p> Посмотрим, какие методы 'видит' " ."отражение... <br>"; $methods = $obj->getMethods(); echo "<br> Как видим, отражение предоставляет доступ даже " ."к приватным методам базового класса: <br>"; echo "<pre>"; print_r($methods); echo "</pre>"; echo "<br> Но если попытаться вызвать приватный унаследованный " ."метод, выбрасвается ReflectionException: <br>"; //$obj->getMethod('basePrivateMethod')->invoke(new MyClass()); // 3) echo "</p><hr><p> Посмотрим, какие свойства 'видит' " ."отражение... <br>"; $props = $obj->getProperties(); echo "<br> Как видим, отражение предоставляет доступ " ."ко всем свойствам класса MyClass и к публичным и " ."защищённым свойствам базового класса: <br>"; echo "<pre>"; print_r($props); echo "</pre>"; die('12313');
- Log in to post comments
- 3821 reads