闭包不能作为类方法工作?

dqh*_*cks 1 php closures

我是否遗漏了什么或闭包根本不能作为类方法工作?以这个为例:

$foo = new stdClass();
$foo->bar = function() {
   echo '@@@';
};
$foo->bar();
Run Code Online (Sandbox Code Playgroud)

似乎给了我一个错误“致命错误:在 X 行的 /blah/blah.php 中调用未定义的方法 stdClass::bar()”

这不应该调用放置在“bar”属性中的闭包吗?

Chr*_*ian 5

是的,这确实是正确的。

唯一的调用方式bar是:

$bar = $foo->bar;
$bar();
Run Code Online (Sandbox Code Playgroud)

悲伤,但真实。

同样值得注意的是,由于同样的效果,$this内部没有$bar 调用(除非您将其作为名为 as 的函数参数传递$this)。

编辑:正如指出的,$this闭包内的值与创建闭包时的范围值相同。这可能意味着$this在两种情况下可能未定义:当作用域是全局 PHP 作用域时或作用域来自静态上下文时。但是,这意味着您理论上可以提供正确的实例:

class Foo {
    public $prop = 'hi';
    function test(){
        $this->bar = function(){
            echo $this->prop;
        }

        $bar = $this->bar;
        $bar();
    }
}

$foo = new Foo();
$foo->test();
Run Code Online (Sandbox Code Playgroud)

此外,似乎通过一些类魔法,您也可以实现$this->bar()

class Foo {
    // ... other stuff from above ...
    public function __call($name, $args){
        $closure = $this->$name;
        call_user_func_array( $closure, $args ); // *
    }
}
Run Code Online (Sandbox Code Playgroud)

[*]当心call_user_func_array非常缓慢的。

哦,这仅适用于 PHP 5.4。在此之前,没有$this闭包:)

此外,您可以在这里看到它的实际效果。