foreach中获取键值需写$key => $value,修改原数组需引用&$value并循环后unset($value),遍历时增删元素行为不稳定,应先收集键再统一处理。

foreach 里怎么拿到键和值
直接用 $key => $value 语法,这是最常用也最容易漏掉的写法。不写 => 就只能拿到值,键会丢。
- 如果只写
foreach ($arr as $item),$item是值,$key根本不存在 - 想同时用键和值,必须显式写出
foreach ($arr as $key => $value) - 键可能是数字(索引数组)或字符串(关联数组),
$key类型自动匹配,不用提前声明 - 注意:遍历对象时,
$key是属性名,但仅限 public 属性;private/protected 属性不会出现在这个循环里
foreach 中修改原数组要用 & 引用
默认 foreach 是复制值,改 $value 不影响原数组。真要改,得加 &,但加错位置或时机就出问题。
- 正确写法:
foreach ($arr as &$value)——&必须紧贴$value,不能写成foreach ($arr as $&value) - 引用循环结束后,
$value仍指向原数组最后一项,后续再用$value赋值会意外改掉数组末尾元素(常见坑) - 安全做法:循环完立刻加
unset($value)断开引用 - 如果还要用键,写成
foreach ($arr as $key => &$value),&依然只作用于$value
foreach 遍历过程中增删数组元素会怎样
PHP 不禁止,但行为不稳定 —— 多数情况是“跳过”或“重复”,不是报错,所以很难排查。
- 在循环中用
unset($arr[$key])删除当前项:当前项之后的元素可能被跳过(内部指针偏移) - 用
$arr[] = ...追加:新元素大概率不会被本轮循环访问到(foreach 启动时已确定迭代范围) - 如果必须边遍历边改,建议先收集要操作的键,循环结束后统一处理,比如:
$toRemove = []; foreach ($arr as $k => $v) { if (...) $toRemove[] = $k; } foreach ($toRemove as $k) unset($arr[$k]); - 对非数组(如 Iterator 对象)做类似操作,行为更不可控,优先避免
foreach 和 for / while 性能差多少
日常开发几乎感觉不到差异,但极端场景下,foreach 在底层做了优化,比手写 for 略快,尤其对大数组。
-
foreach直接使用 PHP 的 HashTable 内部结构,无需计算count()或反复取下标 for ($i = 0; $i 每次都调用count(),且每次都要做数组下标查找,慢一截- 如果确实要用
for,至少把count()提前缓存:$len = count($arr); for ($i = 0; $i - 但只要不是百万级数据+高频执行,选哪个主要看可读性 ——
foreach更贴近意图,也更少出错
实际写的时候,最常栽在引用没清理、键值写反、或者以为删了元素循环会自动重排。这些都不是语法错误,跑起来也没 warning,等逻辑对不上才回头找,特别耗时间。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











