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…
- some code I found on usenet that handles output formatting
- code in the comments of the uniqid and md5 man pages
- some info from the specification for [[wp:uuid]] numbers
- the how to guide found here
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).’-‘
.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
Comments
5 responses to “UUID / GUID in native PHP…”
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
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.
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.
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.
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?