【发布时间】:2011-12-14 09:55:59
【问题描述】:
我是否遗漏了什么或者闭包根本不能作为类方法工作?以此为例:
$foo = new stdClass();
$foo->bar = function() {
echo '@@@';
};
$foo->bar();
似乎给我一个错误“致命错误:在第 X 行的 /blah/blah.php 中调用未定义的方法 stdClass::bar()”
这不应该调用放置在“bar”属性中的闭包吗?
【问题讨论】:
我是否遗漏了什么或者闭包根本不能作为类方法工作?以此为例:
$foo = new stdClass();
$foo->bar = function() {
echo '@@@';
};
$foo->bar();
似乎给我一个错误“致命错误:在第 X 行的 /blah/blah.php 中调用未定义的方法 stdClass::bar()”
这不应该调用放置在“bar”属性中的闭包吗?
【问题讨论】:
是的,确实是这样。
拨打bar的唯一方法是:
$bar = $foo->bar;
$bar();
悲伤,但真实。
同样值得注意的是,由于同样的效果,$bar 调用中没有$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看到它。
【讨论】:
->invoke() 调用闭包类成员。 stackoverflow.com/questions/4535330/…
方法和字段是完全分开的;事实上,你甚至可以拥有同名的方法和字段:
<?php
class foo{
function bar() { echo "hello\n"; }
}
$object = new foo;
$object->bar = 1;
$object->bar(); // echoes "hello"
?>
这解释了为什么您的语法无法创建“真实”方法。
【讨论】:
bar和调用存储在字段bar中的函数在语法上没有区别。所以你在做什么是模棱两可的