while循环先判断后执行;赋值表达式可作条件但不可用==;feof()有滞后性应直接判读取函数返回值;浮点数循环需改整数或加误差容限;变量未更新是死循环主因。

PHP 的 while 循环不是“先执行再判断”,它每次都会先检查条件,为 false 就跳过,一次都不跑——这点和 do-while 有本质区别,也是多数死循环的根源。
为什么 while($row = mysqli_fetch_assoc($result)) 能用但不能写成 ==
这是 PHP 中合法且高频的写法,但背后逻辑容易误读。赋值操作 $row = mysqli_fetch_assoc($result) 的返回值是被赋的值(即当前行数组或 null),PHP 会把它当作布尔值参与判断:null → false,非空数组 → true。
如果错写成 while ($row == mysqli_fetch_assoc($result)),问题有二:
- 每次判断都重新调用
mysqli_fetch_assoc(),直接跳过一行数据 -
==是松散比较,若某行是0或空字符串,可能被转成false提前退出
正确做法始终用 === 或单等号 + 明确判断:
立即学习“PHP免费学习笔记(深入)”;
while (($row = mysqli_fetch_assoc($result)) !== false) { ... }读文件时别用 feof() 做 while 条件
feof($fp) 不是“文件是否到末尾”的实时探测器,而是“上一次读取是否已触达 EOF”。在某些系统或缓冲模式下,它可能滞后返回 true,导致多读一次 fgets() 返回 false,进而引发 notice 或逻辑错乱。
更可靠、更惯用的写法是直接判断读取函数的返回值:
- 用
fgets($fp):while (($line = fgets($fp)) !== false) - 用
fread($fp, $len):while (($chunk = fread($fp, 8192)) !== false && $chunk !== '')
这样既避免了 feof() 的语义陷阱,也省去额外一次函数调用。
浮点数当循环变量?立刻放弃
写 $x = 0.1; while ($x != 1.0) { ... $x += 0.1; } 看似输出 0.1 到 1.0,实际很可能卡死或提前跳出——因为浮点数无法精确表示十进制小数,$x 累加后可能是 0.7999999999999999 或 1.0000000000000002,!= 判断彻底失效。
替代方案只有两个:
- 改用整数计数:
$i = 1; while ($i - 用差值容错判断:
while (abs($x - 1.0) > 1e-10)(仅限必须用浮点的极少数场景)
忘记更新变量是唯一最常触发无限循环的原因
没有初始化、没在循环体内修改、或修改语句被意外注释/跳过,都会让条件恒为真。PHP 不会警告你“这个变量好像没变”,它只会安静地一直跑。
检查要点很具体:
- 循环前是否显式赋初值?例如
$i = 0;,而不是依赖未声明变量默认为null - 递增/递减语句是否在所有执行路径中都可达?比如被
if包裹却条件永远不满足 - 是否误把
$i++写成$i =+ 1(其实是$i = +1,赋固定值)
真正难调试的不是语法错误,而是逻辑上“以为变了,其实没变”——建议在循环体开头加 var_dump($i); 快速验证。



















