foreach遍历空数组时不会执行循环体,因其内部先检查count($arr)===0,为空则直接跳过;空数组包括[]、array()、空查询结果、json_decode('[]',true),而[null]非空。

foreach 遍历空数组时根本不会执行循环体
因为 foreach 的设计逻辑就是「有元素才迭代」。它内部会先检查数组是否为空(即 count($arr) === 0),若为空,直接跳过整个循环体,连一次迭代都不会触发。这不是 bug,是 PHP 的确定性行为。
常见错误现象:
你写了 foreach ($items as $item) { echo $item; },但页面没输出、日志没记录、断点没命中——不是代码卡住,而是 $items 恰好是空数组([] 或 array()),循环压根没进去。
- 空数组包括:
[]、array()、从数据库查不到结果返回的mysqli_result->fetch_all(MYSQLI_ASSOC)空结果、json_decode('[]', true) - 注意:包含
null元素的数组(如[null])不是空数组,foreach会执行一次,$item值为null - 如果需要区分「未初始化」和「明确为空」,建议显式判断:
if (!is_array($arr) || empty($arr)) { /* 处理空情况 */ }
for 循环遍历空数组会直接跳过,但写法不当可能出 Notice
for 本身不感知「数组」,它只看初始条件。如果你写 for ($i = 0; $i ,而 <code>$arr 是空数组,count($arr) 返回 0,所以 $i 为 false,循环体一次都不执行——这和 <code>foreach 表现一致。
但容易踩的坑是:把 count() 放在循环条件里又没做类型校验。例如 $arr 是 null 或字符串,count(null) 会返回 1(PHP 7.2+ 起返回 1,且触发 E_WARNING),导致循环意外执行或报错。
立即学习“PHP免费学习笔记(深入)”;
- 安全写法:
if (!is_array($arr)) { $arr = []; } for ($i = 0; $i - 更推荐用
foreach,它对非数组输入会直接报Fatal error: Uncaught TypeError,比静默出错更容易定位 - 性能上,
count()在for条件中每次迭代都调用——空数组虽只调一次,但习惯性放外面更好:$len = count($arr); for ($i = 0; $i
while + each() 已废弃,且空数组会立即返回 false
each() 函数在 PHP 7.2+ 已被废弃,8.0+ 彻底移除。它的行为是:对空数组调用 each($arr) 直接返回 false,所以 while (list($k, $v) = each($arr)) 一次都不进。
这不是兼容性问题,是语义使然:each() 的作用是「取当前指针位置的键值并后移」,空数组无当前元素,自然返回 false。
- 不要试图用
reset($arr); while (false !== ($pair = each($arr)))来“修复”——它依然对空数组无效,且已不可用 - 替代方案只有
foreach或for+array_keys()(不推荐,多一次遍历) - 如果维护老代码遇到这个模式,优先替换为
foreach,顺便去掉废弃警告
判断空数组别只靠 foreach 是否执行,要主动检查
依赖「循环没进」来推断数组为空,是脆弱的逻辑。比如你忘了给变量赋值,它可能是 undefined(PHP 中为 null),foreach (null as ...) 会直接报致命错误,而不是安静跳过。
- 最稳妥的判断是:
is_array($arr) && empty($arr)—— 同时确认类型和内容 -
empty($arr)单独用有风险:对0、"0"、false、null都返回 true,不能用于判数组空 - 如果数组可能为 null,且你想统一处理空/未定义场景,用
!is_array($arr) || !$arr不够严谨,仍建议先is_array再empty
空数组不进循环不是异常,是预期行为;但人容易把「没反应」当成「卡住」或「逻辑漏了」,真正该花精力的是厘清数据来源是否可靠、是否提前做了必要校验。



















