do while 先执行后判断,while 先判断后执行;前者循环体至少运行一次,后者可能零次;故 mysqli_fetch_assoc() 场景中 do while 会因首次 $row 为 null 导致访问错误。

do while 和 while 的核心区别不是语法多一个 do,而是条件判断发生的时机不同:前者先执行、后判断,后者先判断、后执行。 这一点直接决定循环体是否至少运行一次,也决定了你在数据库遍历、用户输入验证等场景中会不会踩坑。
为什么 while ($row = mysqli_fetch_assoc($result)) 不能换成 do ... while ($row = mysqli_fetch_assoc($result))
因为 mysqli_fetch_assoc() 在结果集为空时返回 null,而 while 会先检查这个值——为 null 就不进循环,安全;do while 却会先执行一次循环体,此时 $row 是 null,再访问 $row['id'] 就触发 Notice: Trying to access array offset on value of type null。
- 常见错误现象:循环第一次就报 Notice 或 Fatal error
- 根本原因:把「读取并判断」逻辑拆到了循环体和条件两处,而
do while强制先跑体、再判值 - 修复方式:要么改回
while,要么在do块开头加if (!$row) break;
do while (0) 不是死循环,而是 C 风格的“伪作用域”写法
PHP 支持这种写法,常用于封装多步逻辑并用 break 提前退出,避免嵌套过深或重复写 if 判断。
- 示例:
do { if (!$user) { break; } if (!is_email($user['email'])) { break; } send_welcome_email($user); } while (0); - 注意:末尾必须有分号,否则 PHP 8.0+ 报
Parse error: syntax error, unexpected ';' - 这不是循环技巧,本质是利用
do while语法允许单次执行 +break控制流,替代 goto 或多层嵌套
空条件或恒假条件下的行为差异最能暴露区别
比如初始变量 $i = 10,条件设为 $i :
立即学习“PHP免费学习笔记(深入)”;
while ($i —— 完全不输出do { echo $i; } while ($i —— 输出一次 <code>10,然后退出
这种差异在生成唯一 ID、重试请求、菜单交互等「必须先做一次再看要不要继续」的场景里是设计依据,不是 bug。
最容易被忽略的是:do while 的分号是语法必需,漏掉就直接解析失败;而 while 后面加多余分号(如 while(true); {})反而会导致空循环体无限执行——这两处标点看似微小,影响的是整个控制流是否成立。



















