hejunjie / id-generator
轻量级 PHP ID 生成器,提供雪花算法、UUID、时间戳和自定义可读 ID 等多种策略,确保全局唯一性与高并发性能,可轻松集成到任何 PHP 项目,适用于订单号、资源标识、日志追踪等多种业务场景 | A lightweight PHP ID generator supporting Snowflake, UUID, timestamp, and custom readable ID strategies. Ensures global uniqueness and high-performance, easily integrable into any PHP project, suita
Requires
- php: >=8.1
README
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
Generatorinterface 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:
- Environment variable (recommended): set
MACHINE_IDto manually specify the machine ID - MAC address: automatically reads the network interface MAC address and hashes it
- 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.