绝大多数数组遍历场景优先用foreach;仅当需数字索引顺序、跳步、倒序或精确控循环时才选for,因非连续键数组用for会漏数据、需array_values()重排且有性能开销,foreach改值须加引用并及时unset,而for天然修改原数组,性能差异在十万级以下可忽略。

直接说结论:绝大多数数组遍历场景,优先用 foreach;只有当你明确需要按数字索引顺序、跳步、倒序、或循环次数完全可控时,才考虑 for。
数组键不是连续数字时,for 会漏数据甚至不工作
这是最常踩的坑。比如这个数组:$arr = [1 => 'a', 3 => 'b', 5 => 'c'],count($arr) 是 3,但 for($i=0; $i<count> 只会尝试访问 <code>$arr[0]、$arr[1]、$arr[2] —— 其中只有 $arr[1] 存在,其余是 undefined index 警告,$arr[3] 和 $arr[5] 根本不会被触达。
foreach 没这个问题,它按数组内部顺序逐个取元素,不管键是数字、字符串还是跳跃的。
- 关联数组(如
['name' => 'Alice', 'age' => 30])只能用foreach - 稀疏索引数组(如
[0 => 'x', 100 => 'y'])用for会跳过中间大量空位 - 如果硬要用
for遍历非连续索引数组,得先用array_values()重排,但这就多了一次复制开销
foreach 默认操作副本,改值要加引用
foreach($arr as $value) 中的 $value 是原数组元素的拷贝,修改它不影响 $arr 本身。想真正改原数组,必须写成 foreach($arr as &$value)。
而 for 直接通过索引赋值,比如 $arr[$i] = strtoupper($arr[$i]),天然就改原数组。
- 加引用后记得在循环结束后调用
unset($value),否则后续代码中$value仍指向最后一个数组元素,可能引发意外覆盖 -
foreach($arr as $key => &$value)是安全的写法,$key不受影响 - PHP 7.4+ 支持解构语法:
foreach($arr as [$id, $name]),但仅限数组元素本身是数组的情况
性能差异其实很小,别为“快一点”牺牲可读性和安全性
在十万级以下数据量时,for 和 foreach 的执行时间差通常在微秒级。PHP 内部对 foreach 做了大量优化,它不是简单地“复制数组”,而是复用内部哈希表指针。
真正影响性能的是你在循环体里干了什么 —— 比如在循环里反复调用 count()、做 in_array() 查询、或连接数据库。
for($i=0; $i<count> 每次都调用 <code>count(),应写成$len = count($arr); for($i=0; $i- 如果循环里要根据键查值,
foreach天然带$key,for得自己维护索引变量 - 嵌套循环中混用
for和foreach容易导致逻辑错乱,统一风格更稳妥
真正容易被忽略的点是:foreach 对空数组、null、非数组类型会静默失败或报 Fatal error,而 for 在 count(null) 时会返回 0,反而“安全”地跳过 —— 所以实际使用前,该做类型判断的还得做,不能依赖循环结构本身兜底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











