foreach默认按值遍历,修改循环变量不影响原数组;需用&引用或键名索引($arr[$key])才能修改原数组,且引用后必须unset($item)避免残留bug。

foreach 循环里直接赋值改不了原数组
PHP 的 foreach 默认是按值遍历,每次循环拿到的是元素的副本。你对循环变量(比如 $item)重新赋值,不会影响原数组里的对应元素。
常见错误现象:
写成这样,数组根本没变:
$arr = ['a', 'b', 'c'];
foreach ($arr as $item) {
$item = strtoupper($item); // ✗ 无效
}
// $arr 还是 ['a', 'b', 'c']
用引用 & 修改原数组元素
必须显式声明引用,让 $item 指向原数组单元的内存地址。
- 在
$item前加&:即foreach ($arr as &$item) - 修改完后,**强烈建议 unset(
$item)**,否则后续可能意外污染其他变量(PHP 引用残留 bug) - 如果原数组是多维,要改深层值,需逐层加
&,比如foreach ($arr as &$sub) foreach ($sub as &$val)
正确示例:
立即学习“PHP免费学习笔记(深入)”;
$arr = ['a', 'b', 'c'];
foreach ($arr as &$item) {
$item = strtoupper($item);
}
unset($item); // ✅ 必须加
// $arr 变成 ['A', 'B', 'C']
用键名索引修改更安全、更清晰
不依赖引用,靠下标直接操作原数组,语义明确,无残留风险,适合多数场景。
- 用
foreach ($arr as $key => $value)形式,再通过$arr[$key] = ...赋值 - 支持所有数组类型(数字/字符串键、稀疏数组、关联数组)
- 性能差异可忽略,但可读性和维护性更好
示例:
$arr = ['name' => 'alice', 'age' => 25];
foreach ($arr as $key => $value) {
if ($key === 'name') {
$arr[$key] = ucfirst($value); // ✅ 安全修改
}
}
// $arr['name'] 变成 'Alice'
修改原数组时要注意的边界情况
有些看似合理的写法会出问题:
- 在
foreach中用array_push()或$arr[] = ...扩容,可能导致循环跳过新元素或重复遍历——PHP 内部数组指针行为不稳定 - 边遍历边
unset($arr[$key]),键名顺序可能错乱,尤其用for配合count()更危险 - 对引用数组嵌套修改时,若某个子项被
unset,其引用变量会变成null,容易引发 Notice
真正需要动态增删元素时,优先考虑先收集操作意图(如要删哪些键),循环结束后统一处理。
引用方式看着省事,但漏掉 unset() 是高频翻车点;键名索引写法多敲几个字符,换来的是确定性和后期没人骂你。



















