Вызвать private метод класса в PHP без Reflection
10 июня 2015
В комментариях к заметке о вызове private метода через Reflection Roman верно подметил, что можно использовать вместо Reflection анонимные функции. Вот только его вариант работает с PHP7.
Оказывается, можно проделать такое чуть иначе и в PHP 5.4:
class PrivacyViolator { private $caller; function __construct() { $this->caller = function ($method, $args) { return call_user_func_array([$this, $method], $args); }; } function callPrivateMethod($object, $method, $args) { return $this->caller->bindTo($object, $object)->__invoke($method, $args); } } $myObject = new MyClass(); $privacyViolator = new PrivacyViolator(); $privacyViolator->callPrivateMethod($myObject, 'hello', ['world']);
Комментарии RSS по email OK
Оказывается, вопрос давно изучен Marco Pivetta. Ещё и с замерами скорости.
php.net/manual/ru/closure.bindto.php
Второй $object лишний
Нет, не лишний. scope как раз и надо менять.
Ох, да, не внимательно прочёл.
Понятия не имею когда это может пригодиться :) Разве что джуниорам показать как не надо писать код.
В тестах.
Функция с $this закидывается в объект и работает изнутри. Да, классно! Но до методов родительского класса добраться не получится. Хотя если бы она могла саму себя прокинуть в parent... но $this в объекте только один.
А почему у меня выкидывает Fatal?
Fatal error: Call to undefined method PrivacyViolator::caller() in /in/ntf08 on line 15 3v4l.org/ntf08
@romanitalian Ну, всегда можно попробовать рефлексию ;)
3v4l.org/qOcSR
@klay Спасибо.
Позволил собрать несколько вариантов у себя в блоге: romanitalian.github.io.local/sections/php/use_private/index.html
@romanitalian 404
@klay надо переезжать с jino.ru (периодически отваливается хостинг)
@klay не туда написал - про jino :(
А действительно в чем дело? 3v4l.org/S5j87
Вот так вот получилось: 3v4l.org/50bnu
В примере из заметки
Между собой получаются не связанные, то есть надо либо связать переменной, либо вызвать в цепочке:
Александр, а Вас работает пример из заметки?
Shkarbatov, да, вызов метода был неверно сделан. Поправил. В реальном коде оно не было завёрнуто в класс...
Спасибо!