PHP:递归调用之间共享引用

Ath*_*ari 5 php recursion reference pass-by-reference

我有三个功能,foo,barbaz,其中,从我的角度来看,应该产生相同的结果.但是,我遇到了一个问题,即在递归函数调用之间共享引用.

$array = array(
    'subs' => array(
        'a' => 1,
        'b' => 2,
    ),
);

function foo(&$array, $value, $callAgain = true) {
    $subs =& $array['subs'];
    foreach ($subs as &$sub)
        $sub = $value;
    if ($callAgain) {
        $copy = $array;
        foo($copy, $value + 1, false);
    }
}

function bar(&$array, $value, $callAgain = true) {
    foreach ($array['subs'] as &$sub)
        $sub = $value;
    if ($callAgain) {
        $copy = $array;
        bar($copy, $value + 1, false);
    }
}

function baz(&$array, $value, $callAgain = true) {
    foreach ($array['subs'] as $key => $sub)
        $array['subs'][$key] = $value;
    if ($callAgain) {
        $copy = $array;
        baz($copy, $value + 1, false);
    }
}

foo($array, 3);
var_dump($array);
bar($array, 3);
var_dump($array);
baz($array, 3);
var_dump($array);
Run Code Online (Sandbox Code Playgroud)

此代码生成以下结果:

array
  'subs' => 
    array
      'a' => int 4
      'b' => int 4
array
  'subs' => 
    array
      'a' => int 3
      'b' => int 4
array
  'subs' => 
    array
      'a' => int 3
      'b' => int 3
Run Code Online (Sandbox Code Playgroud)

但是,我希望所有这些都返回3, 3,因为数组的副本被传递给递归调用.

如何修复前两个函数让它们返回3, 3?我不想使用baz函数的语法,因为它非常详细.

jsl*_*uth 3

我想你已经回答了你自己的问题——baz这是获得你想要的行为的方法。另外两个函数的行为符合 PHP 的预期,至少根据What References Do的手册页是这样的:

但请注意,数组内的引用存在潜在危险。对右侧的引用进行正常(非通过引用)赋值不会将左侧变成引用,但数组内的引用会保留在这些正常赋值中。这也适用于按值传递数组的函数调用。例子:

/* Assignment of array variables */
$arr = array(1);
$a =& $arr[0]; //$a and $arr[0] are in the same reference set
$arr2 = $arr; //not an assignment-by-reference!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* The contents of $arr are changed even though it's not a reference! */
?>
Run Code Online (Sandbox Code Playgroud)

换句话说,数组的引用行为是逐个元素定义的;各个元素的引用行为与数组容器的引用状态无关。