Location: PHPKode > projects > PIMF > pimf-master/core/Pimf/Util/Uuid.php
<?php
/**
 * Pimf_Util
 *
 * PHP Version 5
 *
 * A comprehensive collection of PHP utility classes and functions
 * that developers find themselves using regularly when writing web applications.
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.
 * It is also available through the world-wide-web at this URL:
 * http://krsteski.de/new-bsd-license/
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to hide@address.com so we can send you a copy immediately.
 *
 * @copyright Copyright (c) 2010-2011 Gjero Krsteski (http://krsteski.de)
 * @license http://krsteski.de/new-bsd-license New BSD License
 */

/**
 * A class that generates RFC 4122 UUIDs
 *
 * <pre>
 * This specification defines a Uniform Resource Name namespace for
 * UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally
 * Unique IDentifier).  A UUID is 128 bits long, and requires no central
 * registration process.
 * </pre>
 *
 * @package Pimf_Util
 * @author Gjero Krsteski <hide@address.com>
 * @see http://www.ietf.org/rfc/rfc4122.txt
 */
final class Pimf_Util_Uuid
{
  /**
   * 32-bit integer that identifies this host.
   * @var integer
   */
  private static $node = null;

  /**
   * Process identifier.
   * @var integer
   */
  private static $pid  = null;

  /**
   * Returns a 32-bit integer that identifies this host.
   *
   * The node identifier needs to be unique among nodes
   * in a cluster for a given application in order to
   * avoid collisions between generated identifiers.
   *
   * @return integer
   */
  private static function getNodeId()
  {
    $ip       = null;
    $hostname = null;

    if (true === isset($_SERVER['SERVER_ADDR'])) {
        $ip = $_SERVER['SERVER_ADDR'];
    }

    if ($ip === null && true === function_exists('gethostname')) {
        $hostname = gethostname();
        $ip       = gethostbyname($hostname);
    }

    if ($ip === null && true === function_exists('php_uname')) {
        $hostname = php_uname('n');
        $ip       = gethostbyname($hostname);
    }

    if ($ip === null && $hostname !== null) {
        $ip = crc32($hostname);
    }

    if ($ip === null) {
        $ip = '127.0.0.1';
    }

    return ip2long($ip);
  }

  /**
   * Returns a process identifier.
   *
   * In multi-process servers, this should be the system process ID.
   * In multi-threaded servers, this should be some unique ID to
   * prevent two threads from generating precisely the same UUID
   * at the same time.
   *
   * @return integer
   */
  private static function getLockId()
  {
    return getmypid();
  }

  /**
   * Generate an RFC 4122 UUID.
   *
   * This is pseudo-random UUID influenced by the system clock, IP
   * address and process ID.
   *
   * The intended use is to generate an identifier that can uniquely
   * identify user generated posts, comments etc. made to a website.
   * This generation process should be sufficient to avoid collisions
   * between nodes in a cluster, and between apache children on the
   * same host.
   *
   * @return string
   */
  public static function generate()
  {
    if (self::$node === null) {
        self::$node = self::getNodeId();
    }

    if (self::$pid === null) {
        self::$pid = self::getLockId();
    }

    list($time_mid, $time_lo) = explode(' ', microtime());

    $time_low = (int)$time_lo;
    $time_mid = (int)substr($time_mid, 2);

    $time_high_and_version = mt_rand(0, 0xfff);
    /* version 4 UUID */
    $time_high_and_version |= 0x4000;

    $clock_seq_low = mt_rand(0, 0xff);

    /* type is pseudo-random */
    $clock_seq_high  = mt_rand(0, 0x3f);
    $clock_seq_high |= 0x80;

    $node_low = self::$pid;
    $node     = self::$node;

    return sprintf(
        '%08x-%04x-%04x-%02x%02x-%04x%08x',
        $time_low, $time_mid & 0xffff, $time_high_and_version,
        $clock_seq_high, $clock_seq_low,
        $node_low, $node
    );
  }
}
Return current item: PIMF