Skip to main content

Searching...

Tools
Articles
View All Results

Developer Lab · PHP

Generate UUID in PHP

ramsey/uuid is the PHP standard with 300M+ downloads - supports v4, v7, and v5. Laravel ships Str::uuid() built-in. PHP 7.2+ can also use the Symfony UID component.

Quick Reference

Method Version Sortable Use Case
Uuid::uuid4() v4 No General purpose - session IDs, record IDs, API keys
Uuid::uuid7() v7 Yes Database PKs, event logs - time-ordered
Uuid::uuid5() v5 No Deterministic - same namespace + name = same UUID
Str::uuid() (Laravel) v4 No Laravel helper - wraps ramsey/uuid

Primary Implementation

Production Ready
php
<?php
use Ramsey\Uuid\Uuid;

// UUID v4 - random, CSPRNG-backed
$uuid = Uuid::uuid4();
echo $uuid->toString();
// → f47ac10b-58cc-4372-a567-0e02b2c3d479

// As a plain string
$uuidStr = (string) $uuid;

// As hex (no hyphens)
$uuidHex = $uuid->getHex()->toString();
// → f47ac10b58cc4372a5670e02b2c3d479

// As bytes (16 bytes)
$uuidBytes = $uuid->getBytes();

// Parse and validate an existing UUID string
try {
    $parsed = Uuid::fromString('f47ac10b-58cc-4372-a567-0e02b2c3d479');
    echo $parsed->getVersion(); // → 4
} catch (\InvalidArgumentException $e) {
    echo 'Invalid UUID: ' . $e->getMessage();
}

// Generate multiple UUIDs
$ids = array_map(fn() => (string) Uuid::uuid4(), range(1, 5));

All UUID Versions

UUID v4 - Random (recommended default)

php
<?php
use Ramsey\Uuid\Uuid;

$uuid = Uuid::uuid4();
echo $uuid->toString(); // → "550e8400-e29b-41d4-a716-446655440000"

UUID v7 - Time-ordered (database PKs)

php
<?php
use Ramsey\Uuid\Uuid;

// Millisecond-precision timestamp prefix - sorts chronologically
$uuid = Uuid::uuid7();
echo $uuid->toString(); // → "018e8f6a-1b2c-7d3e-9f4a-5b6c7d8e9f0a"

UUID v5 - Deterministic / Namespace-based

php
<?php
use Ramsey\Uuid\Uuid;

// SHA-1 hash of namespace + name - same inputs always produce the same UUID
$uuid = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'example.com');
echo $uuid->toString(); // → always "cfbff0d1-9375-5685-968c-48ce8b15ae17"

Laravel helpers

php
<?php
use Illuminate\Support\Str;

// Str::uuid() wraps ramsey/uuid - returns a UuidInterface
$uuid = Str::uuid();
echo (string) $uuid; // → "f47ac10b-58cc-4372-a567-0e02b2c3d479"

// Str::orderedUuid() - time-ordered, better for DB index performance
$orderedUuid = Str::orderedUuid();
echo (string) $orderedUuid;

Real-World Use Cases

1. Laravel Eloquent model with UUID primary key

php
<?php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Order extends Model
{
    protected $keyType = 'string';
    public $incrementing = false;

    protected static function boot(): void
    {
        parent::boot();
        static::creating(function (Order $model) {
            if (empty($model->id)) {
                $model->id = (string) Str::uuid();
            }
        });
    }
}

// Or use Laravel's HasUuids trait (Laravel 9+):
// use Illuminate\Database\Eloquent\Concerns\HasUuids;

2. Symfony entity with UUID PK

php
<?php
use Symfony\Component\Uid\Uuid;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Product
{
    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
    private Uuid $id;

    public function __construct()
    {
        $this->id = Uuid::v4();
    }
}

3. API idempotency key

php
<?php
use Ramsey\Uuid\Uuid;

function chargeCustomer(string $customerId, int $amountCents): array
{
    // Generate once, store in session, reuse on retry
    $idempotencyKey = (string) Uuid::uuid4();

    $response = Http::withHeaders([
        'Idempotency-Key' => $idempotencyKey,
    ])->post('https://api.stripe.com/v1/charges', [
        'customer' => $customerId,
        'amount'   => $amountCents,
        'currency' => 'usd',
    ]);

    return $response->json();
}

Common Mistakes

Using uniqid() instead of a proper UUID

uniqid() is based on the current time in microseconds - it is not CSPRNG-backed and has a high collision probability under load. Always use Uuid::uuid4() or Str::uuid().

Not using the native UUID column type in MySQL 8+

MySQL 8.0.17+ supports UUID_TO_BIN(uuid, 1) to store UUIDs as BINARY(16) with time-bit reordering. Storing as VARCHAR(36) wastes space and causes index fragmentation.

Forgetting to cast to string when concatenating

Uuid::uuid4() returns a UuidInterface object, not a string. Use (string) $uuid or $uuid->toString() before passing to string contexts.

How It Works

ramsey/uuid uses PHP's random_bytes(16) for entropy, which maps to the OS CSPRNG (/dev/urandom on Linux, CryptGenRandom on Windows). It then sets the version and variant bits per RFC 4122.

The library returns a UuidInterface object. Cast to string with (string) or call ->toString() for the standard hyphenated format.

Output Formats

$uuid->toString()

f47ac10b-58cc-4372-a567-0e02b2c3d479

$uuid->getHex()->toString()

f47ac10b58cc4372a5670e02b2c3d479

$uuid->getBytes() - 16 bytes

binary string (16 bytes)

Best Practices, Performance, and Security

Best practices

Use Uuid::uuid7() for database PKs - sequential inserts avoid B-tree fragmentation.

In Laravel 9+, use the HasUuids trait instead of manual boot hooks.

Store as BINARY(16) in MySQL or native UUID type in PostgreSQL.

Performance

PHP generates roughly 500K–1M UUIDs/second with ramsey/uuid. The bottleneck is random_bytes() - a syscall on every call.

For bulk generation, consider generating UUIDs in batches and inserting with a single multi-row INSERT rather than one INSERT per UUID.

Security

Entropy source: random_bytes() - maps to /dev/urandom on Linux/macOS and CryptGenRandom on Windows. Cryptographically secure.

Never use uniqid(), rand(), or mt_rand() for IDs. They are not CSPRNG-backed and have predictable output.

Installation

UUID v4 (ramsey/uuid)

bash
composer require ramsey/uuid

Requires PHP 8.0+. Laravel already includes ramsey/uuid as a dependency - no extra install needed in Laravel projects.

Frequently Asked Questions

How do I generate a UUID in PHP?

ramsey/uuid is the de facto PHP standard with hundreds of millions of downloads. Run composer require ramsey/uuid, then Uuid::uuid4() returns a random v4 and Uuid::uuid7() a time-ordered v7. Laravel ships Str::uuid() built in, and Symfony offers the symfony/uid component.

Is Uuid::uuid4() cryptographically secure?

Yes. Uuid::uuid4() uses the platform CSPRNG (operating system secure random source), suitable for session tokens, API keys, and idempotency keys. Do not use non-cryptographic random sources for security-sensitive identifiers.

What is the difference between UUID v4 and v7 in PHP?

UUID v4 (Uuid::uuid4() or equivalent) is fully random and not sortable. UUID v7 embeds a millisecond timestamp for chronological sorting (RFC 9562). Use v4 for general-purpose IDs; use v7 for database primary keys at scale.

Do I need to install a package for UUID generation in PHP?

Yes. PHP has no built-in UUID generator, so install a library - composer require ramsey/uuid is the standard choice. Laravel bundles Str::uuid() and Symfony provides the symfony/uid component.

How do I validate a UUID string in PHP?

Use the platform's UUID parse/validation function, or test against the RFC 4122 regex: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Always validate external input at API boundaries.

Should I use UUIDs as database primary keys in PHP applications?

UUIDs work well as primary keys for distributed systems. Prefer native UUID/BINARY(16) column types over VARCHAR(36). For very large tables, consider UUID v7 for better B-tree insert locality.

Can I generate UUIDs in PHP without a network connection?

Yes. UUID generation uses local OS entropy sources and does not require network access. Each call is independent and thread-safe on modern platforms.

What output formats are available in PHP?

The standard hyphenated lowercase string (36 chars) is the default. Most APIs also support 32-char hex (no hyphens) and 16-byte binary formats. Use string format for APIs and binary for database storage.

What RFC standards apply to PHP UUID generation?

Version 4 UUIDs follow RFC 4122. UUID v7 follows RFC 9562 (May 2024). Ensure your chosen method produces compliant version and variant bits.

When should I avoid UUID v1?

Avoid UUID v1 in security-sensitive contexts - it embeds MAC address and timestamp information. Prefer v4 (Uuid::uuid4() or equivalent) unless you need legacy Cassandra timeuuid compatibility.

Key definitions

UUID
128-bit universally unique identifier, usually shown as 36 hex characters with hyphens.
CSPRNG
Cryptographically secure pseudo-random number generator - the entropy source behind secure UUID generation.
RFC 4122
IETF standard defining UUID versions 1 through 5. Version 4 is random.
RFC 9562
IETF standard adding UUID versions 6, 7, and 8. Version 7 is time-ordered.