40

例如,如果我这样做:

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

$my_var = 0;
bar($my_var);

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

4

3 回答 3

65

不,它们不是通过引用传递的 -use遵循与函数参数类似的符号。

use正如所写的那样,您可以通过将引用定义为传递来实现:

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

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

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

注意:以下答案的旧摘录(2012 年 6 月)是为 PHP < 7.0 编写的。自 7.0(2015 年 12 月)以来,debug_zval_dump()更改的语义(不同的 zval 处理)refcount(?)现在它的输出有所不同,并且不再多说(整数不再有引用计数)。

通过不显示$my_var更改(从0)通过输出进行验证仍然有效(行为)。

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

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

一个完整的所有范围的工作参考将有一个 refcount 为 1。

于 2012-06-03T10:41:19.723 回答
20

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

function() use (&$var)

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

于 2012-06-03T10:36:06.283 回答
4

不,它们不是通过引用传递的。

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

$my_var = 0;
foo($my_var);
echo $my_var; // displays 0

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

$my_var = 0;
bar($my_var);
echo $my_var; // displays 1
于 2012-06-03T10:37:21.583 回答