必须先调用 reset($arr) 重置指针,再用 while 配合 current()、key()、next() 遍历;判断条件应为 key($arr) !== null 而非 current($arr) !== false,以避免 falsy 值误判;绝大多数场景应优先使用 foreach。

用 while 遍历数组前必须重置内部指针
PHP 的 while 本身不直接支持数组遍历,得靠 current()、key()、next() 这组函数配合。但很多人一上来就写 while (current($arr)),结果第一次循环就跳过首元素,或遍历不全——因为数组的内部指针可能不在开头。
正确做法是先调用 reset($arr),强制把指针挪到第一个元素位置:
$arr = ['a', 'b', 'c'];
reset($arr);
while (($val = current($arr)) !== false) {
echo key($arr) . ' => ' . $val . "\n";
next($arr);
}
-
current($arr)返回当前指针指向的值;返回false表示已到末尾(注意:若数组含0、''、null等 falsy 值,要用!== false判断) -
key($arr)获取当前键名,适用于关联数组 - 漏掉
next($arr)就会无限循环
遍历关联数组时别只依赖 current()
如果数组键是字符串(比如 ['name' => 'Tom', 'age' => 25]),current() 和 key() 仍可用,但容易混淆“键是否存在”和“值是否为 falsy”。比如 'status' => 0 会被 current() === false 误判为结束。
更稳妥的方式是用 key($arr) !== null 作为循环条件:
立即学习“PHP免费学习笔记(深入)”;
$user = ['name' => 'Tom', 'age' => 25, 'status' => 0];
reset($user);
while (key($user) !== null) {
$k = key($user);
$v = current($user);
echo "$k: $v\n";
next($user);
}
- 只要还有键,
key()就返回对应字符串/数字;遍历完才返回null - 这个判断不受值内容影响,比
current() !== false更可靠 - 仍需
reset()开头,否则从当前指针位置开始,可能漏掉前面的元素
foreach 是绝大多数情况的更好选择
用 while 手动控制指针,代码冗长、易错、可读性差。PHP 官方文档也明确建议:除非你要在循环中动态修改数组指针(比如跳过某些项、回退、或嵌套遍历时做指针隔离),否则直接用 foreach。
它自动处理指针、兼容索引/关联数组、语义清晰:
foreach ($arr as $key => $value) {
// 安全、简洁、不易出错
}
-
foreach每次迭代都复制一份内部指针状态,原数组指针不受影响 - 想中途
break或continue,逻辑直观;而while+next()容易漏调next()导致死循环 - 性能上,
foreach在 PHP 7+ 已优化得和手动指针操作几乎无差别
真要手动控制指针时,小心 foreach 和 while 混用
同一个数组如果先用 foreach 遍历过,再用 while + current(),很可能从中间开始——因为 foreach 会移动内部指针到末尾。
这时候不能只靠 reset(),还得确认没其他代码干扰指针:
- 函数内传参是值传递,但数组在 PHP 中默认是“写时复制”,
reset()只影响当前作用域副本 - 如果数组是引用传入(
&$arr),reset()会影响原始数组指针 - 调试时可用
var_dump(key($arr), current($arr))快速检查当前指针状态
手动指针操作不是不能用,而是它属于“知道风险还坚持用”的场景,而不是默认首选。



















