Universal Unique Identifier (OUID) implementation for OrdinaryPHP.
composer require ordinary/uid- PHP 8.5 or higher
- Time-based: Includes timestamp with microsecond precision
- Namespaced: Support for custom namespaces
- Sortable: Chronologically sortable by design
- Compact: Uses Crockford Base32 encoding for efficiency
- Type-safe: Full PHP 8.5 type safety with property hooks
<namespace>-<time-seconds><time-microsecond>-<random-bytes>
Example: MYAPP-01J4K6M-8P0A-XYZW1234
- namespace: Alphanumeric uppercase and underscore (e.g.,
MYAPP,MY_APP_123) - time-seconds: Crockford Base32 encoded Unix timestamp (7 chars, supports 100+ years)
- time-microsecond: Crockford Base32 encoded microseconds (4 chars, 0-999999)
- random-bytes: Crockford Base32 encoded random bytes (4 bytes)
useOrdinary\Uid\Ouid;
useOrdinary\Uid\OuidGenerator;
usePsr\Clock\ClockInterface;
// Using the generator (recommended)$clock = newYourClockImplementation(); // PSR-20 Clock$generator = newOuidGenerator('MYAPP', $clock);
$ouid = $generator->generate();
// Manual creation$ouid = Ouid::create(
'MYAPP',
newDateTimeImmutable('now', newDateTimeZone('UTC')),
random_bytes(4)
);
// From string$ouid = Ouid::fromString('MYAPP-01J4K6M-8P0A-XYZW1234');
// NIL OUID$nil = Ouid::nil();$ouid = $generator->generate();
echo$ouid->value; // Full OUID stringecho$ouid->namespace; // "MYAPP"echo$ouid->datetime->format('Y-m-d H:i:s.u'); // Timestamp with microsecondsechobin2hex($ouid->randomBytes); // Random bytes as hexOUIDs can be embedded in value objects using property hooks for clean, type-safe access:
useOrdinary\Uid\HasOuid;
useOrdinary\Uid\HasOuidTrait;
useOrdinary\Uid\HasMutableOuid;
useOrdinary\Uid\HasMutableOuidTrait;
// Immutable OUID (can only be set once)class User implements HasOuid
{
use HasOuidTrait;
publicfunction__construct(Ouid$ouid)
{
$this->uid = $ouid->value; // Set via property
}
}
// Mutable OUID (can be changed anytime)class DraftPost implements HasMutableOuid
{
use HasMutableOuidTrait;
}
// Usage$user = newUser($generator->generate());
echo$user->uid; // String valueecho$user->getOuid()->value; // Ouid object$draft = newDraftPost();
$draft->uid = $generator->generate()->value;
echo$draft->getOuid()->namespace;useRandom\Engine\Xoshiro256StarStar;
usePsr\Clock\ClockInterface;
useDateTimeImmutable;
// Fixed clock for testing$clock = newclassimplements ClockInterface {
publicfunctionnow(): DateTimeImmutable {
returnnewDateTimeImmutable('2024-01-01 12:00:00');
}
};
$engine = newXoshiro256StarStar(12345); // Fixed seed$generator = newOuidGenerator('TEST', $clock, $engine);
$ouid1 = $generator->generate();
$ouid2 = $generator->generate();
// Different random bytes but deterministic sequenceThis package uses Crockford Base32 encoding:
- Character set:
0-9,A-Z(excludingI,L,O,U) - Case-insensitive decoding
- Symbol equivalents:
O/o→0,I/i/L/l→1
useOrdinary\Uid\CrockfordBase32;
$encoded = CrockfordBase32::encode(1234567);
$decoded = CrockfordBase32::decode($encoded);
$bytesEncoded = CrockfordBase32::encodeBytes("\x01\x02\x03\x04");
$bytesDecoded = CrockfordBase32::decodeBytes($bytesEncoded, 4);vendor/bin/phpunitMIT