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

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

问题描述

  class MyClass {
var $ lambda;
function __construct(){
$ this-> lambda = function(){echo'hello world';};
//这里没有错误,所以我认为这是合法的
}
}

$ myInstance = new MyClass();
$ myInstance-> lambda();
//致命错误:调用未定义的方法MyClass :: lambda()

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



$ expr-> something()是一个方法调用,因此PHP将在类中搜索一个方法。



$ expr-> something 是属性提取,因此PHP将在类中搜索属性。



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



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




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 ?

解决方案

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() is a method call, so PHP will search for a method in the class.

$expr->something is a property fetch, so PHP will search for a property in the class.

$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).

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

  • You can do this with ->lambda->__invoke():

    $myInstance = new MyClass();
    $myInstance->lambda->__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();
    

  • Or call it using call_user_func:

    call_user_func($myInstance->lambda);
    

    call_user_func can call any callable, including anonymous functions.

  • 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);
        }
    }
    

    Now this works:

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

    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天全站免登陆