<?php
$ar = [1, 2, 3];
var_dump($ar);
foreach ($ar as &$v) {} // 參考迭代
foreach ($ar as $v) {} // 一般值迭代
var_dump($ar);
/*
輸出:
array(3) { [0]=>1 [1]=>2 [2]=>3 }
array(3) { [0]=>1 [1]=>2 [2]=>&int(2) } // 最後一元素變成 2!
*/
?>
明明第二個 foreach 沒有任何賦值操作,陣列最後一元素卻被改成倒數第二元素的值。
foreach ($ar as &$v) 結束時,$v 仍保持對 $ar[2] 的參考。foreach ($ar as $v) 採用值複製模式。PHP 為了效能,重複使用同一個變數符號 $v,而非建立新變數。$ar[0] 時,執行「將 $ar[0] 的值賦值給 $v」。此時 $v 仍是指向 $ar[2] 的參考,導致 $ar[2] = $ar[0]。$ar[2] 變成 $ar[1] 的值(倒數第二元素)。這不是 Bug,而是 PHP 變數作用域與參考機制的語言特性。官方文件已以 Warning 標註。
<?php
$ar = [1, 2, 3];
foreach ($ar as &$v) {}
unset($v); // 關鍵:銷毀參考變數,後續 $v 將重新綁定
foreach ($ar as $v) {}
var_dump($ar); // 正常輸出 1, 2, 3
?>
foreach ($arr as &$v) 後,立即 unset($v)。foreach ($arr as $k => $v) { $arr[$k] = ...; } 避免參考殘留。