在PHP中向数组添加引用会创建一个引用数组

7

不确定这是否被视为一个错误

$array = ['numbers' => [1, 2, 3]];
foreach ($array as &$numbers) {
    $numbers = [4, 5, 6];
}
var_dump($array);
modify_array($array);
var_dump($array);

function modify_array($array_arg)
{
    $array_arg['numbers'] = [1, 2, 3];
}

打印功能
array(1) {
  ["numbers"]=>
  &array(3) {
    [0]=>
    int(4)
    [1]=>
    int(5)
    [2]=>
    int(6)
  }
}
array(1) {
  ["numbers"]=>
  &array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
}

注意,$array没有通过引用传递给modify_array()函数,但是嵌套数组已被修改。这听起来很合乎逻辑,但不确定是否有记录!
2个回答

4
如果你在使用foreach循环时使用引用,就可以防止PHP复制数组,这样你就可以直接操作原始数组。当你完成foreach循环后,应该使用unset()函数来删除循环中使用的变量,因为它仍然存在于内存中。如果你不这样做,就会得到像你提出的那样不可预测的结果。即使在文档中也有一个警告:

警告:即使在foreach循环之后,$value的引用和最后一个数组元素仍然存在。建议使用unset()函数将其销毁。

这里有一些没有使用unset函数的foreach循环的非常好的例子。

因此,如果你添加了unset()函数,一切看起来都应该是正常的。

$array = ['numbers' => [1, 2, 3]];
foreach ($array as &$numbers) {
    $numbers = [4, 5, 6];
}
unset($numbers);
var_dump($array);
modify_array($array);
var_dump($array);

function modify_array($array_arg) {
    $array_arg['numbers'] = [1, 2, 3];
}

结果:

array(1) { ["numbers"]=> array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) } } 
array(1) { ["numbers"]=> array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) } }

只是想说,如果有人需要确认:http://codepad.viper-7.com/hcpoWB 我添加的唯一一件事就是带 br 标签的那一行。 - Jonathan Kuhn
2
如果你不这样做,你将得到不可预测的结果。那么是什么告诉我们结果必须是不可预测的呢?你引用的警告并没有解释行为。 - zerkms
1
我同意,根据警告,结果将是非常可预测的,但除此之外,这仍然是一个有用的答案。 - StackSlave

0
如果您重写以下代码:
foreach ($array as &$numbers) {
    $numbers = [4, 5, 6];
}

变成这样:

  $array['numbers'] = &$array['numbers'];
  $array['numbers'] = [4,5,6]; 

这种行为会更容易理解,而且这似乎是一个已知的问题。 (参见:http://php.net/manual/zh/language.references.php#87532


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接