rsk*_*k82 75 php lambda closures anonymous-function
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()
Run Code Online (Sandbox Code Playgroud)
那么到达类变量的正确语法是什么?
Arn*_*anc 187
在PHP中,方法和属性位于单独的命名空间中(您可以使用具有相同名称的方法和属性),无论您是访问属性还是方法,都取决于您使用的语法.
$expr->something()是一个方法调用,因此PHP将something在类的方法列表中进行搜索.
$expr->something是一个属性获取,因此PHP将something在类的属性列表中搜索.
$myInstance->lambda();被解析为方法调用,因此PHP搜索lambda您的类中指定的方法,但没有这样的方法(因此调用未定义的方法错误).
所以你必须使用fetch属性语法来获取lambda,然后调用它.
从PHP 7.0开始,您可以使用($obj->lambda)():
($obj->lambda)();
Run Code Online (Sandbox Code Playgroud)
括号确保PHP解析($obj->lambda)为fetch名为lambda的属性.然后,()调用获取属性的结果.
或者你可以这样做->lambda->__invoke():
$myInstance = new MyClass();
$myInstance->lambda->__invoke();
Run Code Online (Sandbox Code Playgroud)
__invoke是PHP的神奇方法之一.当一个对象实现此方法时,它变为可调用:可以使用$var()语法调用它.匿名功能的实例Closure,其实现__invoke.
或者将其分配给局部变量:
$lambda = $myInstance->lambda;
$lambda();
Run Code Online (Sandbox Code Playgroud)或者使用call_user_func调用它:
call_user_func($myInstance->lambda);
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在这个工作:
$myInstance = new MyClass();
$myInstance->lambda();
Run Code Online (Sandbox Code Playgroud)
从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();
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
23380 次 |
| 最近记录: |