UUID (Universally Unique Identifier) 是 128 位元識別碼,標準格式為 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(8-4-4-4-12,共 36 字元)。常見版本:
Microsoft 實作為 GUID,格式通常帶大括號:{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}。
<?php
/**
* 生成 RFC 4122 相容的 UUID v4(隨機)
* @param bool $uppercase 是否大寫輸出
* @param bool $braces 是否包含大括號(GUID 風格)
* @return string
*/
function generate_uuid_v4(bool $uppercase = false, bool $braces = false): string {
// PHP 7.0+ 使用 random_bytes(密碼學安全隨機源)
$bytes = random_bytes(16);
// 設定版本位(第 7 字節高 4 位 = 0100 = v4)
$bytes[6] = chr((ord($bytes[6]) & 0x0F) | 0x40);
// 設定變體位(第 9 字節高 2 位 = 10 = RFC 4122)
$bytes[8] = chr((ord($bytes[8]) & 0x3F) | 0x80);
// 組裝標準格式
$hex = bin2hex($bytes);
$uuid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split($hex, 4));
if ($uppercase) $uuid = strtoupper($uuid);
if ($braces) $uuid = '{' . $uuid . '}';
return $uuid;
}
/**
* 批次生成(效能優化:單次 random_bytes 產生多組)
*/
function generate_uuids_v4(int $count = 100, bool $uppercase = false, bool $braces = false): array {
$bytes = random_bytes(16 * $count);
$uuids = [];
for ($i = 0; $i < $count; $i++) {
$chunk = substr($bytes, $i * 16, 16);
$chunk[6] = chr((ord($chunk[6]) & 0x0F) | 0x40);
$chunk[8] = chr((ord($chunk[8]) & 0x3F) | 0x80);
$hex = bin2hex($chunk);
$uuid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split($hex, 4));
if ($uppercase) $uuid = strtoupper($uuid);
if ($braces) $uuid = '{' . $uuid . '}';
$uuids[] = $uuid;
}
return $uuids;
}
// 使用範例
echo generate_uuid_v4(); // 如: 550e8400-e29b-41d4-a716-446655440000
echo generate_uuid_v4(true, true); // 如: {550E8400-E29B-41D4-A716-446655440000}
<?php
/**
* 使用 Windows 系統 API 生成 GUID(Version 1,含 MAC/時間)
* 需啟用 php_com_dotnet.dll 擴展
*/
function generate_guid_com(): ?string {
if (!class_exists('COM')) {
trigger_error('COM 元件未啟用,請在 php.ini 開啟 extension=com_dotnet', E_USER_WARNING);
return null;
}
try {
$guid = com_create_guid(); // 返回格式: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
return $guid;
} catch (com_exception $e) {
trigger_error('COM 生成 GUID 失敗: ' . $e->getMessage(), E_USER_WARNING);
return null;
}
}
// 使用範例
$guid = generate_guid_com();
if ($guid) echo $guid; // 輸出: {A1B2C3D4-E5F6-1122-3344-5566778899AA}
| 函式庫 | 安裝 | 特色 |
|---|---|---|
| ramsey/uuid | composer require ramsey/uuid | 支援 v1~v8、編碼/解碼、Doctrine/laravel 整合、最活躍維護 |
| symfony/uid | composer require symfony/uid | 輕量、原生 UUID 物件、Symfony 生態無縫整合 |
| webonyx/graphql-php | composer require webonyx/graphql-php | 內建 UUID 型別、GraphQL 專案首選 |
<?php
// ramsey/uuid 使用範例
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
try {
// v4 隨機
$uuid4 = Uuid::uuid4()->toString();
// v1 時間+MAC
$uuid1 = Uuid::uuid1()->toString();
// v7 時間有序(適合資料庫主鍵,索引友善)
$uuid7 = Uuid::uuid7()->toString();
echo "v4: $uuid4\nv1: $uuid1\nv7: $uuid7\n";
} catch (UnsatisfiedDependencyException $e) {
// 回退到 polyfill 或原生實現
echo generate_uuid_v4();
}
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 一般 Web 專案、API Token、檔案命名 | 原生 generate_uuid_v4() | 零依賴、效能佳、RFC 4122 相容 |
| 高併發分散式系統、資料庫主鍵 | ramsey/uuid (v7) 或自研 Snowflake/ULID | 時間有序減少索引分裂、全域唯一 |
| 需與 Windows 系統互操作(COM、註冊表、AD) | COM com_create_guid() | 系統原生 GUID,版本 1 可追蹤來源 |
| 微服務追蹤 ID、分散式日誌關聯 | UUID v4/v7 + W3C Trace Context | 標準化、可跨語言傳遞 |
uniqid() 當 UUID:uniqid() 僅微秒時間 + 進程 ID,極易碰撞,不具備全域唯一性。CHAR(36) 或 BINARY(16)(UUID_TO_BIN() / BIN_TO_UUID() 8.0+ 內建函數),PostgreSQL 使用原生 UUID 型別。