for循环边界写成$i会导致数组越界访问,因$i未初始化或未正确设置终止条件,可能引发未定义行为或程序崩溃。

for循环边界写成$i 会越界,不是少一项而是多一次
很多人以为$i 更“保险”,结果循环体执行了count($arr) + 1次,最后一次访问$arr[count($arr)]——这个下标根本不存在,PHP 返回 NULL 或触发 Notice: Undefined offset。真正导致“少遍历一项”的常见原因是:$i 这类手动减 1 的写法,或者初始化时错写成 $i = 1。
- 正确写法只有一种:
for ($i = 0; $i - 别把
count($arr)提前存变量再减 1,除非你真要跳过最后一项 - 如果数组是空的,
count($arr) === 0,$i 不成立,循环直接跳过——这是预期行为,不是 bug
在循环里修改数组长度却没倒序,索引自动偏移导致漏掉下一项
PHP 的 for 循环不感知数组内容变化,它只按初始 count($arr) 和当前 $i 值机械推进。一旦你在循环中调用 unset($arr[$i]) 或 array_splice(),后续元素索引集体前移,但 $i 仍照常递增,刚移到 $i 位置的那个元素就被跳过了。
- 正向删元素时,必须倒序:
for ($i = count($arr) - 1; $i >= 0; $i--) -
unset()不会重排索引,所以下次循环仍用原$i判断,不会“错乱”——但你要删的是当前项,不是靠索引找下一项 - 真要重排索引(比如之后还要用数字键),得等循环结束再调
$arr = array_values($arr),不能塞进循环里
初始化或条件表达式里误写赋值语句,导致循环一次都不跑
for 的三个表达式职责分明:第一个只运行一次,第二个是每次循环前判断的布尔条件,第三个是每次循环体结束后执行。如果在第二个表达式里写 $i = $i + 1,那它就不是判断,而是赋值——结果永远返回真(非零即真),变成无限循环;如果写成 $i = 0,那每次都是 0,也永远为真。
- 典型错误:
for ($i = 0; $i = $i + 1; $i++)—— 第二个表达式恒为真 - 另一个坑:
for (;$i 没初始化$i,直接报Undefined variable: i - 递增写
$i++或$i += 1就行,别用$i = $i + 1,可读性差还易手滑写错位置
用count($arr)做条件却在循环里增删元素,性能和逻辑双崩
每次循环都重新调用 count($arr),对大数组就是纯 CPU 浪费;更危险的是,如果循环体里动态改变了数组长度,count($arr) 的返回值每轮都在变,$i 和边界就彻底失同步——可能提前结束、可能多跑几次、也可能卡死。
- 安全做法:循环前缓存长度,
$len = count($arr),然后用$i - 但缓存长度只解决“长度不变”的场景;如果真要边遍历边改数组,优先考虑
foreach+ 引用修改,或改用反向for - 记住:
foreach基于内部哈希游标,不受unset影响,遍历稳定性远高于for
倒序遍历不是“技巧”,是修改数组时维持索引正确的硬性要求;而把 count() 放进条件里,表面省事,实际埋了性能和逻辑两颗雷——这两点最容易被当成小问题忽略,直到线上数据出错才去翻日志。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











