On Mon, Oct 19, 2015 at 10:18 AM, Alexander Lisachenko <
lisachenko...@gmail.com> wrote:

> Hello, internals!
>
> Just noticed this thread and want to clarify some things with getClosure()
> method. If i understood correctly, ReflectionFunctionAbstract::getClosure()
> should return non-rebindable closure ONLY for internal functions, but for
> userland functions binding should be still possible, right?
>
> E.g.
>
> class Foo {private $a=1;}
>
> function test() {
>     var_dump($this);
> }
> $closure = (new \ReflectionFunction('test'))->getClosure();
> $object = new Foo;
> $closure = $closure->bindTo($object, get_class($object));
> $closure();
>
> (unfortunately, it's broken: https://3v4l.org/YeDBj#v700rc5)
>
> I know, that binding functions to objects is tricky, but this can be
> useful for utility classes. But if you insist on this, ok, it's very rare
> case, just one single example.
>
> What is more important for me is ability to work with methods as closures.
> So my main concern is about restrictions of ReflectionMethod->getClosure()
> and rebinding.
>
> See this example:
>
> class Foo {private $a=1;}
>
> class Bar {
>     function test() {
>         var_dump($this);
>     }
> }
> $closure = (new \ReflectionMethod('Bar','test'))->getClosure(new Bar);
> $object = new Foo;
> $closure = $closure->bindTo($object, get_class($object));
> $closure();
>
> This kind of rebinding is heavily used by Go! Aspect-Oriented Framework
> and now it will be broken (see https://3v4l.org/cZtbI#v700rc5). I think
> there will be some more frameworks/libraries that use reflection and
> closure rebinding via reflections. So this introduced patch for RC5 is
> definitely a BC break for existing code.
> Could you please provide a workaround or alternative ways to keep it
> working? Maybe, restrict rebinding only for internal objects/methods will
> be enough? Or only for ReflectionFunctionAbstract->getClosure(), but not
> for ReflectionMethod->getClosure()
>

This change is primarily targeting userland methods, so your use-case is
exactly the one this is supposed to prevent. Note that you can still use
->bindTo($object). The only thing you cannot do is ->bindTo($object,
get_class($object)).

Nikita

Reply via email to