alesitom/hybrid-id
Composer 安装命令:
composer require alesitom/hybrid-id
包简介
Compact, time-sortable unique ID generator for PHP. Drop-in UUID/ULID alternative with base62 encoding, Stripe-style prefixes, and configurable entropy profiles.
关键字:
README 文档
README
Compact, time-sortable unique identifiers for PHP
A space-efficient alternative to UUID with configurable entropy profiles, Stripe-style prefixes, and an instance-based API. Generate chronologically sortable, URL-safe identifiers 33-56% smaller than canonical UUIDs — with zero dependencies.
Why HybridId?
| Feature | HybridId | TypeID | KSUID | UUIDv7 | NanoID | CUID2 |
|---|---|---|---|---|---|---|
| Length | 16-24 chars | 26 chars | 27 chars | 36 chars | 21 chars | 24 chars |
| Configurable size | Yes | No | No | No | No | No |
| Type prefixes | Yes | Yes | No | No | No | No |
| Time-sortable | Yes | Yes | Yes | Yes | No | No |
| Metadata extraction | Full | Partial | Partial | Partial | None | None |
| Zero dependencies | Yes | Varies | Varies | Yes | Varies | Varies |
| Range queries | Yes | No | No | No | No | No |
| Multi-node safe | Yes | Yes | No | Yes | N/A | N/A |
| Random entropy | 47.6 - 83.4+ bits | ~80 bits | 128 bits | 74 bits | ~126 bits | ~120 bits |
Installation
composer require alesitom/hybrid-id
Requires PHP 8.3, 8.4, or 8.5 (64-bit). No external dependencies.
Quick Start
use HybridId\HybridIdGenerator; $gen = new HybridIdGenerator(node: 'A1'); $id = $gen->generate(); // 0VBFDQz4A1Rtntu09sbf $id = $gen->generate('usr'); // usr_0VBFDQz4A1Rtntu09sbf $id = $gen->compact('log'); // log_0VBFDQz6xK9mLp2w $id = $gen->extended('txn'); // txn_0VBFDQz7A1pBKVwwn2xiF0
Profiles
Three built-in profiles with different size/entropy tradeoffs:
| Profile | Length | Structure | Random entropy | Use case |
|---|---|---|---|---|
compact |
16 | 8ts + 8rand | 47.6 bits | Internal PKs, low-scale apps |
standard |
20 | 8ts + 2node + 10rand | 59.5 bits | General purpose (default) |
extended |
24 | 8ts + 2node + 14rand | 83.4 bits | High-scale, public-facing IDs |
Standard / Extended: Compact (no node):
0VBFDQz4 A1 Rtntu09sbf 0VBFDQz4 xK9mLp2w
|______| |_| |_________| |______| |________|
ts node random ts random
- ts (8 chars): Millisecond timestamp in base62. Enables chronological sorting.
- node (2 chars, standard/extended): Server/process identifier. Prevents cross-node collisions.
- rand (variable): Cryptographically secure random bytes via
random_bytes().
Custom profiles are available via ProfileRegistry — see API Reference.
Configuration
use HybridId\HybridIdGenerator; // Standard profile with explicit node (recommended for production) $gen = new HybridIdGenerator(node: 'A1'); // Explicit profile $gen = new HybridIdGenerator(profile: 'extended', node: 'A1'); // Compact — no node needed $gen = new HybridIdGenerator(profile: 'compact'); // From environment variables (HYBRID_ID_PROFILE, HYBRID_ID_NODE, HYBRID_ID_BLIND, HYBRID_ID_BLIND_SECRET) $gen = HybridIdGenerator::fromEnv();
By default, standard and extended profiles require an explicit node to prevent accidental collisions in production. Pass requireExplicitNode: false for local development.
Prefixes
Stripe-style prefixes make IDs self-documenting:
$gen->generate('usr'); // usr_0VBFDQz4A1Rtntu09sbf $gen->generate('ord'); // ord_0VBFDQz5A1xiF0G9pBKV
Rules: 1-8 chars, lowercase alphanumeric, starts with a letter. All extraction and validation methods handle prefixed IDs transparently.
Database
Column sizing
| Profile | No prefix | With prefix (max 3) | With prefix (max 8) |
|---|---|---|---|
compact |
CHAR(16) |
VARCHAR(20) |
VARCHAR(25) |
standard |
CHAR(20) |
VARCHAR(24) |
VARCHAR(29) |
extended |
CHAR(24) |
VARCHAR(28) |
VARCHAR(33) |
Collation (MySQL/MariaDB)
Base62 uses mixed case (A != a). You must use ascii_bin or utf8mb4_bin collation — the default utf8mb4_0900_ai_ci will silently break uniqueness and sort order.
CREATE TABLE users ( id CHAR(20) COLLATE ascii_bin NOT NULL PRIMARY KEY, ... );
PostgreSQL and SQLite are case-sensitive by default — no special collation needed.
Storage efficiency
| Format | Size | Savings vs UUID |
|---|---|---|
| UUID (canonical) | CHAR(36) | — |
| ULID | CHAR(26) | 28% |
| TypeID | VARCHAR(34) | 6% |
| HybridId compact | CHAR(16) | 56% |
| HybridId standard | CHAR(20) | 44% |
| HybridId extended | CHAR(24) | 33% |
Smaller primary keys improve B-tree index density and reduce page splits. Time-sorted layout eliminates the random-insert penalty of UUID v4. See Database Guide for time-range queries, NoSQL patterns, and migration strategies.
Security
Not for secrets. Do NOT use HybridId for security tokens, session IDs, API keys, or password resets. The timestamp is predictable — use random_bytes() with 128+ bits for those.
Standards alignment:
- RFC 9562: UUIDv8 compliant via
UuidConverter::toUUIDv8() - CSPRNG:
random_bytes()backed by OS-level cryptographic random - RFC 3986: URL-safe base62, no percent-encoding needed
- Rejection sampling eliminates modulo bias (NIST SP 800-90A aligned)
What HybridId is NOT: not OWASP ASVS V2.6 compliant, not constant-time in validation, timestamps are predictable by design (same as UUIDv7).
Blind Mode
HMAC-hashes the timestamp and node with a per-instance secret, making creation time unextractable. Same length and format — an observer cannot tell if an ID is blind.
$gen = new HybridIdGenerator(node: 'A1', blind: true); $id = $gen->generate('usr'); // usr_<opaque20chars>
See Blind Mode for details on what works, what changes, and when to use it.
UUID Interoperability
Convert between HybridId and RFC 9562 UUIDs:
| Method | Lossless | Notes |
|---|---|---|
UuidConverter::toUUIDv8() / fromUUIDv8() |
Yes | Profile auto-detected on decode |
UuidConverter::toUUIDv7() / fromUUIDv7() |
No | Timestamp-preserving, needs profile hint |
UuidConverter::toUUIDv4Format() / fromUUIDv4Format() |
No | Lossy, NOT a true UUIDv4 |
Compact and standard profiles only. Prefixed IDs are rejected — strip prefix first.
See UUID Interoperability for full examples and compatibility matrix.
Framework Integrations
| Package | Framework | Install |
|---|---|---|
| hybrid-id-laravel | Laravel 11/12 | composer require alesitom/hybrid-id-laravel |
| hybrid-id-doctrine | Doctrine DBAL 4 / ORM 3 | composer require alesitom/hybrid-id-doctrine |
See Dependency Injection & Testing for IdGenerator interface, DI wiring, and framework examples.
Requirements
- PHP 8.3, 8.4, or 8.5 (64-bit)
- No external dependencies
Learn More
| Topic | Link |
|---|---|
| Full API (validation, parsing, metadata, sorting, custom profiles) | docs/api-reference.md |
| UUID conversion (v8, v7, v4-format) | docs/uuid-interoperability.md |
| Database (time-range queries, NoSQL, migration from UUID) | docs/database.md |
| Blind mode (HMAC-hashed timestamps) | docs/blind-mode.md |
| CLI reference | docs/cli.md |
| Dependency injection & testing | docs/dependency-injection.md |
| Internals (clock drift, concurrency, design decisions) | docs/internals.md |
| Upgrading (v1 → v2 → v3 → v4) | UPGRADING.md |
| Changelog | CHANGELOG.md |
License
MIT
统计信息
- 总下载量: 690
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 2
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-02-14