symfony/uid
Symfony UID component offers an object-oriented API to generate and work with unique identifiers. Includes ULIDs and UUIDs (v1 and v3–v8), with implementations compatible with both 32-bit and 64-bit systems for consistent, portable IDs.
Installation:
composer require symfony/uid
Add to composer.json under require:
"symfony/uid": "^8.0"
First Use Case: Generate a UUIDv7 (time-ordered) for a new model record:
use Symfony\Uid\Uuid;
use Symfony\Uid\UuidFactory;
$uuidFactory = UuidFactory::v7();
$uuid = $uuidFactory->generate();
// Outputs: e.g., "018a0f34-75a3-7e4d-9b2a-000000000001" (RFC 4122)
Where to Look First:
src/Uid/ in the source code for implementation details.UuidFactory class for generating different UUID versions (v1, v4, v7, v8, ULID).Use traits or accessors to generate UIDs for Eloquent models:
use Symfony\Uid\Uuid;
use Symfony\Uid\Traits\UuidTrait;
class Post extends Model
{
use UuidTrait;
protected $keyType = 'string';
public $incrementing = false;
protected $casts = [
'id' => 'string',
];
protected static function boot()
{
static::creating(function ($model) {
$model->id = Uuid::v7()->toRfc9562();
});
}
}
Use UuidV7 for sortable, time-based IDs (e.g., logs, events):
$factory = UuidFactory::v7();
$eventId = $factory->generate(); // e.g., "018a0f34-75a3-7e4d-9b2a-000000000001"
// Sortable by timestamp: `018a0f34-75a3-7e4d-9b2a-000000000001` < `018a0f34-75a3-7e4d-9b2a-000000000002`
Encode UUIDs in BASE58 for compact, shareable links:
$uuid = Uuid::v4();
$shortUrl = route('share', ['id' => $uuid->toBase58()]);
// Outputs: e.g., `/share/2J...` (32 chars vs. 36 for hex)
Use MockUuidFactory for reproducible UUIDs in tests:
use Symfony\Uid\MockUuidFactory;
$mockFactory = new MockUuidFactory('2023-01-01 12:00:00');
$uuid = $mockFactory->generate(); // Always same UUID for timestamp
Store UUIDs efficiently in binary format (PostgreSQL/MySQL 8.0+):
// Migration
Schema::create('posts', function (Blueprint $table) {
$table->binary('id')->primary(); // Stores UUID in 16 bytes
$table->string('title');
$table->timestamps();
});
Service Provider Binding:
Bind UuidFactory in AppServiceProvider for dependency injection:
public function register()
{
$this->app->singleton(UuidFactory::class, function () {
return UuidFactory::v7(); // Default to time-ordered UUIDs
});
}
API Responses: Serialize UUIDs in JSON API responses:
use Symfony\Component\Serializer\Normalizer\UidNormalizer;
$normalizer = new UidNormalizer();
$serialized = $normalizer->normalize($uuid, null, ['format' => 'rfc9562']);
// Outputs: "018a0f3475a37e4d9b2a000000000001" (compact, no hyphens)
Validation: Validate UUIDs in Form Requests:
use Symfony\Component\Uid\Uuid;
public function rules()
{
return [
'uuid' => ['required', function ($attribute, $value, $fail) {
if (!Uuid::isValid($value)) {
$fail('The '.$attribute.' must be a valid UUID.');
}
}],
];
}
UuidFactory instances (e.g., singleton) to avoid regeneration overhead.BINARY(16) in databases to reduce storage and improve indexing.$factory = UuidFactory::v7();
$uids = array_map(fn() => $factory->generate(), range(1, 1000));
UUIDv1 Clock Skew:
UuidV7 (time-ordered but skew-resistant) or UuidV4 (random).Case Sensitivity:
strtolower() if needed:$uuid = Uuid::v1()->toRfc4122(); // Ensure lowercase for consistency
ULID vs. UUID:
MockUuidFactory Limitations:
UuidV7 (not other versions). For testing UuidV4, use a custom mock:$mockUuid = new Uuid('00000000-0000-0000-0000-000000000001', Uuid::V4);
Database Indexing:
BINARY(16)) index faster than strings (CHAR(36)), but some ORMs (e.g., Eloquent) may not handle them out of the box.spatie/laravel-uuid.PHP Extensions:
UuidV7) rely on ext-ds (Data Structures). Ensure it’s installed:pecl install ds
Invalid UUIDs:
Uuid::isValid($string) to validate manually:if (!Uuid::isValid($input)) {
throw new \InvalidArgumentException('Invalid UUID format.');
}
Time-Based UUIDs:
UuidV7 generation with:$factory = UuidFactory::v7();
$uuid = $factory->generate();
$timestamp = $uuid->getTimestamp(); // Extract Unix timestamp
Performance Bottlenecks:
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$uuid = Uuid::v7();
}
$time = microtime(true) - $start; // Should be < 100ms for 10K UIDs
Custom UUID Versions:
Extend AbstractUuid to create domain-specific UUIDs:
class CustomUuid extends AbstractUuid
{
public static function generate(): static
{
return new self(self::generateRandomBytes());
}
}
Additional Encodings:
Add custom encoders (e.g., BASE64URL) by extending UidEncoder:
class
How can I help you explore Laravel packages today?