<?php
$items = [['a' => '1', 'b' => 1], ['a' => '2', 'b' => 2], ['a' => '3', 'b' => 3]];
foreach ($items as &$item) {
// 什么都没做
}
// 此时 $item 是 $items[2] 的引用
$items[] = ['a' => '4', 'b' => 4];
// 现在 $items 有4个元素:索引0,1,2,3
// $item 仍然引用 $items[2](原来的第3个元素)
for ($i = 0; $i < count($items); $i++) {
$item = $items[$i];
// 第1次循环:$i=0,$item = $items[0]
// 因为 $item 是引用,所以 $items[2] 被修改为 $items[0]
// 第2次循环:$i=1,$item = $items[1]
// $items[2] 被修改为 $items[1]
// 第3次循环:$i=2,$item = $items[2]
// $items[2] 被修改为 $items[2](自身,不变)
// 第4次循环:$i=3,$item = $items[3]
// $items[2] 被修改为 $items[3]
}
var_dump($items);
array(4) {
[0]=> array(2) { ["a"]=> string(1) "1" ["b"]=> int(1) }
[1]=> array(2) { ["a"]=> string(1) "2" ["b"]=> int(2) }
[2]=> array(2) { ["a"]=> string(1) "4" ["b"]=> int(4) } // 被改成了最后一个元素
[3]=> array(2) { ["a"]=> string(1) "4" ["b"]=> int(4) }
}
| 循环次数 | 执行语句 | $items[2] 变成 |
|---|---|---|
| 初始状态 | $item 引用 $items[2] |
['a'=>'3','b'=>3] |
| i=0 | $item = $items[0] |
['a'=>'1','b'=>1] |
| i=1 | $item = $items[1] |
['a'=>'2','b'=>2] |
| i=2 | $item = $items[2] |
['a'=>'2','b'=>2] (不变) |
| i=3 | $item = $items[3] |
['a'=>'4','b'=>4] |
array(4) {
[0]=> array(2) { ["a"]=> "1", ["b"]=> 1 }
[1]=> array(2) { ["a"]=> "2", ["b"]=> 2 }
[2]=> array(2) { ["a"]=> "4", ["b"]=> 4 } // 重复了最后一项
[3]=> array(2) { ["a"]=> "4", ["b"]=> 4 }
}
在 foreach 后立即 unset($item),或者不使用引用。