匿名函数返回值

15

更新: 从PHP7开始,现在可以使用以下语法来使用匿名函数取消引用:

$function = (function() { return "Hello, world!"; })(); echo $function; // Output: Hello, world!

$array[] = [
    'new' => (function()
    {
        ...
        return mt_rand();
    })(),

    'or' => getClosure()()
]

原始帖子:最近我在尝试一些新东西,并想知道是否有任何方法可以使用匿名函数的返回值。

假设我有一个for循环,它创建一个数组,数组的每个值都必须进行数据库调用,我想要做的是:

for($i = 0; $i != 10; $i++)
{
    $array[] = [
        'new' => function(){
            // some proccesing here maybe
            // lets use mt_rand for this example.
            return mt_rand();
        },

        'old' => function(){
            return mt_rand();
        }
    ];
}

或者也许

echo function(){
     // again, we'll just use mt_rand
     return mt_rand();
};

这两种方法都返回一个 closure 类。有没有办法将它们的返回值传回到数组或者上面的示例中进行输出?

更新:我已经确认这是不可能的,因此可以在此处找到功能请求:http://bugs.php.net/bug.php?id=64608


你真的需要匿名函数吗?听起来你只需要一个普通函数,然后在循环内调用它。 - kero
取决于您使用的PHP版本...我相信PHP 5.4可能能够做到这一点,但运行旧软件包的服务器(例如Debian Squeeze我知道运行PHP 5.3)则无法实现。 - Julian H. Lam
@JulianH.Lam 我的示例是在 PHP 5.4.13 上测试过的。 - Jordan Doyle
@JordanDoyle 您想定义并立即执行一个匿名函数。虽然您找到的票据表明目前不可能,但我想知道是否有许多情况需要使用它。您提出问题的方式表明这是不可能的 - 这并不是事实。您的循环使用一些匿名函数填充了一个数组。为什么它们应该立即执行?也许只有在需要时才执行它们可能是一个非常好的主意。 - Sven
@Sven,它们需要一次性执行才能与模板系统配合使用。 - Jordan Doyle
显示剩余2条评论
4个回答

25

迄今为止最简单的解决方法:

echo call_user_func(function () { return 'foo'; });

1
PHP7现在支持匿名函数解引用! - Jordan Doyle

2
尝试将匿名的函数赋值给一个变量。
$myFunc = function() {
  return 'Test';
}

echo $myFunc(); // Outputs Test

函数本身的值不是返回值,当函数被 调用 时返回的值才是返回值。

编辑:

deceze所建议,您可以使用 call_user_func()。实现您想要的另一种方法是利用 PHP 的 eval(),但这绝不是良好的编码实践。

$array[] = array(
  'new' => call_user_func(function() {
     // some proccesing here maybe
     // lets use mt_rand for this example.
     return mt_rand();
  }),
  'old' => call_user_func(function() {
    return mt_rand();
  }),
);

eval()

eval()

echo eval('$x = function() {
  // some proccesing here maybe
  // lets use mt_rand for this example.
  return mt_rand();
}; return $x();');

我认为OP想要在访问$myFunc时返回的值,而不是$myFunc() - user142162
@TimCooper 不,你需要函数调用,请看这里http://codepad.viper-7.com/3nnjGW - Sam
@Sam:是的,我知道你必须评估函数才能获得返回值,但我认为这是一个关于在哪里进行评估的问题。我认为 OP 希望在定义匿名函数时对其进行评估。 - user142162
eval 是解决这个问题最糟糕的方案。 - deceze

1

在取消引用闭包之前,必须对其进行分配 - 请尝试以下代码:

for($i = 0; $i != 10; $i++)
{
    $array[] = [
    'new' => call_user_func(function(){
        // some proccesing here maybe
        // lets use mt_rand for this example.
        return mt_rand();
    }),

    'old' => call_user_func(function(){
        return mt_rand();
    })
    ];
}

[编辑] - 修改为使用call_user_func()而不是自定义函数 - 哎呀!


0

你必须将函数分配给一个变量,看这里

这个工作

    for($i = 0; $i != 10; $i++)
 {
$array[] = [
    'new' => function(){
        // some proccesing here maybe
        // lets use mt_rand for this example.
        return mt_rand();
    },

    'old' => function(){
        return mt_rand();
    }
];
}
echo $array[5]['new']();

或者

$function = function(){
 // again, we'll just use mt_rand
 return mt_rand();
};

echo $function();

1
在我的情况下,我需要直接从返回值开始。运行$a = function(){ return mt_rand(); }();无法正常工作。 - Jordan Doyle
因为这是一个赋值操作,你可以执行 $a(),有什么问题吗? - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接