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,
// [email protected]
// 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).’-‘

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

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

An example of the output….


5 Responses

  1. 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. 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. Hello,

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


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


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

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

Comments are closed.