Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hejunjie/php-id-generator

English | 简体中文

A lightweight PHP ID generator supporting Snowflake, UUID, timestamp, and readable ID strategies. Suitable for order numbers, database primary keys, log tracing, resource identifiers, and more.

🔗 Quickly understand this project's structure and code logic via Zread.

Features

  • Four built-in strategies: Snowflake, Timestamp, Readable, UUID — covering common ID generation needs
  • Custom strategy support: Implement the Generator interface and register your own strategy
  • Concurrency-safe: Built-in file lock and Redis lock, from single machine to distributed
  • Parseable IDs: Extract timestamp, machine ID, sequence number, and more from generated IDs
  • Lightweight with zero dependencies: Redis extension is optional; only PHP >= 8.1 required

Requirements

  • PHP >= 8.1
  • ext-redis (optional, recommended for distributed scenarios)

Installation

composer require hejunjie/id-generator

Quick Start

use Hejunjie\IdGenerator\IdGenerator;

// Create a Snowflake ID generator
$generator = IdGenerator::make('snowflake');

// Generate an ID
echo $generator->generate(); // 746532984356372480

// Parse an ID
print_r($generator->parse('746532984356372480'));
// [
//     'timestamp'  => 1715779200000,
//     'datetime'   => '2024-05-15 12:00:00',
//     'machine_id' => 256,
//     'sequence'   => 0,
// ]

Built-in Strategies

Snowflake

64-bit Snowflake algorithm: 1-bit sign + 41-bit timestamp + 10-bit machine ID + 12-bit sequence number.

Configuration:

Parameter Type Default Description
useFileLock bool false Enable file lock for concurrency safety
redisConfig array [] Redis config; automatically uses Redis lock when provided

Concurrency modes:

Mode Description Use Case
Default (no lock) Random sequence; duplicates possible at > 75 IDs/ms Low-frequency calls
File lock Safe on a single machine; slightly lower performance Single server
Redis lock Safe across distributed systems (recommended) Distributed

Note

The machine ID is automatically obtained via the MACHINE_ID environment variable, MAC address, or IP address. See Configuration for details.

use Hejunjie\IdGenerator\IdGenerator;

// Default (no lock)
$snowflake = IdGenerator::make('snowflake');

// Redis lock (recommended for distributed)
$snowflake = IdGenerator::make('snowflake', [
    'redisConfig' => [
        'host' => '127.0.0.1',
        'port' => 6379,
        'auth' => null, // omit if no password
    ],
]);

$id = $snowflake->generate();
print_r($snowflake->parse($id));

Timestamp

Millisecond timestamp + sequence number, with optional custom prefix.

Configuration:

Parameter Type Default Description
prefix string '' ID prefix; no prefix added if omitted
useFileLock bool false Enable file lock for concurrency safety
redisConfig array [] Redis config; automatically uses Redis lock when provided
use Hejunjie\IdGenerator\IdGenerator;

// Timestamp ID with prefix
$timestamp = IdGenerator::make('timestamp', ['prefix' => 'ORD']);

$id = $timestamp->generate(); // ORD1715779200000123034
print_r($timestamp->parse($id));
// [
//     'prefix'    => 'ORD',
//     'datetime'  => '2024-05-15 12:00:00',
//     'timestamp' => 1715779200000,
//     'sequence'  => '123034',
// ]

Readable

Human-readable ID in the format PREFIX-YYYY-MM-DD-RANDOM. Ideal for user-facing scenarios.

Configuration:

Parameter Type Default Description
prefix string 'ID' ID prefix, automatically uppercased
randomLength int 8 Random string length (A-Z, 0-9)
use Hejunjie\IdGenerator\IdGenerator;

$readable = IdGenerator::make('readable', ['prefix' => 'ORD', 'randomLength' => 6]);

$id = $readable->generate(); // ORD-2024-05-15-A3B9K2
print_r($readable->parse($id));
// [
//     'prefix' => 'ORD',
//     'date'   => '2024-05-15',
//     'random' => 'A3B9K2',
// ]

UUID

RFC 4122 compliant. Supports both v1 (time-based) and v4 (random).

Configuration:

Parameter Type Default Description
version string 'v4' UUID version: v1 or v4
use Hejunjie\IdGenerator\IdGenerator;

// UUID v4 (default)
$uuid = IdGenerator::make('uuid');

// UUID v1
$uuid = IdGenerator::make('uuid', ['version' => 'v1']);

$id = $uuid->generate(); // 550e8400-e29b-41d4-a716-446655440000
print_r($uuid->parse($id));
// [
//     'uuid'    => '550e8400-e29b-41d4-a716-446655440000',
//     'version' => '4',
// ]

Custom Strategies

Implement the Generator interface, then register with registerStrategy:

use Hejunjie\IdGenerator\Contracts\Generator;
use Hejunjie\IdGenerator\IdGenerator;

class MyCustomGenerator implements Generator
{
    public function __construct(private string $prefix = 'MY') {}

    public function generate(): string
    {
        return $this->prefix . '-' . random_int(1000, 9999);
    }

    public function parse(string $id): array
    {
        return ['id' => $id];
    }
}

// Register
IdGenerator::registerStrategy('custom', function (array $config) {
    return new MyCustomGenerator($config['prefix'] ?? 'MY');
});

// Use
$custom = IdGenerator::make('custom', ['prefix' => 'ORD']);
echo $custom->generate(); // ORD-4821

Configuration

Machine ID (Snowflake)

The Snowflake strategy requires a 10-bit machine ID (0–1023). The resolution order is:

  1. Environment variable (recommended): set MACHINE_ID to manually specify the machine ID
  2. MAC address: automatically reads the network interface MAC address and hashes it
  3. IP address: falls back to IP address hashing when the above are unavailable
# Recommended: specify via environment variable at deploy time
export MACHINE_ID=1

Redis Configuration

For distributed scenarios, configure Redis as follows:

[
    'redisConfig' => [
        'host' => '127.0.0.1',
        'port' => 6379,
        'auth' => null, // password; omit if none
    ],
]

FAQ

Which strategy should I choose?

Strategy Use Case Example ID
Snowflake Distributed systems, DB primary keys, timestamp parsing 746532984356372480
Timestamp Order numbers, transaction IDs, prefixed IDs ORD1715779200000123034
Readable User-visible IDs, ticket numbers ORD-2024-05-15-A3B9K2
UUID Standardized scenarios, third-party integrations 550e8400-e29b-41d4-a716-446655440000

Can the default mode (no lock) produce duplicates?

Snowflake's default mode uses a random sequence number, with collision risk when generating more than ~75 IDs per millisecond. This is typically safe for low-frequency use (e.g., a single ID per web request). For high-concurrency scenarios, use the Redis lock.

What happens if Redis is unreachable?

If redisConfig is provided but Redis is unavailable, generate() will throw an exception. Consider implementing error handling or a fallback strategy.

Contributing

Issues and pull requests are welcome — whether it's new strategies, performance improvements, or documentation enhancements.

This project is licensed under the MIT License.

About

轻量级 PHP ID 生成器,多策略高性能,可用于订单号、资源标识等场景 | Lightweight PHP ID generator, multi-strategy & high-performance, for orders, resources, etc.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages