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

PHP 生成 UUID(通用唯一識別碼)完整實現:相容 RFC 4122 與 COM 元件兩種方案

     編輯:PHP 相關知識

UUID 基礎知識

UUID (Universally Unique Identifier) 是 128 位元識別碼,標準格式為 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(8-4-4-4-12,共 36 字元)。常見版本:

  • Version 1:時間戳 + MAC 位址(可追蹤機器,隱私風險)
  • Version 3/5:命名空間 + 名稱(MD5/SHA-1 雜湊,確定性)
  • Version 4:隨機/偽隨機(最常用,無追蹤性)
  • Version 6/7/8:新標準(時間有序、Unix 毫秒/納秒、自定義)

Microsoft 實作為 GUID,格式通常帶大括號:{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}。

方案一:原生 PHP 實現(Version 4 隨機,跨平台、無依賴)

<?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}

方案二:Windows COM 元件(僅限 Windows + PHP_COM_DOTNET 擴展)

<?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/uuidcomposer require ramsey/uuid支援 v1~v8、編碼/解碼、Doctrine/laravel 整合、最活躍維護
symfony/uidcomposer require symfony/uid輕量、原生 UUID 物件、Symfony 生態無縫整合
webonyx/graphql-phpcomposer 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,極易碰撞,不具備全域唯一性。
  • 資料庫主鍵慎用 UUID v4:隨機性導致 B+ 樹索引頻繁分裂、頁面碎片化。優先考慮 UUID v7、ULID、Snowflake ID 或有序 BIGINT。
  • 儲存格式:MySQL 使用 CHAR(36) 或 BINARY(16)(UUID_TO_BIN() / BIN_TO_UUID() 8.0+ 內建函數),PostgreSQL 使用原生 UUID 型別。
  • 大小寫:儲存統一小寫,顯示時按需轉大寫,避免比較錯誤。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved