PHP產生UUID的正確姿勢是?

來源:互聯網
上載者:User
網上搜尋,發現大體都類似如下:

        $chars = md5(uniqid(mt_rand(), true));        $uuid  = substr($chars,0,8) . '-';        $uuid .= substr($chars,8,4) . '-';        $uuid .= substr($chars,12,4) . '-';        $uuid .= substr($chars,16,4) . '-';        $uuid .= substr($chars,20,12);        return $prefix . $uuid;
            mt_srand ( ( double ) microtime () * 10000 ); //optional for php 4.2.0 and up.隨便數播種,4.2.0以後不需要了。            $charid = strtoupper ( md5 ( uniqid ( rand (), true ) ) ); //根據目前時間(微秒計)產生唯一id.            $hyphen = chr ( 45 );            $uuid = '' .                 substr ( $charid, 0, 8 ) . $hyphen . substr ( $charid, 8, 4 ) . $hyphen . substr ( $charid, 12, 4 ) . $hyphen . substr ( $charid, 16, 4 ) . $hyphen . substr ( $charid, 20, 12 );            return $uuid;

看了UUID的說明,怎麼感覺這些產生方法 撞擊率 達不到標準啊?

回複內容:

網上搜尋,發現大體都類似如下:

        $chars = md5(uniqid(mt_rand(), true));        $uuid  = substr($chars,0,8) . '-';        $uuid .= substr($chars,8,4) . '-';        $uuid .= substr($chars,12,4) . '-';        $uuid .= substr($chars,16,4) . '-';        $uuid .= substr($chars,20,12);        return $prefix . $uuid;
            mt_srand ( ( double ) microtime () * 10000 ); //optional for php 4.2.0 and up.隨便數播種,4.2.0以後不需要了。            $charid = strtoupper ( md5 ( uniqid ( rand (), true ) ) ); //根據目前時間(微秒計)產生唯一id.            $hyphen = chr ( 45 );            $uuid = '' .                 substr ( $charid, 0, 8 ) . $hyphen . substr ( $charid, 8, 4 ) . $hyphen . substr ( $charid, 12, 4 ) . $hyphen . substr ( $charid, 16, 4 ) . $hyphen . substr ( $charid, 20, 12 );            return $uuid;

看了UUID的說明,怎麼感覺這些產生方法 撞擊率 達不到標準啊?

目前很多所謂PHP產生UUID的方法都以隨機數最為其演算法的基礎,這雖然在實踐中很難出現重複的幾率,但在理論上顯然是行不通的。

這裡用MongoDb的ObjectId作為例子,個人覺得這種產生方法是可以引入到PHP中的。
ObjectId主要分為四塊:時間戳記、毫秒數、機器碼、自增計數。

前兩者就不用細說了,PHP都可以取到,重點在後兩者上。

機器碼主要用於避免在不同主機間產生相同的UUID。
機器碼目前主要的產生方法是根據硬體資訊進行散列計算出,而這個方法並不適用於PHP。
主要因為兩點,一是PHP不能直接獲得硬體資訊(需要通過擴充或者執行本地命令等方法),二是PHP請求與請求之間無法共用資料,所以每次請求都得拉取機器碼,對效能影響很大。
解決這一問題有個很簡單的辦法,就是在不同機器先計算出機器碼,之後直接寫入設定檔,PHP處理時直接讀取即可。

自增計數主要用於避免在並發處理中產生相同的UUID。
對於自增來說,PHP由於不能在請求間共用資料,所以不能直接實現自增計數。
解決這一問題我們可以引入PHP的兩個擴充,分別是Semaphore和Shared Memory,這兩者都在PHP源碼中整合,通過--enable-sysvsem和--enable-sysvshm就能開啟。我們只需要把自增數放置在共用記憶體中,再通過訊號量限制訪問,即可達到並發請求共用自增技術的目的了。當然,自增也能通過其他工具來實現。

Linux核心提供有UUID產生介面:
cat /proc/sys/kernel/random/uuid
Linux上一切皆檔案,不管什麼程式,讀取檔案就能擷取一個UUID.

自行產生一個唯一值:

php best.php

另外貌似用openssl_random_pseudo_bytes也能產生不錯的隨機串:

echo base64_encode(openssl_random_pseudo_bytes(32));
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.