class MyClass { var $lambda; function __construct() { $this->lambda = function() {echo 'hello world';}; // no errors here, so I assume that this is legal } } $myInstance = new MyClass(); $myInstance->lambda(); //Fatal error: Call to undefined method MyClass::lambda()
那么到达类变量的正确语法是什么?
在PHP中,方法和属性位于单独的命名空间中(您可以具有相同名称的方法和属性),而访问属性还是方法取决于您使用的语法。
$expr->something()是一个方法调用,因此PHP将something在类的方法列表中进行搜索。
$expr->something()
something
$expr->something是属性提取,因此PHP将something在类的属性列表中搜索。
$expr->something
$myInstance->lambda();被解析为方法调用,因此PHP会lambda在您的类中搜索一个命名的方法,但是没有这样的方法(因此 Call to undefined method error)。
$myInstance->lambda();
lambda
因此,您必须使用 fetch属性 语法来获取lambda,然后对其进行调用。
($obj->lambda)()
($obj->lambda)();
括号确保PHP解析($obj->lambda)为 获取名为lambda的属性 。然后,()调用获取属性的结果。
($obj->lambda)
()
->lambda->__invoke()
$myInstance = new MyClass();
$myInstance->lambda->__invoke();
__invoke是PHP的魔术方法之一。当对象实现此方法时,它可以调用:可以使用$var()语法来调用它。匿名功能的实例Closure,其实现__invoke。
__invoke
$var()
Closure
或将其分配给局部变量:
$lambda = $myInstance->lambda;
$lambda();
或使用call_user_func调用它:
call_user_func($myInstance->lambda);
call_user_func可以调用任何callable,包括匿名函数。
call_user_func
callable
__call
class MyClass
{ private $lambda;
public function __construct() { $this->lambda = function() { echo "Hello world!\n"; }; } public function __call($name, $args) { return call_user_func_array($this->$name, $args); }
}
现在这有效:
$myInstance = new MyClass(); $myInstance->lambda();
从PHP 5.4开始,您甚至可以在特征中做到这一点:
trait LambdasAsMethods { public function __call($name, $args) { return call_user_func_array($this->$name, $args); } } class MyClass { use LambdasAsMethods; private $lambda; public function __construct() { $this->lambda = function() { echo "Hello World!\n"; }; } } $myInstance = new MyClass(); $myInstance->lambda();