Pull to refresh

Comments 15

Спасибо за статью!
Функционал Reflection, конечно, интересная вещь. Жалко что места в реальных проектах ему места практически нету(кроме довольно специфических задач, в т.ч. описанных в статье)

В коде приложения, скорее всего, таким заниматься не надо (ну, разве что колхозишь какой-то свой велосипед).
В коде же фреймворков и библиотек может встречаться довольно часто.


Допустим, PHP-DI активно использует рефлексию для реализации автосвязывания (когда DI контейнер по сигнатуре конструктора сам определяет, что в него надо внедрять).


Или Doctrine — на основе описания модели (обычный PHP класс со специальными phpdoc-аннотациями) генерирует sql-скрипты.


Тот же phpunit — разработчик пишет тестовый класс в соответствии с определенными соглашениями (имена методов, phpdoc-аннотации), а тестовый фреймворк через рефлексию определяет, что и как в этом тесте надо запускать.

UFO just landed and posted this here
Ну без Reflection для таких случаев иногда делают методы protected вместо private, но это в любом случае плохой тон, по хорошему тестировать нужно интерфейс.
Приватные методы можно и без рефлексии вызывать, как и получать инфу из приватных полей.

Никто же пока не отменял контексты:
$result = (function () {
    return $this->somePrivateMethod();
})->call($context);
Помимо рефлексии можно ещё через Closure с замыканием:

$closureBind = Closure::bind(function &(SomeClass $someClass) {
            return $someClass->privateProperty;
        }, null, $someClass);
$privateProperty = &$closureBind($someClass);


$privateProperty в данном случае будет содержать ссылку на приватное свойство, которое можем смотреть и изменять. Работает, к слову, быстрее рефлекции.

Принципиально не тестирую приватные методы. Тестирую публичный интерфейс.


Если что-то приватное очень хочется протестировать, скорее всего, это означает, что эта приватная логика — сама по себе отдельная ответственность. И выносится в отдельный класс (в соответствии с SRP).

UFO just landed and posted this here
Но ведь по вашей же ссылке «218 code results in symfony/symfony»? Либы для работы с аннотацииями, умный DI, тестирование и подобные штуки вполне могут быть написаны через Reflection, а к приложениям они просто подключаются в виде готовых библиотек (phpunit, codeception, symfony annotations etc.)
Например в Laravel:
Запрос: site.ru/post/1
В маршрутах написано правило 'post/{post}'
Action в контроллере тебе уже не нужно делать запрос, и определять класс Request, оба параметры будут распознаны Reflection API и переданы:
public function show(Post $post, Request $request)
{
    // $post === Post::where('id', 1)->first();
}
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Sign up to leave a comment.

Articles