View Source

<h2>Overview</h2>
<p>This RFC contains a proposal for implementing Universally Unique Identifier (UUID) in ZF2. Component will support <a href="http://tools.ietf.org/html/rfc4122">RFC 4122</a> UUIDs.</p>

<p>Component is partly implemented in <a href="https://github.com/denixport/zf2/tree/feature/uuid/library/Zend/Uuid">this feature branch</a> on GitHub.</p>

<h2>Scope of this Proposal</h2>
<h3>UUID Version 1 (time-based, MAC address)</h3>
<p>The original generation scheme for UUIDs. Generator uses Node ID (MAC address), timestamp, and clock sequense.</p>

<p>RFC 4122 requires stable state storage for generator, so every time new UUID is generated, state file is updated with timestamp and clock sequense used. Maintaining state file is out of the scope of this proposal so component will use system timestamp and random clock sequense.</p>

<h3>UUID Version 2 (time-based, DCE Security)</h3>
<p>Same as version 1, but clock sequense is replaced by the identifier for a &quot;local domain&quot;. This version will not be implemented in this proposal.</p>

<h3>UUID Version 3 (name-based, MD5 hash)</h3>
<p>Name based UUID uses a scheme deriving a UUID from a URL, FQDN, DN or any other namespace and some name.</p>

<h3>UUID Version 4 (random-based)</h3>
<p>This UUID is based on 128-bit random (or pseudo-random) number.</p>

<p>Because ver. 4 UUID is just a random number with few bits altered, generation could also be implemented in Rand component (<a href="http://framework.zend.com/wiki/x/HADTAg">see proposal here</a>) as <code>getUuid()</code> method.</p>

<h3>UUID Version 5 (name-based, SHA-1 hash)</h3>
<p>Same as ver.3 but uses SHA-1 hashing, so 160 bit SHA-1 hash is truncated to 128 bits to make the length work out.</p>

<h2>Proposed Class Structure</h2>
<p>Component is divided into UUID entity and UUID generator.</p>
<h3>Zend\Uuid\Uuid</h3>
<p>Immutable object representing UUID. Object is constructed with canonical UUID string. Methods include:</p>
<ul>
<li><code>getVersion()</code></li>
<li><code>getVariant()</code> - RFC 4122, Microsoft GUID etc</li>
<li><code>getTimestamp()</code> - returns false if not ver. 1 UUID</li>
<li><code>getClockSequense()</code> - false if not ver. 1</li>
<li><code>getNode()</code> - false if not ver. 1</li>
<li><code>isNil()</code> &ndash; Nil UUID is a special case of UUID with all bits set to zero</li>
<li><code>toString()</code> &ndash; get canonical string representation</li>
<li><code>isValid()</code> &ndash; according to RFC it's only possible to test ver.1 UUID for validity</li>
</ul>


<h3>Zend\Uuid\Generator</h3>
<p>Generates UUID instance based on version, node, namespace etc. Methods include:</p>
<ul>
<li><code>generate($version, $name_or_node, $namespace)</code></li>
<li><code>generateTimeBased($node)</code></li>
<li><code>generateNameBased($version, $name, $namespace)</code></li>
<li><code>generateRandomBased()</code></li>
</ul>


<h2>Questions</h2>
<ul>
<li><em>How UUID instance should be created?</em><br />
Should constructor expect canonical string only and different factory methods (or separate Factory class) to create instance from other types, or constructor could expect string, binary string, another UUID instace etc.</li>
<li><em>Should component consider possibility of using <a href="http://pecl.php.net/package/uuid">PECL extension</a>?</em><br />
This will require defining an interface and creating separate adapters. Also not sure if PECL extension is compatible with PHP 5.3.3</li>
<li><em>Should component maintain the generator state file for ver. 1 UUIDs?</em><br />
Ver.1 is not widely used, so probably adding state file capabilities will complicate things with no clear advantage.</li>
<li>Related question <em>Should generator expect user to provide timestamp and clock sequense vor ver.1 UUID, or it should use system time and random clock sequense?</em></li>
</ul>


<h2>References</h2>
<h3>Docs</h3>
<p><a href="http://tools.ietf.org/html/rfc4122">RFC 4122</a><br />
<a href="http://en.wikipedia.org/wiki/Universally_unique_identifier">Wikipedia entry</a></p>
<h3>Previous Proposals</h3>
<p><a href="http://framework.zend.com/wiki/x/WoBEAQ">http://framework.zend.com/wiki/x/WoBEAQ</a><br />
<a href="http://framework.zend.com/wiki/x/6oAxAQ">http://framework.zend.com/wiki/x/6oAxAQ</a><br />
<a href="http://framework.zend.com/wiki/x/nYAxAQ">http://framework.zend.com/wiki/x/nYAxAQ</a></p>