40

For example, if I do this:

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

$my_var = 0;
bar($my_var);

Will $my_var be modified? If not, how do I get this to work without adding a parameter to $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(from 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 に答える