我有三个函数,foo
,bar
和baz
,从我的角度来看,它应该产生相同的结果。但是,我遇到了在递归函数调用之间引用共享的问题。
$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);
此代码产生以下结果:
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
但是,我希望所有这些都返回3, 3
,因为数组的副本会传递给递归调用。
如何修复前两个函数以使它们返回3, 3
?我不想使用baz
函数的语法,因为它非常详细。
答案 0 :(得分: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! */
?>
换句话说,数组的引用行为是逐个元素定义的;单个元素的引用行为与数组容器的引用状态分离。