Как стать автором
Обновить

Комментарии 17

Свойство было приватным. И никаких getter'ов для него в реализации класса не было. Изменять класс я конечно же не стал, ибо после composer update эта правка тут же слетит.

собственно валидировать то, что не предоставляется публичным api библиотеки чревато тем же.

Вот если бы кто статью написал с паттернами мышления которые приводят к костылям и сомнительным решениям. Например.


И мне потребовалось получить список всех правил, передаваемых валидатору.

Представьте что вы идете по дороге и тут развилка. Вы выбрали направление, например пошли на леко. Через 10 минут дороги вы обнаруживаете что дороги больше нет, есть болото. Ваш выбор, вернуться назад и попробовать другой маршрут или "и так сойдет?".


Я к тому что проблема у вас именно в этом месте, что вам зачем-то для валидатора понадобилось пробросить все правила валидации. И вместо того что бы решить эту проблему, настоящую проблему, вы ее решили игнорировать и в итоге потратили время решая другую.


Оно конечно хорошо что вы разобрались с областями видимости пропертей, но как-то не очень хорошо так делать.

Передо мной стояла задача написать рекурсивную валидацию.
Есть некоторый массив со своей структурой. И у него есть элемент, в котором вся эта структура дублируется.
В идеале, я задаю правила для элементов и говорю, как называется «рекурсивный» элемент. Поэтому мне требовалось пробросить все правила внутрь, чтобы я мог применить их ко вложенным массивам.
НЛО прилетело и опубликовало эту надпись здесь
Давно не использовал и не слежу за Laravel-ом, но судя по исходнику, свойство не приватное, а защищенное (protected), поэтому упомянутая проблема элементарно решается созданием дочернего класса Validator и описанием нужных методов — классика ООП.
Да, можно было сделать и так.
Но в я посчитал, что такое вмешательство не несет вреда, так как я знаю что лежит внутри и использую эти данные только для чтения.
Соглашусь с orlov0562, там же Factory, она для того и создана чтобы ее можно было расширить если необходимо. Это был бы самый быстрый и красивый способ.

Другой вопрос, который меня мучает: причем тут reflection?
Другой вопрос, который меня мучает: причем тут reflection?

получение приватного свойста "как в reflection"

Автор, у меня вопрос: как Вы так читали отличную документацию на Reflection API, что в итоге даже не поняли, что это? Вы использовали стандартный метод класса Closure, применили позднее статическое связывание. Но никак не Reflection.
Ну и да, соглашусь с предыдущими комментаторами — если Вам нужно зачем-либо получить доступ к приватным свойствам или методам чужого класса, значит Вы что-то делаете не так. Ищите другое решение.

Автор, у меня вопрос: как Вы так читали отличную документацию на Reflection API, что в итоге даже не поняли, что это? Вы использовали стандартный метод класса Closure, применили позднее статическое связывание. Но никак не Reflection.

ну он и пишет — "reflection на замыканиях", т.е. отдает себе в этом отчет)

Сомневаюсь. Reflection тут вообще совсем не при чем:)

он "как в reflection" получил доступ к приватному свойству.

Автор, вы, безусловно, молодец в том, что исследуете язык и ищете нестандартные способы решения поставленной задачи.
PHP-сообщество сильно разделено в погоне за признанием, поэтому предпочитает тыкать носом во все неакадемичные решения.

Да пусть делает что хочет, лишь бы код этот не пришлось поддерживать кому-то еще. Такие вот "неакадемические" решения в итоге ведут к тому что обновить ту же ларавельку человеку уже будет не так просто. А люди которые "тыкают носом" просто хотят что бы человек задумался о средне и долгосрочных перспективах развития проекта и как его решения на это все влияют.


А то всякие решатели проблем нарешают проблем, а как только некофмортно работать с кодом становятся идут "решать проблемы" куда-то еще.

Решение действительно выигрывает по объему кода и его концентрации (только в нужном месте).

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

Совет интересный, спасибо, запомню.
поступить вразрез с идеологией, нежели потратить в 3 раза больше времени (если время критичный ресурс).

тут есть очень опасный момент. С точки зрения бизнеса важна не только стоимость но и возможность эту стоимость предсказать. А используя подобные подходы мы создаем условия для рисков при изменения кода. Хотите обновить либку? А вот уже нельзя просто взять и обновить — надо протестить. И как правило "помнить" обо всех таких нюансах не выходит. А это значит что то что вы сэкономили час выльется потом в 3-4 часа отладки.


Так что "идеологического" ничего нет. Есть здравый смысл. Подобное оправдано только в ситуациях когда вы на коленке написали прототип и планируете его в ближайшее же время. И намного чаще как раз таки ограничения по времени не позволят нам делать PoC реализации и потом выкидывать ее. А рефакторинг, чистка кода и т.д. — весьма редкая привычка у разработчиков.

Свойство было приватным. И никаких getter'ов для него в реализации класса не было.

И тут я подумал, что решение должно быть проще.

Если я правильно Вас понял, то чтобы получить приватное свойство ведь достаточно пары строк —
$reflection = new \ReflectionClass(вашкласс);
$property = $reflection->getProperty('имя приватного свойства');
$property->->setAccessible(true);

Может я не понял задачи, но в unit-тестах я проверяю содержание приватных свойств таким методом.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории