foreach不加&无法修改原数组,需用&$val;for/while通过下标可直接修改;多次foreach后应unset($val)防意外。

在 PHP 数组遍历中直接修改元素,看似简单,但容易踩坑——关键在于遍历方式决定是否能真正修改原数组。用错语法或忽略引用机制,常导致“改了却没改”的假象。
foreach 中不加 & 无法修改原数组元素
默认情况下,foreach ($arr as $val) 中的 $val 是元素的副本,修改它只影响当前循环变量,不影响原数组:
$arr = [1, 2, 3];
foreach ($arr as $val) {
$val *= 2; // 只改了 $val,$arr 不变
}
// $arr 仍是 [1, 2, 3]
要真正修改,必须显式使用引用:
-
foreach ($arr as &$val)—— 修改$val即修改原数组对应位置 - 循环结束后建议
unset($val),避免后续意外修改(尤其在多次 foreach 同一数组时)
for 循环和 while 遍历天然支持原地修改
它们通过下标直接访问数组,无需引用即可安全赋值:
立即学习“PHP免费学习笔记(深入)”;
$arr = [1, 2, 3];
for ($i = 0; $i < count($arr); $i++) {
$arr[$i] *= 2; // 直接改原数组
}
// $arr 变成 [2, 4, 6]
注意:count($arr) 在循环内调用没问题,但若循环中会增删元素,需谨慎处理边界(如用 sizeof() 或提前缓存长度)。
修改键名或增删元素时,避免边遍历边改动结构
在 foreach 中用 unset() 删除当前元素,或用 $arr[] = ... 追加,可能导致:
- 跳过下一个元素(内部指针偏移)
- 重复处理某个元素(PHP 7.0+ 行为更稳定,但仍不推荐)
- 警告或不可预期行为(尤其关联数组)
安全做法:先收集要操作的键,再统一处理:
$keys_to_remove = [];
foreach ($arr as $k => $v) {
if ($v < 5) $keys_to_remove[] = $k;
}
foreach ($keys_to_remove as $k) unset($arr[$k]);
关联数组遍历时,注意键类型和顺序稳定性
PHP 数组是有序哈希表,foreach 按插入顺序遍历。但若在循环中动态添加新键:
- 新键通常追加到末尾,不会干扰当前遍历(PHP 7.0+)
- 但若用
array_unshift()或重排函数(如ksort()),会破坏顺序,导致逻辑错乱 - 键为字符串数字(如
"1")或纯数字时,PHP 可能自动转换,引发意外交互
建议:结构变更操作尽量放在遍历之外,或用 array_map()、array_filter() 等函数替代手动循环修改。











