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()
那么到达类变量的正确语法是什么?
答案 0 :(得分:183)
在PHP中,方法和属性位于单独的命名空间中(您可以使用具有相同名称的方法和属性),无论您是要访问属性还是方法,都取决于您使用的语法。
$expr->something()
是一个方法调用,因此PHP将在类的方法列表中搜索something
。
$expr->something
是属性提取,因此PHP将在类的属性列表中搜索something
。
$myInstance->lambda();
被解析为方法调用,因此PHP在您的类中搜索名为lambda
的方法,但是没有这样的方法(因此调用未定义的方法错误)。
所以你必须使用 fetch属性语法来获取lambda,然后调用它。
自PHP 7.0以来,您可以使用($obj->lambda)()
执行此操作:
($obj->lambda)();
括号确保PHP解析($obj->lambda)
获取名为lambda 的属性。然后,()
调用获取属性的结果。
或者您可以使用->lambda->__invoke()
执行此操作:
$myInstance = new MyClass();
$myInstance->lambda->__invoke();
__invoke
是PHP's magic methods之一。当一个对象实现此方法时,它将变为可调用:可以使用$var()
语法调用它。匿名函数是Closure
的实例,它实现__invoke
。
或者将其分配给本地变量:
$lambda = $myInstance->lambda;
$lambda();
或使用call_user_func调用它:
call_user_func($myInstance->lambda);
call_user_func
可以调用任何callable
,包括匿名函数。
或者,如果这是代码中的常见模式,则可以设置__call
方法将呼叫转发到lambda:
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();
答案 1 :(得分:2)
您也可以使用ReflectionFunction调用您的lambda函数,而无需更改类中的某些内容。
$myInstance = new MyClass();
$lambda = new ReflectionFunction($myInstance->lambda);
$lambda->invoke();
或者如果你必须传递参数
$args = array('arg'=>'value');
$lambda->invokeArgs($args);