首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 獲取毫秒級時間戳:microtime() 高精度實現與 32 位系統陷阱

     編輯:PHP 綜合知識

核心函數: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微秒緩存過期時間、簡單時間差
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved