在不使用ReflectionFunction-> invoke()的对象上下文中时使用$ this

时间:2014-10-26 00:56:50

标签: php reflection this fatal-error

class someClass {
    private $success = "success\n";
    function getReflection() {
        return new ReflectionFunction(function() {
            print $this->success;
        });
     }
}
$reflection = (new someClass)->getReflection();
$reflection->invoke();

当我运行时,我得到了一个

Fatal error: Using $this when not in object context in Command line code on line 5

这里发生了什么?为什么$this没有在那里定义......?

由于我在方法中的Closure中,通常应该定义$this。是的,我使用的是比PHP 5.4更新的版本。

我该如何解决?

1 个答案:

答案 0 :(得分:5)

ReflectionFunction正在未绑定的Closures上运行。这就是为什么在ReflectionFunction::invoke()调用之后,Closure中没有定义的$this变量,因此会出现您的致命错误。

但是可以解决这个问题。

ReflectionFunction为您提供了三种必要的方法来使用$this绑定来调用它:

  • ReflectionFunctionAbstract::getClosure()
  • ReflectionFunctionAbstract::getClosureThis()
  • ReflectionFunctionAbstract::getClosureScopeClass()

ReflectionFunctionAbstract::getClosure()仍未绑定,但我们可以通过Closure::bind()绑定它。

所有Closure::bind()需要的是Closure,被绑定的对象和类范围。

然后解决方案是:

call_user_func(\Closure::bind(
    $reflection->getClosure(),
    $reflection->getClosureThis(),
    $reflection->getClosureScopeClass()->name));

我最初想发布此问题只是一个问题,但我在发布之前就已经找到了解决方案,所以只需添加答案。上下文就是这个问题:https://github.com/rdlowrey/Auryn/pull/72