UUID / GUID in native PHP…

In the course of my development efforts it has become fairly clear that I need to make use of a more cross platform and cross server identifier for certain content objects. The common tactic of using a database column that automatically increments has fallen pretty flat for this – it is almost guaranteed to collide if you try and merge tables or data in the future. The code is below the fold!

Microsoft databases have the concept of a [[wp;GUID]]  that they implement in a nice simple manner and that is supported well in .NET.Nothing similar exists in MySQL and PHP at the moment, though some tantalizing hints existed. Long and short of it, I solved the problem, or at least I have an early attempt at solving the problem. Compare it to the numbers you can get at this online UUID generator.

This code is a combination of…

So enjoy it, and please [[let me know]] if I missed anything! BOh, and a CHAR(32) in MySQL is a good place to store these.

// -_-_–_-_–_-_–_-_—

// build a UUID or GUID via PHP
// may or may not be Microsoft GUID compatible
// thanks to all the internet code examples!
//
// contact me with corrections and changes please,
// soulhuntre@soulhuntre.com
//
// 10/29/2004 – v1.0
//
// Do whatever you want with this code, it’s in the public domain

$rawid = strtoupper(md5(uniqid(rand(), true)));
$workid = $rawid;

// hopefully conform to the spec, mark this as a “random” type
// lets handle the version byte as a number
$byte = hexdec( substr($workid,12,2) );
$byte = $byte & hexdec(“0f”);
$byte = $byte | hexdec(“40″);
$workid = substr_replace($workid, strtoupper(dechex($byte)), 12, 2);

// hopefully conform to the spec, mark this common variant
// lets handle the “variant”
$byte = hexdec( substr($workid,16,2) );
$byte = $byte & hexdec(“3f”);
$byte = $byte | hexdec(“80″);
$workid = substr_replace($workid, strtoupper(dechex($byte)), 16, 2);

// build a human readable version
$rid = substr($rawid, 0, 8).’-’
    .substr($rawid, 8, 4).’-’
    .substr($rawid,12, 4).’-’
    .substr($rawid,16, 4).’-’
    .substr($rawid,20,12);

// build a human readable version
$wid = substr($workid, 0, 8).’-’
    .substr($workid, 8, 4).’-’
    .substr($workid,12, 4).’-’
    .substr($workid,16, 4).’-’
    .substr($workid,20,12);

// -_-_–_-_–_-_–_-_—

An example of the output….

A2C2817A-F2CE-49B1-BF4C-DB0961998E2A
9BCF2CD8-A5E5-4331-BD71-491804CE6ED6
575D3B15-19ED-4A50-A773-0FFD3631F391
AF457D46-7BF6-4F7F-B718-47EAD9FCD47E
8138B63D-0CC1-4E35-8641-A67FF0D3486D
6F4AD196-45FD-4B4D-88F7-68F9C009365C
930ED1AB-4335-4DF2-AB05-DFFC3E349295
B6097E8A-3CAD-492B-9DB9-59697AE97BA6
7944D65B-82DB-4946-81F5-D6527227D422
15BC5F60-B731-4C0B-9F88-8C71F1196FE1

5 Responses to UUID / GUID in native PHP…

  1. Joshua Giese September 7, 2006 at 19:09 #

    Thanks for putting this together. I was looking for some GUID support for php. Its a shame that its not part of the core. You think something like this would be needed by enough people to consider it

  2. Martijn Kruithof February 7, 2007 at 17:55 #

    The sites referred to a http://kruithof.xs4all.nl/uuid/uuidgen and http://kruithof.xs4all.nl/guid-uuid-random.html have been moved to
    http://www.famkruithof.net/uuid/uuidgen (and http://www.famkruithof.net/guid-uuid-random.html)

    While the old version of the page was written as a Java Servlet the new version has completely been rewritten in PHP. I have chosen a somewhat different approach for the generation of the random positions, by plainly generating multiple random numbers, each responsible for part of the string.

  3. Carlos Averett April 15, 2007 at 11:17 #

    Hello,

    I used your code as a basis for a UUID class in the framework I’m writing.

    http://coreforge.org/snippet/detail.php?type=snippet&id=3

    I actually use them as both session ids, and encryption keys for the session handler:

    http://coreforge.org/snippet/detail.php?type=snippet&id=1

    As for storing them, I use a postgres domain to hold them:

    CREATE DOMAIN “UUID” AS character(38) DEFAULT ‘{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}’::bpchar
    CONSTRAINT “UUID_check” CHECK ((VALUE ~ ‘^{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}}$’::text));

    They are stored in between brackets, similar to how Windows does it.

  4. gasper_k January 14, 2008 at 05:31 #

    There is a native extension that provides the same functionality I believe: http://pecl.php.net/package/uuid. It uses libuuid, which is a sort-of-a-standard library for uuids. If speed is important, I think this is a good choice.

  5. Jeffery July 15, 2008 at 01:57 #

    Martijn,

    How easy would it be to make a “Time-based UUID” following your example shown above? I believe they are version 1 uuid’s?

Leave a Reply