PHP 闭包中的 use 关键字是否通过引用传递?

2022-08-30 12:01:28

例如,如果我这样做:

function bar(&$var)
{
    $foo = function() use ($var)
    {
        $var++;
    };
    $foo();
}

$my_var = 0;
bar($my_var);

将被修改?如果没有,我如何在不添加参数的情况下使其工作?$my_var$foo


答案 1

不,它们不是通过引用传递的 - 遵循类似的表示法,如函数的参数。use

正如所写的,你通过定义作为传递引用来实现这一点:use

    $foo = function() use (&$var)

也可以通过以下方式创建递归:

$func = NULL;
$func = function () use (&$func) {
    $func();
}

注意:以下答案的旧摘录(2012 年 6 月)是为 PHP < 7.0 编写的。自7.0(2015年12月)以来,已更改(不同的zval处理)的语义现在不同,并且不再那么重要(整数不再具有refcount)。debug_zval_dump()refcount(?)

通过不显示已更改(来自)的输出进行验证仍然有效(行为)。$my_var0

您可以在debug_zval_dump函数(演示)的帮助下自行验证:

function bar(&$var)
{
    $foo = function() use ($var)
    {
        debug_zval_dump($var);
        $var++;
    };
    $foo();
};
    
$my_var = 0;
bar($my_var);
echo $my_var;

输出:

long(0) refcount(3)
0

一个全范围工作引用的引用编号为 1。


答案 2

几乎根据定义,闭包是由值而不是通过引用来关闭的。您可以通过在参数列表中添加一个来“通过引用使用”:&

function() use (&$var)

这可以在匿名函数手册页的示例 3 中看到。


推荐