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