php 5.6 的 sleep() 不支持小数秒,传入浮点数会报错并返回 false;应改用 usleep()(单位微秒)或封装 sleep_ms() 统一处理,注意精度截断与 sapi 差异。

PHP 5.6 的 sleep() 不支持小数,直接报错
PHP 5.6 的 sleep() 函数只接受整数秒,传入 0.5 或 1.2 这类浮点数会触发警告并返回 false,实际不生效。这不是 bug,是设计如此——它底层调用的是系统 sleep(3),POSIX 标准里就只认整秒。
如果你在老项目里写了 sleep(0.1) 并期望休眠 100ms,那它根本不会睡,代码会立刻往下跑,可能引发竞态、重复提交或接口误判。
用 usleep() 替代,但注意单位和整数截断
usleep() 接收微秒(1 秒 = 1,000,000 微秒),且只接受整数参数。所以要把小数秒换算成整数微秒,不能直接丢给它浮点数。
-
sleep(0.3)→ 改成usleep(300000) -
sleep(1.999)→ 改成usleep(1999000)(别写usleep(1.999 * 1000000),PHP 会把浮点结果转整时向下取整,(int)(1.999 * 1000000)可能得 1998999) - 更稳妥写法:
usleep(round($seconds * 1000000)),避免精度丢失
封装一个兼容函数,避开版本判断和重复转换
与其到处改 sleep() 调用,不如统一替换为自定义函数,内部按版本或参数类型自动路由:
立即学习“PHP免费学习笔记(深入)”;
function sleep_ms($seconds) {
if ($seconds < 0.001) {
return;
}
$microseconds = (int) round($seconds * 1000000);
if ($microseconds < 1000000) {
usleep($microseconds);
} else {
sleep((int) floor($seconds));
$left = $seconds - floor($seconds);
if ($left > 0) {
usleep((int) round($left * 1000000));
}
}
}这样调用 sleep_ms(0.05)、sleep_ms(2.7) 都能正确处理,不用关心底层是 sleep() 还是 usleep()。
注意 usleep() 在 CLI 和 Web SAPI 下的行为差异
在 CLI 模式下,usleep() 基本准时;但在 Apache mod_php 或某些 FastCGI 环境中,受 PHP 的 tick 机制和服务器超时配置影响,实际休眠可能略长(尤其短于 10ms 时误差明显)。
- 低于 10000 微秒(10ms)的延时,不要依赖精确性,更适合用轮询 +
time_nanosleep()(需启用pcntl扩展) - Web 请求中慎用
usleep()做“防刷”或“限频”,容易被反向代理或 CDN 缓存绕过 - 如果项目已用
set_time_limit(0),也要确认 web 服务器(如 Nginx 的fastcgi_read_timeout)没强行中断连接
真正要跨版本稳定延时,关键不是选 sleep() 还是 usleep(),而是统一入口、显式单位、规避浮点截断,并意识到 PHP 层的延时永远只是近似值。











