Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Uid Laravel Package

symfony/uid

Symfony UID provides an object-oriented API for generating and representing unique identifiers, with implementations for ULIDs and UUID v1 and v3 through v8 that work on both 32-bit and 64-bit CPUs.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Seamless Laravel Integration: Symfony’s UID component is Symfony-agnostic but Laravel-compatible, leveraging Laravel’s service container, validation, and serialization (e.g., Illuminate\Contracts\Container\BindingResolutionException compatibility). Ideal for:
    • Domain-driven design (DDD): Use UuidInterface/UlidInterface as value objects in entities (e.g., User::id() returns UuidV7).
    • API Platforms: Works natively with API Resources, JSON:API, or GraphQL (via Symfony\Component\Serializer).
    • Event Sourcing: Time-ordered UUIDv7 enables chronological event replay without manual timestamps.
  • Database Agnostic: Supports binary storage (PostgreSQL UUID, MySQL BINARY(16)), string storage (RFC 4122/9562), and BASE_58 for compactness. Avoids vendor lock-in.
  • Microservices Alignment: Distributed ID generation (no database dependencies) aligns with event-driven architectures (e.g., Kafka, RabbitMQ).
  • Change in v8.1.9 (patch): one correctness fix — time-based UUIDs generated from pre-1970 dates with fractional seconds now carry the correct date (bug #66834). No architectural impact, no API surface change, no deprecations. Architecture fit is unchanged; the fix only closes an edge case relevant to historical/archival backdating.
  • Cumulative picture across 8.1.8 → 8.1.9: four correctness fixes, all in the same defect class (time/validation correctness in ID generation). The component is converging on correctness rather than accumulating caveats, which strengthens the case for adopting it as the platform-wide ID layer.

Integration Feasibility

  • Zero Laravel-Specific Dependencies: Pure PHP 8.1+ (v7.4+) or 8.4+ (v8.0+), with no framework assumptions. Integrates via:
    • Service Provider: Bind UidFactoryInterface to UuidV7Factory (default) or UlidFactory in AppServiceProvider.
    • Eloquent Models: Replace protected $incrementing = true with protected $keyType = 'string' and cast id to UuidInterface.
    • Validation: Use Uuid::isValid() / Ulid::isValid(), or Laravel’s UuidValidator (via symfony/validator). v8.1.8 tightened Ulid::isValid() — base-58 inputs exceeding 2^128 that were previously accepted now correctly fail.
    • API Responses: Serialize to RFC_9562 (camelCase) or BASE_58 for compact payloads.
  • Version Target: Pin to ^8.1.9 rather than ^8.1.8 or ^8.0.9. The 8.0 → 8.1 minor boundary carries only correctness fixes per the published changelog; treat adoption as low-risk patch-level. There is no reason to remain on 8.1.8 — v8.1.9 supersedes it with no trade-off.
  • Migration Path:
    1. Phase 0 — Patch Adoption (0.5–1 day): Upgrade to v8.1.9, run full test suite, re-run ID validation and ordering regression suites plus a pre-1970 timestamp fixture check (see Operational Impact).
    2. Phase 1: Replace Ramsey\Uuid\Uuid with Symfony\Uid\Uuid in new features.
    3. Phase 2: Add UuidInterface to existing models via trait or abstract class.
    4. Phase 3: Update database schema (e.g., ALTER TABLE users MODIFY id BINARY(16)).
    5. Phase 4: Replace custom UUID logic (e.g., Str::uuid()) with UidFactory.

Technical Risk

Risk Area Mitigation Strategy Impact Assessment
Backward Compatibility Use abstract base classes (e.g., AbstractUuidModel) to wrap legacy IDs during migration. v8.1.9 introduces no deprecations or signature changes. Low
Performance Overhead Benchmark UuidV7 vs. Ulid generation (both <100ns on x64). Binary storage in DB reduces I/O by 20–30%. v8.1.9 has no measurable perf delta. Negligible
Clock Skew (UUIDv7) Fixed in v8.1.8 (bug #66246): UuidV7 ordering now holds when the system clock goes backwards. Remaining exposure is cross-host skew during multi-region generation — retain NTP-synchronized clocks or use ULIDs (monotonic) where strict global ordering matters. Low (was Medium)
Pre-1970 Time-Based Derivation Fixed in v8.1.9 (bug #66834): time-based UUIDs (v1/v6/v7) built from a date before 1970 with a fractional second previously produced an incorrect embedded timestamp. Only relevant if you generate IDs from supplied/backdated dates (archival imports, historical record backfills, legacy system replays) rather than from now(). Audit and re-derive any such IDs written under 8.1.8. Low (Medium if backdating)
Validation Tightening (Ulid) v8.1.8 (bug #66253): Ulid::isValid() no longer accepts base-58 strings above 2^128. Audit inbound payloads and any lax validation gates; backfill/repair any persisted IDs that only passed under the old behaviour. Medium (one-time audit)
Mixed-Type Comparison v8.1.8 (bug #66247): comparing a Uuid with a Ulid now behaves correctly. Audit dedupe/merge/sort logic in any environment where both types coexist (i.e. during phased migration). Low–Medium (audit)
Deterministic Test Fixtures IDs derived from pre-1970 or clock-regressed timestamps may differ from prior versions. MockUuidFactory fixtures are unaffected; only hardcoded “expected generated value” assertions need review. Low
Testing Complexity Use MockUuidFactory for deterministic UUIDs in CI/CD. Add one fixture per time-based regression fix (clock rollback, pre-1970 fractional second). Low
Database Schema Changes Binary storage (PostgreSQL/MySQL 8.0+) is recommended for performance. Fallback to CHAR(36) if needed. Medium (one-time cost)
Team Adoption Provide Laravel-specific examples (e.g., UuidModel, UlidModel traits) and migration scripts. Low (if documented well)

Key Questions

  1. Database Strategy:
    • Are you using PostgreSQL/MySQL 8.0+ (supports BINARY(16))? If not, will CHAR(36) suffice?
    • Do you need time-ordered queries (UUIDv7/ULID) or randomness (UUIDv4)?
  2. ID Format Preference:
    • Should new IDs use UUIDv7 (time-ordered, clock-regression safe), ULID (monotonic), or UUIDv4 (random)?
    • Do you need BASE_58 for URL-shortening (e.g., /share/2J...)?
  3. Upgrade Exposure to v8.1.9:
    • Do you generate time-based UUIDs from a supplied date rather than now() (backfills, archival replay, import of legacy records)? If so, do any of those dates precede 1970-01-01 with fractional-second precision?
    • Do you have inbound endpoints or importers that call Ulid::isValid()? If so, do any currently-accepted payloads exceed 2^128 in base-58 form?
    • Does any code compare or sort mixed Uuid/Ulid collections (dedupe sets, merge scripts, reconciliation jobs)?
    • Does any consumer rely on UUIDv7 ordering where the host clock has historically stepped backwards (VMs, containers, edge nodes)?
  4. Migration Timeline:
    • Can you opt-in to UID per model (gradual adoption) or big-bang replace?
    • Are there legacy systems (e.g., PHP <8.1) that can’t upgrade?
  5. Testing Requirements:
    • Do you need reproducible UUIDs in CI/CD (use MockUuidFactory)?
    • Are there flaky tests related to UUID generation, clock-sensitive ordering, or historical date fixtures?
  6. Compliance Needs:
    • Do sequential IDs pose privacy risks (e.g., user count exposure)?
    • Are you subject to GDPR/CCPA/HIPAA where anonymization is critical?
    • If you derive IDs from dates (e.g., date-of-birth-adjacent schemes), confirm that isn't leaking personal data — independent of this patch.

Integration Approach

Stack Fit

Laravel Component Integration Strategy Example Implementation
Eloquent Models Replace $incrementing = true with $keyType = 'string' and cast id to UuidInterface. Use UuidModel trait for boilerplate. ```phpuse Symfony\Uid\Uuid;use Symfony\Uid\AbstractUuid;class User extends Model { protected $keyType = 'string'; protected $casts = [ 'id' => Uuid::class, ]; public function getRouteKey(): string { return $this->id->toRfc9562(); }}
API Responses Serialize to RFC_9562 (camelCase) or BASE_58 for compactness. Use Symfony\Component\Serializer or Laravel’s JsonSerializable. ```phpreturn response()->json([ 'id' => $user->id->toRfc9562(), 'name' => $user->name,]);
Validation Use Uuid::isValid() / Ulid::isValid(), or Laravel’s UuidValidator (via symfony/validator). On v8.1.8+, Ulid::isValid() rejects base-58 values above 2^128 — re-baseline any custom rules built on the old behaviour. ```phpuse Symfony\Component\Validator\Constraints as Assert;class CreateUserRequest { #[Assert\Uuid] public string $externalId;}
Database Schema Prefer BINARY(16) for UUIDs/ULIDs (PostgreSQL/MySQL 8.0+). Fallback to CHAR(36) if needed. ```sqlALTER TABLE users MODIFY id BINARY(16);-- or --ALTER TABLE users MODIFY id CHAR(36) CHARACTER SET ascii COLLATE ascii_bin;
Event Sourcing Use UuidV7 for time-ordered events. Ordering is stable under clock regression (v8.1.8); backdated events now carry the correct embedded timestamp (v8.1.9). Store as binary in DB for efficiency. ```phpclass OrderCreated { public UuidV7 $orderId; public Carbon $occurredOn;}
Backdated / Imported Records If replaying historical data, derive IDs after upgrading to v8.1.9, or use MockUuidFactory-style deterministic derivation so the same source date always yields the same ID. Verify embedded timestamps round-trip. ```php$id = UuidV7::fromDateTime( new \DateTimeImmutable('1965-04-11 12:00:00.250'));$id->getDateTime(); // assert correct
Mixed ID Handling When Uuid and Ulid coexist (mid-migration), comparison semantics are correct as of v8.1.8. Still normalize to a single type at boundaries to avoid ambiguity. ```php$a = Uuid::fromString($x);$b = Ulid::fromString($y);// convert before compare$a->equals(Uuid::fromString($b->toRfc9562()));
Testing Use MockUuidFactory for deterministic UUIDs in CI/CD. Add regression coverage for Ulid validation bounds, clock-regression ordering, and pre-1970 fractional-second date derivation. ```php$factory = new MockUuidFactory('123e4567-e89b-12d3-a456-426614174000');$user = new User();$user->id = $factory->generate();

Migration Path

  1. Patch Adoption Phase (0.5–1 day):
    • Bump symfony/uid to ^8.1.9; confirm no other Symfony packages are pinned below the 8.1 line.
    • Run the full suite plus targeted regressions: Ulid validation boundary cases, mixed Uuid/Ulid comparisons, UUIDv7 ordering under simulated clock rollback, and time-based UUID derivation from a pre-1970 date with fractional seconds.
    • Grep for fromDateTime / date-supplied generation call sites and confirm none run in a hot path requiring re-derivation.
  2. Assessment Phase (1–2 weeks):
    • Audit existing UUID usage (e.g., Ramsey\Uuid, custom logic, Str::uuid()).
    • Grep for Ulid::isValid() call sites and any persisted base-58 IDs; reconcile against the tightened rule.
    • Identify any backdated ID generation (imports, replays, archival) and whether generated values must be re-derived.
    • Decide on ID strategy (UUIDv7/ULID/UUIDv4) and storage format (binary/string).
    • Update database schema (if needed) in a non-breaking migration.
  3. Opt-In Phase (2–4 weeks):
    • Create UuidModel/UlidModel traits for new models.
    • Replace Ramsey\Uuid with Symfony\Uid in new features.
    • Add validation and serialization layers.
  4. Gradual Replacement (4–8 weeks):
    • Update existing models via trait or abstract class.
    • Replace custom UUID generation with UidFactory bindings.
    • Normalize mixed-type collections at service boundaries; backfill binary columns.
  5. Cutover & Cleanup (1–2 weeks):
    • Remove Ramsey\Uuid and legacy Str::uuid() usages.
    • Convert string columns to binary where the performance case is proven.
    • Retire wrapper shims; publish internal conventions doc.

Operational Impact

Maintenance

  • v8.1.9 is a single-fix patch on an active minor line — effectively a one-line correctness change with no surface area. Adoption cost is a composer bump plus a test run; merge risk is near zero.
  • v8.1.9 supersedes v8.1.8 entirely — no reason to stage 8.1.8 first unless a branch is already mid-flight. Roll both fixes in one bump.
  • Ongoing cadence is the standard Symfony release train. Budget roughly one patch adoption per quarter with a half-day regression pass, weighted toward ID validation and time-derivation tests.
  • Pin to ^8.1.9 and let the constraint float within the minor; avoid * so that intentional review happens at minor boundaries.

Support

  • No vendor support contract; support is community-driven (GitHub issues, Symfony docs). Internal ownership sits with the platform/backend team.
  • All four fixes across 8.1.8 and 8.1.9 were upstream-reported and upstream-fixed within the patch line — a positive responsiveness signal, and a concrete reason to stay current rather than pinning to 8.0.x.
  • The 8.1.9 fix originates from the component maintainer (@nicolas-grekas), which is a strong indicator of regression-test coverage on the time-based path going forward.
  • Document the internal binding conventions (UidFactoryInterface → UuidV7Factory) so support load doesn’t concentrate on one engineer.

Scaling

  • No scaling characteristics change: generation remains client-side, DB-independent, and sub-microsecond.
  • UUIDv7 ordering under clock rollback is correct (8.1.8), removing a source of index fragmentation and out-of-order event replay on hosts with unstable clocks (containers, VM live-migration, edge nodes).
  • Backdated generation is now faithful (8.1.9) — relevant for bulk historical imports where ID ordering is used as a proxy for event ordering. Previously, pre-1970 fractional-second dates could produce IDs that sorted incorrectly relative to their true dates, which would have skewed index locality and replay order in archival partitions.
  • Binary storage remains the recommended path for 20–30% I/O reduction at volume; plan the column conversion after the patch is in production, not before.

Failure Modes

Failure Mode Trigger Detection Response
Validation regression (422s) Endpoints using Ulid::isValid() receive base-58 values above 2^128 that previously passed Spike in 4xx on ingest endpoints post-deploy Expected/correct behaviour; fix the client or reject the record. Pre-audit before upgrading to avoid surprise.
Persisted invalid ULIDs Rows written while the loose validation was in effect Data audit query on ULID columns; length/charset checks Backfill or quarantine affected rows; do not relax validation to compensate.
Mixed compare/sort drift Dedupe or reconciliation jobs comparing Uuid against Ulid Diff in dedupe counts, duplicate-key errors, reconciliation mismatches Fixed in 8.1.8 (bug #66247); re-run affected jobs to confirm outputs converge.
UUIDv7 ordering surprise Clock steps backwards on a generating host Out-of-order event sequences, index hot spots Fixed in 8.1.8 (bug #66246) within-process; cross-host skew still requires NTP or ULID.
Misdating on backdated IDs Time-based UUID generated from a pre-1970 date with fractional seconds on v8.1.8 Embedded timestamp round-trip mismatch; archival events sorting before their true date Fixed in 8.1.9 (bug #66834). Re-derive affected IDs if immutability allows; otherwise record a correction mapping and exclude from ordering assumptions.
Test fixture breakage Hardcoded expectations of generated IDs in clock-regression or pre-1970 date scenarios CI failures scoped to ID-ordering/date tests Move to MockUuidFactory fixtures; assert ordering and date properties, not literal values.
Partial upgrade symfony/uid 8.1.x alongside other Symfony packages pinned to 8.0.x Composer resolution conflicts or runtime ClassNotFound Align the Symfony package set before upgrading; stage in a branch.

Ramp-up

  • Engineer ramp-up remains ~1–2 days for teams already familiar with UUIDs; the component’s API is small and well-documented.
  • Add a short upgrade note to the internal runbook covering the four behaviour changes from 8.1.8–8.1.9 — this is the only new ramp-up material required. v8.1.9 adds one line: “time-based UUIDs from dates before 1970 are now correctly dated.”
  • Reviewers/QA need two checks in the release checklist: “Ulid validation and UUIDv7 ordering regression suite green” and “pre-1970 fractional-second date derivation fixture green.”
  • If the team is mid-migration (mixed Uuid/Ulid in production), allocate an extra half-day for a mixed-type comparison audit; this is the highest-value use of time in the upgrade. If the team imports historical data, allocate a similar half-day to confirm no IDs were derived from pre-1970 dates under 8.1.8.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource