Skip to content

Identifiers

Identifiers provide unique identity for entities through the IdInterface contract. Multiple implementations support different use cases.

Why Use Typed Identifiers

Raw strings or integers as entity IDs lose type safety and domain meaning. Typed identifiers:

  • Prevent accidental ID swaps between entities (a BookId cannot be used where a UserId is expected)
  • Provide consistent comparison via equals()
  • Support different ID formats through a unified interface

Usage

// Reconstruct from stored value
$bookId = UuidV7::from('019aab5a-19a5-701c-8a23-d5379acbf015');

// Compare identifiers
$bookId->equals($otherBookId);

// Get underlying value for persistence
$bookId->getValue();

// String conversion
(string) $bookId;  // '019aab5a-19a5-701c-8a23-d5379acbf015'

Available Implementations

Type Format Sortable Use Case
UuidV7 36 chars Yes Production default
UuidV4 36 chars No Distributed systems, no ordering needed
Ulid 26 chars Yes Public APIs, compact URLs
TimestampId Integer Yes Development, testing

Timestamp-prefixed UUID providing chronological ordering for better database index performance:

$id = UuidV7::from('019aab5a-19a5-701c-8a23-d5379acbf015');

Ulid

Compact Base32 Crockford encoding, URL-safe:

$id = Ulid::from('01JQXMP8BS0HT8EVCP1T7DN81R');

TimestampId

Integer-based identifier for simple scenarios:

$id = TimestampId::from(1234567890123456);
$id->getValue();  // int

Relation with IdGenerator Plugin

IdInterface types represent existing identifiers (domain layer). The ID Generator plugin creates new identifiers (infrastructure layer).

// Generate new ID (infrastructure)
$id = $this->idGenerator->generate();

// Use ID in entity (domain)
$book = new Book(id: $id, ...);

See Also