如何调用作为类变量的闭包? [英] How to call a closure that is a class variable?

查看:25
本文介绍了如何调用作为类变量的闭包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

那么访问类变量的正确语法是什么?

So what is the correct syntax for reaching class variables ?

推荐答案

在 PHP 中,方法和属性在一个单独的命名空间中(你可以有一个同名的方法和一个属性),以及你是否正在访问一个属性或方法取决于您使用的语法.

In PHP, methods and properties are in a separate namespace (you can have a method and a property with the same name), and whether you are accessing a property or a method depends of the syntax you are using to do so.

$expr->something() 是一个方法调用,所以 PHP 会在类的方法列表中搜索 something.

$expr->something() is a method call, so PHP will search something in the class' list of methods.

$expr->something 是一个属性获取,所以 PHP 会在类的属性列表中搜索 something.

$expr->something is a property fetch, so PHP will search something in the class' list of properties.

$myInstance->lambda(); 被解析为一个方法调用,所以 PHP 在你的类中搜索一个名为 lambda 的方法,但是没有这样的方法(因此出现调用未定义方法错误).

$myInstance->lambda(); is parsed as a method call, so PHP searches for a method named lambda in your class, but there is no such method (hence the Call to undefined method error).

所以你必须使用 fetch property 语法来获取 lambda,然后调用它.

So you have to use the fetch property syntax to fetch the lambda, and then call it.

  • 从 PHP 7.0 开始,您可以使用 ($obj->lambda)() 来做到这一点:

($obj->lambda)();

括号确保 PHP 将 ($obj->lambda) 解析为 获取名为 lambda 的属性.然后,() 调用获取属性的结果.

The parentheses make sure that PHP parses ($obj->lambda) as fetch the property named lambda. Then, () calls the result of fetching the property.

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

or you can do this with ->lambda->__invoke():

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

__invokePHP 的魔法方法之一.当一个对象实现这个方法时,它变得可调用:它可以使用 $var() 语法调用.匿名函数是 Closure 的实例,它实现了 __invoke.

__invoke is one of PHP's magic methods. When an object implements this method, it becomes invokable: it can be called using the $var() syntax. Anonymous functions are instances of Closure, which implements __invoke.

或者将其赋值给一个局部变量:

Or assign it to a local variable:

$lambda = $myInstance->lambda;
$lambda();

  • 或者使用 call_user_func 调用它:

  • Or call it using call_user_func:

    call_user_func($myInstance->lambda);
    

    call_user_func 可以调用任何callable,包括匿名函数.

    call_user_func can call any callable, including anonymous functions.

    或者,如果这是您代码中的常见模式,您可以设置一个 __call 方法来将调用转发到您的 lambda:

    Alternatively, if this is a common pattern in your code, you can setup a __call method to forward calls to your 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 中做到这一点:

    Since PHP 5.4 you can even do that in a trait:

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

  • 这篇关于如何调用作为类变量的闭包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆