5

如果我遍历一个数组两次,一次是按引用,然后是按值,如果我为每个循环使用相同的变量名,PHP 将覆盖数组中的最后一个值。最好通过一个例子来说明这一点:

$array = range(1,5);
foreach($array as &$element)
{
  $element *= 2;
}
print_r($array);
foreach($array as $element) { }
print_r($array);

输出:

数组( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10

数组( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8

请注意,我不是在寻找解决方法,而是想了解为什么会发生这种情况。另请注意,如果每个循环中的变量名不是每个都被调用,则不会发生这种情况$element,所以我猜这与$element仍在范围内和第一个循环结束后的引用有关。

4

3 回答 3

7

在第一个循环之后,$element 仍然是对 $array 的最后一个元素/值的引用。
您可以看到,当您使用 var_dump() 而不是 print_r()

array(5) {
  [0]=>
  int(2)
...
  [4]=>
  &int(2)
}

请注意 & 在&int(2).
在第二个循环中,您将值分配给 $element。由于它仍然是一个引用,因此数组中的值也发生了变化。试试看

foreach($array as $element)
{
  var_dump($array);
}

作为第二个循环,你会看到。
所以它或多或少与

$array = range(1,5);
$element = &$array[4];
$element = $array[3];
// and $element = $array[4];
echo $array[4];

(只有循环和乘法......嘿,我说“或多或少”;-))

于 2010-04-15T13:18:45.753 回答
5

以下是该男子本人的解释

$y = "some test";

foreach ($myarray as $y) {
    print "$y\n";
}

$y是一个符号表条目,它引用了一个包含“一些测试”的字符串。在第一次迭代中,您基本上是这样做的:

$y = $myarray[0];  // Not necessarily 0, just the 1st element

所以现在与关联的存储$y 被来自的值覆盖 $myarray。如果$y通过引用与某个其他存储关联,则该存储将被更改。

现在假设你这样做:

$myarray = array("Test");
$a = "A string";
$y = &$a;

foreach ($myarray as $y) {
    print "$y\n";
}

这里与通过引用$y关联的存储相同,$a因此当第一次迭代时:

$y = $myarray[0];

“Test”字符串唯一可以去的地方是与 $y.

于 2010-04-15T13:40:28.637 回答
1

这是解决此问题的方法:

foreach($array as &$element)
{
    $element *= 2;
}
unset($element); #gets rid of the reference and cleans the var for re-use.

foreach($array as $element) { }
于 2016-02-04T10:50:37.263 回答