在 PHP 中,我们经常需要让程序暂停一段时间,这在处理轮询、定时任务或限速操作时非常常见。通常,大家会使用 sleep() 函数来实现这一目的,但 sleep() 的时间单位是秒,无法满足对毫秒甚至纳秒级别的精确控制需求。这时,PHP 提供了 time_nanosleep() 函数,能让你以秒和纳秒的精度来控制暂停时间。
time_nanosleep() 是 PHP 5.0.0 及以上版本中提供的函数,用来让当前进程暂停指定的秒数和纳秒数。相比 sleep() 只能精确到秒,time_nanosleep() 允许你更灵活地控制暂停时间。
函数定义如下:
bool time_nanosleep(int $seconds, int $nanoseconds)
$seconds:暂停的秒数,整数。
$nanoseconds:暂停的纳秒数,整数,范围为 0 到 999,999,999。
如果暂停成功,函数返回 true,如果中途被信号打断,则返回一个包含剩余时间的数组。
下面是一个简单的例子,演示如何用 time_nanosleep() 暂停 1 秒又 500 毫秒(即 1.5 秒):
<?php
echo "开始时间:" . microtime(true) . PHP_EOL;
$seconds = 1;
$nanoseconds = 500000000; // 500 毫秒 = 500,000,000 纳秒
if (time_nanosleep($seconds, $nanoseconds)) {
echo "睡眠结束时间:" . microtime(true) . PHP_EOL;
} else {
echo "睡眠被中断" . PHP_EOL;
}
?>
运行结果会显示两次时间戳,时间差约为 1.5 秒。
如果 time_nanosleep() 被系统信号中断,会返回一个数组,里面包含剩余的秒数和纳秒数。你可以根据返回值重新调用 time_nanosleep() 来继续睡眠。示例如下:
<?php
$seconds = 2;
$nanoseconds = 0;
while (true) {
$result = time_nanosleep($seconds, $nanoseconds);
if ($result === true) {
echo "睡眠完成" . PHP_EOL;
break;
} elseif (is_array($result)) {
echo "睡眠被中断,剩余时间:{$result['seconds']}秒 {$result['nanoseconds']}纳秒" . PHP_EOL;
$seconds = $result['seconds'];
$nanoseconds = $result['nanoseconds'];
} else {
echo "睡眠失败" . PHP_EOL;
break;
}
}
?>
这种写法确保程序能够在被信号打断后继续完成预定的睡眠时间。
假设你想实现一个请求限速的功能,每次请求之间暂停 200 毫秒,可以结合 curl 发送请求,使用 time_nanosleep() 来精准控制间隔时间。以下是示例代码:
<?php
$urls = [
"https://gitbox.net/api/data1",
"https://gitbox.net/api/data2",
"https://gitbox.net/api/data3",
];
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo "请求失败:" . curl_error($ch) . PHP_EOL;
} else {
echo "请求成功:" . substr($response, 0, 50) . "..." . PHP_EOL;
}
curl_close($ch);
// 暂停 200 毫秒
time_nanosleep(0, 200000000);
}
?>
这段代码依次请求三个接口,每次请求后暂停 200 毫秒,从而避免请求过于频繁。
time_nanosleep() 允许你以秒和纳秒的精度让 PHP 程序暂停。
需要注意处理信号中断的情况,保证程序逻辑的健壮性。
在需要限速、间隔控制或精细调度时,time_nanosleep() 是一个非常实用的函数。
通过合理运用 time_nanosleep(),可以让你的 PHP 应用在时间控制上更加精准和高效。