【问题标题】:PHP - passing anonymous function as a parameterPHP - 将匿名函数作为参数传递
【发布时间】:2019-11-23 09:50:08
【问题描述】:

是否可以在 PHP 中将匿名函数作为参数传递?如果是 - 如何?

我正在尝试将一个匿名函数传递给一个 setter,它将用从该函数返回的值填充一个数组。

class MyClass
{
    private $arr = array();

    public function __construct()
    {
        $this->setArrElm('New', function(){return 123;});
    }

    private function setArrElm($name, $val)
    {
        // here: gettype($val) == object
        $this->arr[$name] = $val;
    }
}

请注意注释 - val 的类型是 object,我希望是 int。

【问题讨论】:

  • 当传递这样一个匿名函数时,PHP 实际上会传递一个代表该函数的对象。它被称为Closure。它是一个可调用对象,因此您仍然可以将其用作函数。
  • $this->arr[$name] = $val();

标签: php


【解决方案1】:

在 PHP 7 中,您可以自行执行闭包

class MyClass
{
    private $arr = array();

    public function __construct()
    {
        $this->setArrElm('New', (function(){return 123;})()); //<-- self execute
    }

    private function setArrElm($name, int $val) //<-- added typehint
    {
        // here: gettype($val) == object
        $this->arr[$name] = $val;
        print_r($val);
    }
}

new MyClass;

输出

123

Sandbox

这采用类似于 JS 的形式(也可能是其他语言):

 (function(){return 123;})()

重要的是要知道它正在执行函数,然后传递结果。您也可以传递闭包(它是一个对象)然后执行它。但是如果你有严格的类型并且需要一个 int,你也可以自己执行闭包。

只有当你需要一个 int 作为参数时,这样做才有意义。即使在这种情况下,您也可以事先执行它,然后传递结果。这只是为您节省了一个局部变量。

对于 PHP7 或者只是因为

Alt1

class MyClass
{
    private $arr = array();

    public function __construct()
    {
        $var = function(){return 123;};

        $this->setArrElm('New', $var()); //<-- execute
    }

    private function setArrElm($name, $val) //<-- added typehint
    {
        // here: gettype($val) == object
        $this->arr[$name] = $val;
        print_r($val);
    }
}

new MyClass;

Alt2

class MyClass
{
    private $arr = array();

    public function __construct()
    {
        $var = function(){return 123;};

        $this->setArrElm('New', $var); 
    }

    private function setArrElm($name, $val) //<-- mixed
    {
        if(gettype($val) == 'object' && is_a($val, '\Closure')){
             //is a closure, you could use is_callable etc. too. see __invoke()

            $val = $val();
        }
        $this->arr[$name] = $val;
        print_r($val);
    }
}

new MyClass;

Alt3

class MyClass
{
    private $arr = array();

    public function __construct()
    {
        $var = function(){return 123;};

        $this->setArrElm('New', $var); 
    }

    private function setArrElm($name, $val) //<-- mixed
    {
        if(is_callable($val)){
            //pass functions (as a string) or arrays or closures(executable classes with __invoke)
            $val = call_user_func($val);
        }
        $this->arr[$name] = $val;
        print_r($val);
    }
}

new MyClass;

干杯

【讨论】:

    猜你喜欢
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多