How to create a MongoDB ObjectID from a timestamp using PHP

This is a useful tidbit of code to have until PHP adds this feature into their MongoDB extension. I stumbled on an example on Stack Overflow illustration showing how to do this and rewrote it in what I think is a slightly more modern way that does the same thing.

ObjectId’s are constructed using a 4-byte timestamp value, 3-byte machine identifier, 2-byte process id, and a 3-byte counter which create a 12-byte BSON type:


 --------------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---------------|-----------|-------|--------------|
| time          | machine   | pid   | counter      |
 --------------------------------------------------

Knowing that makes this PHP code easy to understand:

MongoUtil:

/**
 * Class MongoUtil.
 */
class MongoUtil {

    /**
     * This is needed to keep documents unique that have the same timestamp.
     * @var integer
     * @see $timestamp
     */
    public static $_mongoIdFromTimestampCounter = 0;

    /**
     * Mongo Id From Timestamp
     * @param integer $timestamp
     * @return MongoID
     * @see http://docs.mongodb.org/manual/reference/object-id/
     */
    public static function mongoIdFromTimestamp( $timestamp ) {
        // Build Binary Id
        $binaryTimestamp = pack('N', $timestamp); // unsigned long
        $machineId = substr(md5(gethostname()), 0, 3); // 3 bit machine identifier
        $binaryPID = pack('n', posix_getpid()); // unsigned short
        $counter = substr(pack('N', self::$_mongoIdFromTimestampCounter++), 1, 3); // Counter
        $binaryId = "{$binTimestamp}{$machineId}{$machineId}{$counter}";

        // Convert to ASCII
        $id = '';
        for ($i = 0; $i < 12; $i++) {
            $id .= sprintf("%02X", ord($binaryId[$i]));
        }

        // Return Mongo ID
        return new MongoID($id);
    }

}

Example of usage:

$date = strtotime('today');
$mongoId = MongoUtil::mongoIdFromTimestamp( $date );

// Do more stuff.
Mar 31, 2014 Programming