在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 應用在時間控制上更加精準和高效。