<rmcreative>

RSS

Вызвать 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

  1. №9838
    Sam
    Sam 10.06.2015, 23:45:26

    Оказывается, вопрос давно изучен Marco Pivetta. Ещё и с замерами скорости.

  2. №9839
    klay
    klay 11.06.2015, 11:50:40

    php.net/manual/ru/closure.bindto.php

    $this->caller->bindTo($object);

    Второй $object лишний

  3. №9840
    Sam
    Sam 11.06.2015, 12:14:43

    Нет, не лишний. scope как раз и надо менять.

  4. №9841
    klay
    klay 11.06.2015, 12:22:17

    Ох, да, не внимательно прочёл.

  5. №9842
    Максим
    Максим 11.06.2015, 17:50:23

    Понятия не имею когда это может пригодиться :) Разве что джуниорам показать как не надо писать код.

  6. №9843
    Sam
    Sam 11.06.2015, 21:37:07

    В тестах.

  7. №9844
    ElisDN
    ElisDN 12.06.2015, 3:14:13

    Функция с $this закидывается в объект и работает изнутри. Да, классно! Но до методов родительского класса добраться не получится. Хотя если бы она могла саму себя прокинуть в parent... но $this в объекте только один.

  8. №9849
    romanitalian
    romanitalian 24.06.2015, 11:46:43

    А почему у меня выкидывает Fatal?

    Fatal error: Call to undefined method PrivacyViolator::caller() in /in/ntf08 on line 15 3v4l.org/ntf08

  9. №9851
    klay
    klay 28.06.2015, 14:39:23

    @romanitalian Ну, всегда можно попробовать рефлексию ;)

    3v4l.org/qOcSR

  10. №9860
    romanitalian
    romanitalian 02.07.2015, 15:13:21

    @klay Спасибо.

    Позволил собрать несколько вариантов у себя в блоге: romanitalian.github.io.local/sections/php/use_private/index.html

  11. №9862
    klay
    klay 02.07.2015, 17:23:39

    @romanitalian 404

  12. №9879
    romanitalian
    romanitalian 06.07.2015, 16:49:21

    @klay надо переезжать с jino.ru (периодически отваливается хостинг)

  13. №9881
    romanitalian
    romanitalian 06.07.2015, 21:35:25

    @klay не туда написал - про jino :(

  14. №9939
    Shkarbatov
    Shkarbatov 22.08.2015, 16:21:53

    А действительно в чем дело? 3v4l.org/S5j87

    Fatal error: Call to undefined method PrivacyViolator::_caller()

  15. №9940
    Shkarbatov
    Shkarbatov 22.08.2015, 19:15:13

    Вот так вот получилось: 3v4l.org/50bnu

    Fatal error: Call to undefined method PrivacyViolator::_caller()

    В примере из заметки

    $this->caller->bindTo($object, $object);
    return $this->caller($method, $args);

    Между собой получаются не связанные, то есть надо либо связать переменной, либо вызвать в цепочке:

    return $this->caller->bindTo($object, $object)->__invoke($method, $args);

    Александр, а Вас работает пример из заметки?

  16. №9942
    Sam
    Sam 23.08.2015, 20:39:38

    Shkarbatov, да, вызов метода был неверно сделан. Поправил. В реальном коде оно не было завёрнуто в класс...

    Спасибо!

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.