uniqid() 基於微秒時間生成唯一標識,廣泛用於臨時文件名、緩存鍵、安全 Token、數據庫主鍵等場景。本文系統講解函數原型、基礎用法、與 md5() 組合、可排序性優勢,並對比三種生成 UUID 的進階方案。
string uniqid([string $prefix = ""][, bool $more_entropy = false])
// PHP 3, 4, 5, 7, 8 全版本可用
$prefix:前綴,區分業務場景(如 order_, token_)。$more_entropy:true 時在末尾增加額外熵(組合線性同餘產生器),長度達 23 字符,碰撞概率更低。<?php
// 1. 默認 13 字符(十六進制微秒時間)
echo uniqid(); // 例: 65a8f3c2d1e4b
// 2. 帶前綴
echo uniqid('ord_'); // ord_65a8f3c2d1e4b
// 3. 更多熵(23 字符)
echo uniqid('', true); // 65a8f3c2d1e4b7.12345678
// 4. 結合 md5() 產生 32 字符定長 ID
echo md5(uniqid('', true)); // dfbc5c8c6438de075da28b3c8a413fd0
// 5. 連續生成展示可排序性
echo uniqid() . "\n"; // 65a8f3c2d1e4b
echo uniqid() . "\n"; // 65a8f3c2d1e5a
echo uniqid() . "\n"; // 65a8f3c2d1e6c
// 按字典序排序即為時間順序,利於數據庫索引/分頁
因基於時間戳,uniqid() 生成的 ID 天然按生成順序排序。對比 UUID v4(隨機)或 md5(rand()),在數據庫聚簇索引(InnoDB 主鍵)場景下,順序寫入大幅減少頁分裂,寫入性能提升 30%+。
$id = md5(time() . mt_rand(1, 1000000));
// 秒級時間 + 隨機數,高併發下理論可能重複
function uuid() {
if (function_exists('com_create_guid')) { // Windows COM
return com_create_guid();
}
mt_srand((double)microtime() * 10000); // PHP < 4.2.0 需要
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = '-';
return '' // '{'
. substr($charid, 0, 8) . $hyphen
. substr($charid, 8, 4) . $hyphen
. substr($charid, 12, 4) . $hyphen
. substr($charid, 16, 4) . $hyphen
. substr($charid, 20, 12); // '}'
}
// 輸出格式: 5DDB650F-4389-F4A9-A100-501EF1348872
public function create_guid($namespace = '') {
static $guid = '';
$uid = uniqid("", true);
$data = $namespace
. $_SERVER['REQUEST_TIME']
. $_SERVER['HTTP_USER_AGENT']
. $_SERVER['LOCAL_ADDR']
. $_SERVER['LOCAL_PORT']
. $_SERVER['REMOTE_ADDR']
. $_SERVER['REMOTE_PORT'];
$hash = strtoupper(hash('ripemd128', $uid . $guid . md5($data)));
$guid = '{'
. substr($hash, 0, 8) . '-'
. substr($hash, 8, 4) . '-'
. substr($hash, 12, 4) . '-'
. substr($hash, 16, 4) . '-'
. substr($hash, 20, 12)
. '}';
return $guid;
}
// 輸出: {E2DFFFB3-571E-6CFC-4B5C-9FEDAAF2EFD7}
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 臨時文件/緩存鍵/短期 Token | uniqid('prefix_', true) | 極快、長度適中、可排序、無依賴 |
| 數據庫主鍵/分布式 ID(單機/低併發) | md5(uniqid('', true)) | 32 字符定長、可排序、碰撞極低 |
| 分布式系統/高併發/跨語言互通 | UUID v7 (時間有序) / Snowflake / ULID | 標準化、強排序、無中心協調 |
| Windows 環境需符合 COM 規範 | com_create_guid() | 原生實現,格式標準 |
<?php
// PHP 8.2+ 推薦:密碼學安全隨機 UUID v4
$uuid = \Random\Randomizer::getBytes(16);
$uuid[6] = ($uuid[6] & 0x0f) | 0x40; // version 4
$uuid[8] = ($uuid[8] & 0x3f) | 0x80; // variant 10
echo bin2hex($uuid); // 32 字符十六進制
// 或使用 symfony/uid, ramsey/uuid 等成熟庫
uniqid() 可預測(基於時間),安全 Token 必須用 random_bytes() / openssl_random_pseudo_bytes()。$more_entropy=true 或組合 random_int()。CHAR(32) 存 md5(uniqid()),或 CHAR(36) 存標準 UUID,避免 VARCHAR 索引效率較低。理解 uniqid() 的時間有序特性與局限性,結合業務場景選擇最適合的唯一 ID 生成策略,是 PHP 開發者處理分布式標識的基本功。