应提前缓存 count() 结果,因 for 循环每次迭代前都重新计算条件表达式;若数组键不连续(如 ['id'=>1, 'name'=>'bob']),for 易越界而 foreach 不会。

要提前取出,否则每次迭代都调用 count() 是纯浪费。
为什么 for 循环里 count() 会重复执行
for 的条件表达式在每次迭代前都会重新求值。写成 for ($i = 0; $i ,等于每轮都执行一次 <code>count($arr) ——哪怕数组没变、长度固定。
- 对小数组(
- 对千级数组,多出上千次函数调用;若在高并发或循环嵌套中,性能拖累会放大
-
count()虽然快,但不是零成本:它要检查类型、遍历内部哈希表计数(对非 Countable 对象)
什么时候必须提前缓存 count() 结果
绝大多数标准遍历场景都需要缓存,尤其是:
- 纯数字索引数组(如
$arr = [1, 2, 3, 4])且循环体不修改数组结构 - 需要反向遍历(
for ($i = $len - 1; $i >= 0; $i--)) - 同步遍历多个等长数组(
for ($i = 0; $i )
示例:
/* 低效 */ for ($i = 0; $i /<em> 高效 </em>/ $len = count($data); for ($i = 0; $i <h3>提前缓存的例外情况:循环中修改了数组</h3><p>如果循环体内有 <code>unset($arr[$i])</code>、<code>array_push()</code>、<code>array_splice()</code> 等操作,导致数组长度动态变化,那缓存的 <code>$len</code> 就会失效——可能跳过元素或触发 <code>Notice: Undefined offset</code>。</p>
- 此时优先改用
foreach,它基于内部指针,天然适配动态数组 - 若必须用
for,就得手动维护边界,比如每次迭代后重算$len = count($arr),但这就又回到性能陷阱 - 更稳妥的做法是:先收集待删/待加的键或值,循环结束后批量处理
真正容易被忽略的是混合数组(数字键 + 字符串键)和空数组边界。比如 $arr = [0 => 'a', 'name' => 'bob'],count($arr) 返回 2,但 $arr[1] 不存在——for 循环在这种结构上极易越界,而 foreach 不会。别为了省一个变量,把逻辑复杂度和出错风险全扛在 for 上。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











