PHP-CLI中time()-$_SERVER["REQUEST_TIME_FLOAT"]结果差1秒的原因
问题原因解析
这个时间偏差的核心原因在于时间精度不匹配,结合time()和$_SERVER["REQUEST_TIME_FLOAT"]的特性共同导致,具体拆解如下:
1. 两个时间指标的精度差异
time()返回的是整秒级别的Unix时间戳,它只会截取当前时间的整数部分。比如当前实际时间是1699999999.8,time()只会返回1699999999,完全忽略小数部分的毫秒/微秒信息。$_SERVER["REQUEST_TIME_FLOAT"]是PHP启动时记录的高精度浮点时间,精确到微秒级别,比如1699999995.234567。
当你用time() - $_SERVER["REQUEST_TIME_FLOAT"]计算时,本质是用「当前整秒时间」减去「启动时的浮点时间」。假设脚本启动时间是1699999995.6,sleep(4)后实际流逝了4秒,当前时间是1699999999.6,此时time()返回1699999999,计算结果就是1699999999 - 1699999995.6 = 3.4——这就是你看到的3.X结果,差的那0.6秒就是time()忽略的小数部分。
2. 测试结果的验证
看你最后一次测试的输出:
hans@hans-lp17 ~ $ php -r 'function f(){sleep(4);var_dump(time()-$_SERVER["REQUEST_TIME_FLOAT"]);}f();f();' float(3.0999999046326) float(7.0999999046326)
第一次调用f()后,实际流逝4秒,但time()只取到了整秒,所以结果是3.X;第二次调用f()后,总共流逝8秒,此时time()取到的整秒减去启动浮点时间,刚好是7.X,和第一次的偏差完全一致,完美验证了这个逻辑。
另外getrusage()["ru_utime.tv_sec"]返回0也能说明:sleep(4)期间进程处于挂起状态,没有占用CPU时间,实际流逝的物理时间确实是4秒左右,只是计算方式的问题导致结果看起来有偏差。
3. 正确的计算方式
如果想要准确获取脚本运行的时间,应该用和$_SERVER["REQUEST_TIME_FLOAT"]精度匹配的microtime(true)来代替time(),它同样返回高精度浮点时间:
php -r 'sleep(4);var_dump(microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]);'
执行这个命令后,你会得到接近4秒的结果,完全符合预期。
内容的提问来源于stack exchange,提问作者hanshenrik
相关产品推荐
相关产品推荐

