我是否遗漏了某些东西或者闭包只是不能用作类方法?以此为例:
$foo = new stdClass();
$foo->bar = function() {
echo '@@@';
};
$foo->bar();
似乎给我一个错误“致命错误:在第X行的/blah/blah.php中调用未定义的方法stdClass :: bar()”
这不应该调用放在“bar”属性中的闭包吗?
答案 0 :(得分:3)
是的,这确实是正确的。
致电bar
的唯一方法是:
$bar = $foo->bar;
$bar();
伤心,但确实如此。
另外值得注意的是,由于同样的效果,$ bar调用内没有 < / p>
$this
(除非你把它作为名为$this
的函数参数传递。)
编辑:正如nikic指出的那样,闭包内$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();
此外,似乎有一些类魔术,你也可以实现$this->bar()
:
class Foo {
// ... other stuff from above ...
public function __call($name, $args){
$closure = $this->$name;
call_user_func_array( $closure, $args ); // *
}
}
[*]请注意call_user_func_array
非常慢。
哦,这仅限于PHP 5.4。在此之前,闭包中没有$this
:)
,您可以在行动here中看到它。
答案 1 :(得分:1)
方法和领域完全分开;事实上,你甚至可以拥有一个同名的方法和领域:
<?php
class foo{
function bar() { echo "hello\n"; }
}
$object = new foo;
$object->bar = 1;
$object->bar(); // echoes "hello"
?>
这解释了为什么您的语法无法创建“真实”方法。