如何调用一个类variables的闭包?

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() 

那么达到类variables的正确语法是什么?

在PHP中,方法和属性位于一个单独的名称空间中(您可以拥有同名的方法和属性),而且您是否正在访问属性或方法取决于您正在使用的语法。

$expr->something()是一个方法调用,所以PHP将search类的方法列表中的something

$expr->something是一个属性获取,所以PHP将search类的属性列表中的something

$myInstance->lambda(); 被parsing为一个方法调用,所以PHP在你的类中search名为lambda的方法,但是没有这样的方法(因此调用未定义的方法错误)。

所以你必须使用fetch属性语法来获取lambda,然后调用它。

  • 从PHP 7.0开始,你可以用($obj->lambda)()来完成这个工作:

     ($obj->lambda)(); 

    圆括号确保PHPparsing($obj->lambda)作为获取名为lambda的属性 。 然后, ()调用获取属性的结果。

  • 或者你可以用->lambda->__invoke()来做到这一点。

     $myInstance = new MyClass(); $myInstance->lambda->__invoke(); 

    __invoke是PHP的魔法之一 。 当一个对象实现这个方法时,它就成为可调用的:它可以使用$var()语法来调用。 匿名函数是Closure实例,它实现了__invoke

  • 或者把它分配给一个局部variables:

     $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(); 

你也可以使用ReflectionFunction来调用你的lambda函数而不用改变你的类中的东西。

 $myInstance = new MyClass(); $lambda = new ReflectionFunction($myInstance->lambda); $lambda->invoke(); 

或者如果你必须传递参数

 $args = array('arg'=>'value'); $lambda->invokeArgs($args);