PHP中遍历二维数组应优先使用foreach而非for,因foreach自动解构键值、避免越界、容错性强;for需手动控制索引,易在空数组或非数组元素时出错。

PHP for 循环遍历二维数组的基本写法
直接用 for 遍历二维数组,核心是先拿到外层数组长度,再嵌套一层 for 处理内层数组。它不像 foreach 那样自动解构键值,必须手动控制索引,稍不注意就容易越界或漏元素。
假设你有这样一个二维数组:
$data = [
['name' => '张三', 'age' => 25],
['name' => '李四', 'age' => 30],
['name' => '王五', 'age' => 28]
];要安全遍历,得这么做:
- 外层
for的上限用count($data),不是count($data) - 1—— 因为for ($i = 0; $i 才能覆盖全部索引 - 内层循环前,必须检查
isset($data[$i]) && is_array($data[$i]),否则遇到空行或非数组元素会报Warning: Invalid argument supplied for foreach()或 Notice - 如果内层数组键名不固定(比如有的有
'city',有的没有),别硬写$data[$i]['city'],先用isset()或??运算符兜底
for 遍历关联二维数组时怎么取键和值
for 本身不提供键名,它只按数字索引跑。如果你的二维数组是关联形式(比如用字符串作外层键),for 就不适用了——它会跳过非数字键,甚至直接报错 Undefined offset。
立即学习“PHP免费学习笔记(深入)”;
这种场景下,要么转成数字索引数组再用 for:
$indexed = array_values($data); // 强制重排索引
要么老老实实用 foreach。硬要用 for 去“模拟”关联遍历,就得额外维护一个键数组:
$keys = array_keys($data);
for ($i = 0; $i < count($keys); $i++) {
$key = $keys[$i];
$row = $data[$key];
echo $key . ': ' . ($row['name'] ?? 'N/A') . "\n";
}但这么写既绕又易错,除非你在做底层索引映射逻辑,否则没必要。
性能和可读性对比:for vs foreach
纯数字索引二维数组下,for 和 foreach 性能差异几乎可以忽略(PHP 7.4+ 两者编译后接近)。但可读性和安全性上,foreach 明显更稳:
-
foreach ($data as $row)不怕空数组,for忘写count()判断就会无限循环 -
foreach ($data as $i => $row)能同时拿到数字键和值,比手动维护$i变量更少出错 - 如果二维数组某一行是
null或字符串,foreach会跳过或报错更明确;for容易在$data[$i]这步就触发 Notice
所以除非你在写性能敏感的底层工具函数,或者明确需要控制索引步长(比如每次处理两行),否则优先选 foreach。
容易被忽略的边界情况
真实项目里,二维数组往往不是“教科书式”的整齐结构。下面这些点,for 很容易翻车:
- 外层数组为空:
count($data) === 0,此时for ($i = 0; $i 不执行,看似安全,但若后续代码没判空就直接用 <code>$data[0],就崩了 - 内层数组不等长:第 0 行有 3 个字段,第 1 行只有 2 个,用
for ($j = 0; $j 没问题,但若写成 <code>for ($j = 0; $j 就会错读第 1 行 - 数组中混入非数组项:比如
$data[1] = "invalid",for照样进循环,但count("invalid")返回 1,接着$data[1][0]就变成字符串首字符,完全偏离预期
这些都不是语法问题,而是数据契约没对齐。写 for 时,别假设输入“应该”是什么,得用 is_array()、isset()、array_key_exists() 主动校验。



















