核心函數:microtime()
<?php
// 默認返回字符串 "0.123456 1705300000" (微秒 秒)
echo microtime();
// true 參數直接返回浮點秒數
echo microtime(true); // 1705300000.123456
?>
獲取毫秒數(整數)
方案一:sprintf 格式化(推薦,精度可控)
<?php
function getMillisecond(): float {
[$usec, $sec] = explode(' ', microtime());
// (秒 + 微秒) * 1000 = 毫秒
return (float)sprintf('%.0f', ((float)$sec + (float)$usec) * 1000);
}
// 測試
echo getMillisecond(); // 1705300000123 (13 位整數)
?>
方案二:microtime(true) 直接運算(簡潔)
<?php
function getMillisecondV2(): float {
return (float)sprintf('%.0f', microtime(true) * 1000);
}
?>
方案三:PHP 7.3+ hrtime() 納秒級(最高精度)
<?php
// 返回納秒數(相對任意起點,不可作為 Unix 時間戳)
$ns = hrtime(true); // int (64位)
// 轉毫秒
$ms = (int)($ns / 1_000_000);
// 計算耗時(極高精度)
$start = hrtime(true);
// ... 代碼 ...
$elapsedMs = (hrtime(true) - $start) / 1_000_000;
?>
32 位系統整數溢出陷阱
| 系統 | PHP_INT_MAX | 毫秒時間戳 (2024年) | 是否溢出 |
| 64 位 | 9,223,372,036,854,775,807 (~9×10¹⁸) | ~1.7×10¹² | ✅ 安全 |
| 32 位 | 2,147,483,647 (~2×10⁹) | ~1.7×10¹² | ❌ 溢出! |
結論:32 位 PHP 無法用整數存儲毫秒時間戳(已超過 21 億上限),必須用浮點數。
浮點數精度設置
<?php
// 默認精度 14 位,毫秒時間戳需 13 位,臨界夠用
// 但為了安全,建議顯式設置
ini_set('precision', '16'); // 或在 php.ini: precision = 16
$ms = getMillisecond();
echo $ms; // 正確輸出 1705300000123
// 若 precision=10 會輸出 1.7053E+12 (科學計數法丟失精度)
?>
實戰:生成唯一訂單號/請求 ID
<?php
function generateRequestId(): string {
$ms = getMillisecond(); // 13 位毫秒
$rand = mt_rand(100, 999); // 3 位隨機
return (string)$ms . $rand; // 16 位:時間+隨機,極低衝突
}
// 高併發下更安全:hrtime 納秒 + 進程ID
function generateUniqueId(): string {
$ns = hrtime(true); // 納秒
$pid = getmypid() % 1000; // 進程號後3位
return base_convert($ns, 10, 36) . str_pad($pid, 3, '0', STR_PAD_LEFT);
}
?>
性能對比
<?php
$n = 1_000_000;
$start = microtime(true);
for ($i=0; $i<$n; $i++) microtime(true);
echo "microtime(true): " . (microtime(true)-$start) . "s\n";
$start = microtime(true);
for ($i=0; $i<$n; $i++) hrtime(true);
echo "hrtime(true): " . (microtime(true)-$start) . "s\n";
$start = microtime(true);
for ($i=0; $i<$n; $i++) getMillisecond();
echo "getMillisecond(): " . (microtime(true)-$start) . "s\n";
// 典型輸出 (PHP 8.2):
// microtime(true): 0.08s
// hrtime(true): 0.06s
// getMillisecond(): 0.15s (字符串解析開銷)
?>
總結選擇指南
| 需求 | 推薦函數 | 返回類型 | 精度 | 適用場景 |
| Unix 毫秒時間戳 | sprintf('%.0f', microtime(true)*1000) | float | 毫秒 | 訂單號、日誌時間、API 簽名時間戳 |
| 高精度耗時測量 | hrtime(true) | int (納秒) | 納秒 | 性能分析、基準測試、SWOOLE 定時器 |
| 微秒字符串 | microtime() | string | 微秒 | 調試輸出、人類可讀 |
| 浮點秒數 | microtime(true) | float | 微秒 | 緩存過期時間、簡單時間差 |