iliaal/fast_uuid
Composer 安装命令:
pie install iliaal/fast_uuid
包简介
Fast RFC 9562 UUID generation (v1/v2/v3/v4/v5/v6/v7/v8 + nil/max) as a PHP C extension, with a ramsey/uuid-shaped object API and procedural fast-path functions.
README 文档
README
A high-performance PHP C extension for RFC 9562 / RFC 4122 UUID generation, 11x to 57x faster than ramsey/uuid on v1/v4/v7 generation and 7x to 11x faster on parsing. It produces versions 1, 2 (DCE Security), 3, 4, 5, 6, 7, 8, plus nil and max. The engine is pure C (no C++/libstdc++). The object API mirrors ramsey/uuid under the FastUuid namespace, and procedural functions give a zero-allocation fast path for the hottest call sites.
Full API reference with runnable examples: docs/index.html. Benchmarks: BENCHMARKS.md.
⚡ Why it's fast
- Batched CSPRNG:
getrandom()is amortized across ~500 v4s via an 8 KB per-thread buffer instead of one syscall per UUID. ramsey's per-callrandom_bytes()is the usual bottleneck. - No property table: the object is 16 inline bytes plus a lazily-cached canonical string. No
HashTable, no declared properties, custom create/free/clone/compare/cast handlers. - SIMD hex formatter: x86-64 uses a runtime-dispatched SSSE3
pshufb-LUT path, and ARM64 uses a NEON table-lookup path. Both turn 16 bytes into 32 hex in a handful of vector ops, with a scalar LUT fallback for other architectures. - Procedural path:
uuid_v4()and friends return azend_stringwith no object allocation, for ORM inserts and cache keys.
Requirements
- PHP 8.1 through 8.6, NTS or ZTS. PHP 8.1/8.2/8.3 build via small
#if PHP_VERSION_IDpolyfills. - x86-64 and ARM64 get the SIMD formatter automatically; other architectures fall back to the scalar path. No build flags needed either way.
- No external libraries. v1 and v6 use an internal RFC-compliant generator with a random node (multicast bit set, per RFC 9562 §5.1). v3 and v5 use PHP's bundled MD5/SHA1.
📦 Install
The quickest path is PIE, which resolves a prebuilt
binary for your platform (Windows x86/x64 NTS/TS, Linux glibc
x86_64/arm64, macOS arm64) and falls back to a source build otherwise:
pie install iliaal/fast_uuid
Then enable it with extension=fast_uuid in your php.ini.
🛠️ Build from source
phpize ./configure --enable-fast-uuid make make test php -d extension="$(pwd)/modules/fast_uuid.so" -r 'echo \FastUuid\Uuid::uuid4(), "\n"; echo uuid_v7(), "\n";'
The arginfo header is generated from fast_uuid.stub.php. To regenerate after editing the stub:
php /path/to/php-src/build/gen_stub.php fast_uuid.stub.php
Object API: FastUuid\Uuid
Static factories (all return FastUuid\UuidInterface):
uuid1(int|string|null $node = null, ?int $clockSeq = null)
uuid2(int $localDomain, int|string|null $localIdentifier = null, int|string|null $node = null, ?int $clockSeq = null)
uuid3(UuidInterface|string $ns, string $name)
uuid4()
uuid5(UuidInterface|string $ns, string $name)
uuid6(int|string|null $node = null, ?int $clockSeq = null)
uuid7(int|DateTimeInterface|null $dateTime = null) // int = unix milliseconds
uuid8(string $bytes) // 16 raw bytes
fromString(string $uuid) // canonical, urn:uuid:, {braced}, bare 32-hex, any case
fromBytes(string $bytes) // 16 raw bytes
fromInteger(string $integer) // decimal string
fromHexadecimal(Stringable|string $hex) // 32 hex chars; Stringable covers ramsey's Type\Hexadecimal
fromDateTime(DateTimeInterface $dt, int|string|null $node = null, ?int $clockSeq = null)
isValid(string $uuid): bool
Instance methods:
toString(): string __toString(): string getBytes(): string getHex(): string
getUrn(): string getVersion(): ?int getVariant(): int getInteger(): string
getDateTime(): DateTimeImmutable getFields(): array equals(mixed): bool
compareTo(mixed): int jsonSerialize(): string getTimestampMillis(): int
toBytes(): string toHexadecimal(): string toUrn(): string toInteger(): string
toBytes()/toHexadecimal()/toUrn()/toInteger()are aliases ofgetBytes()/getHex()/getUrn()/getInteger(), matching theget*→to*naming of the newerramsey/identifierlibrary.getTimestampMillis()returns the embedded timestamp as unix milliseconds for RFC time-based versions (v1, v2, v6, v7) and is much cheaper thangetDateTime()since it builds no object; it throwsUnsupportedOperationExceptionfor non-time-based versions and non-RFC variants.Uuid::uuid7()accepts a unix-millisecondintas well as aDateTimeInterface, which skips the DateTime machinery entirely. The proceduraluuid_v7_at(int $unixMillis)is the fastest explicit-timestamp form.- UUIDv7 carries sub-millisecond precision (RFC 9562 §6.2 Method 3): the sub-ms fraction is encoded in
rand_aand a monotonic counter lives inrand_b, so v7s generated within the same millisecond still sort in time order (the tie-breaking counter is per process, or per thread under ZTS, so ~244 ns ties across threads or processes carry no order).getDateTime()reads back at millisecond precision, matchingramsey/uuid. getVariant()returns0(NCS),2(RFC 4122),6(Microsoft),7(future);getVersion()isnullfor nil/max and non-RFC variants.getDateTime()works for RFC time-based versions (v1, v2, v6, v7) and throwsFastUuid\Exception\UnsupportedOperationExceptionfor non-time-based versions and non-RFC variants.getFields()returns an associative array of hex strings (time_low,time_mid,time_hi_and_version,clock_seq_hi_and_reserved,clock_seq_low,node). For the ramsey-shapedFieldsInterface/Typeobjects, use the compat layer below.equals()andcompareTo()accept another UUID object (native, a compat wrapper, or anyStringablewhose string form parses as a UUID) or its canonical string.var_dump()shows the value as a virtualuuidproperty, andvar_export()output rebuilds throughUuid::__set_state().
Constants: NIL, MAX, NAMESPACE_DNS, NAMESPACE_URL, NAMESPACE_OID, NAMESPACE_X500, DCE_DOMAIN_PERSON, DCE_DOMAIN_GROUP, DCE_DOMAIN_ORG.
Implements FastUuid\UuidInterface, JsonSerializable, Stringable.
DCE Security (v2)
$u = \FastUuid\Uuid::uuid2(\FastUuid\Uuid::DCE_DOMAIN_PERSON); // local id auto-fills from POSIX uid $u->getVersion(); // 2 $u = \FastUuid\Uuid::uuid2(\FastUuid\Uuid::DCE_DOMAIN_GROUP, 4242);
The local identifier occupies bytes 0 to 3 (big-endian); the local domain is stored in byte 9. With domain PERSON or GROUP and a null identifier, the extension uses the process uid or gid; on Windows, where there is no POSIX uid/gid, an explicit localIdentifier is required.
Exceptions
FastUuid\Exception\InvalidArgumentException(extends\InvalidArgumentException): a bad length, node, or integer.FastUuid\Exception\InvalidUuidStringException(extends the above): an unparseable UUID string.FastUuid\Exception\UnsupportedOperationException(extends\LogicException, matchingramsey/uuid4.x): raised bygetDateTime()on a non-time-based version.
Out-of-range factory inputs are rejected, not silently truncated: a v7 timestamp past the 48-bit millisecond field, a fromDateTime instant outside the v1 Gregorian window, a non-canonical or >128-bit decimal string for fromInteger, a node outside 0..2^48-1, a clock sequence outside 0..0x3fff, or uuid2 without an explicit local identifier for a non-PERSON/GROUP domain all throw InvalidArgumentException.
Procedural API
uuid_v1() uuid_v3($ns, $name) uuid_v4() uuid_v4_fast() uuid_v5($ns, $name) uuid_v6() uuid_v7() uuid_v8($bytes)
uuid_v7_at($unixMillis) // v7 from a unix-millisecond int (no DateTime)
uuid_v1_bin() uuid_v4_bin() uuid_v6_bin() uuid_v7_bin() uuid_v4_fast_bin() // raw 16 bytes, no string
uuid_v3_bin($ns, $name) uuid_v5_bin($ns, $name) uuid_v8_bin($bytes) uuid_v7_at_bin($unixMillis)
uuid_v4_batch($n) uuid_v7_batch($n) // array of $n canonical strings
uuid_v4_bin_batch($n) uuid_v7_bin_batch($n) // array of $n raw 16-byte values
uuid_to_bin($uuid) // canonical/parsed string -> 16 raw bytes
uuid_from_bin($bytes)// 16 raw bytes -> canonical string
uuid_is_valid($uuid) // bool
fast_uuid_random_bytes($length) // batched CSPRNG bytes, $length > 0
uuid_v4_fast() uses a non-cryptographic xoshiro256** PRNG. Use it only for non-security IDs.
Batch count is capped at 100,000 UUIDs per call, and fast_uuid_random_bytes() is capped at 16 MiB per call.
ramsey/uuid compatibility layer (FastUuid\Compat)
compat/ is a PSR-4 (FastUuid\Compat\) companion package (iliaal/fast-uuid-compat) that provides the cold-path ramsey ergonomics on top of the C engine. It ships in this repo's compat/ directory and is not on Packagist yet; install it as a Composer path repository (composer config repositories.fast-uuid-compat path /path/to/fast_uuid/compat && composer require iliaal/fast-uuid-compat:@dev) or autoload FastUuid\Compat\ to compat/src/. It provides: UuidFactory, the per-version Rfc4122\UuidV1…UuidV8 / NilUuid / MaxUuid / Nonstandard\Uuid classes, Rfc4122\UuidV2 with getLocalDomain() / getLocalIdentifier() / getLocalDomainName(), Rfc4122\UuidV6 with fromUuidV1() / toUuidV1(), Rfc4122\Fields (FieldsInterface), Type\Hexadecimal, Type\Integer, the codecs (StringCodec, OrderedTimeCodec, TimestampFirstCombCodec, TimestampLastCombCodec, GuidStringCodec), Guid\Guid, the providers (RandomGeneratorInterface, NodeProviderInterface, TimeGeneratorInterface + defaults), and the validators (GenericValidator, NonstandardValidator).
Generation stays on the pure-C fast path; supplying a custom RandomGeneratorInterface / TimeGeneratorInterface / NodeProviderInterface intentionally routes off it where needed (ramsey behaviour) so application-supplied generators win. Custom node providers feed uuid1(), uuid2(), uuid6(), and fromDateTime() when no explicit node is passed. The compat Uuid::uuid7() facade also accepts a unix-millisecond int, matching the core object API. Factory decode methods honor the active codec: with GuidStringCodec, fromString(), fromBytes(), fromHexadecimal(), and fromInteger() interpret input as GUID mixed-endian data; use the default StringCodec for network-order integer/hex identity. Migration from ramsey/uuid is largely a use swap from Ramsey\Uuid\Uuid to FastUuid\Compat\Uuid. The compat package has no external dependencies beyond the extension itself.
📊 Benchmarks
Throughput against ramsey/uuid 4.9.2 and the PECL uuid extension 1.3.0
(libuuid-backed). PHP 8.4.22 NTS, non-debug, no sanitizers; SSSE3 hex formatter
active (x86-64). Each operation runs 300,000 iterations after a 20,000-iteration
warmup; reported figure is the best of 40 runs. Million ops/sec, higher is
better:
| Operation | fast_uuid (obj) | fast_uuid (proc) | ramsey/uuid | PECL uuid |
|---|---|---|---|---|
| v4 gen→string | 12.6 | 19.5 | 1.10 | 0.47 |
| v1 gen→string | 12.3 | 16.5 | 0.29 | 8.22 |
| v7 gen→string | 12.1 | 19.8 | 0.66 | n/a |
| parse→16 bytes | 23 | 36 | 3.18 | 5.28 |
Speedup over ramsey/uuid: v4 11.5x to 17.7x, v1 42x to 57x, v7 18.3x to 30x,
parse 7.2x to 11.3x.
Generating many at once amortizes the per-call overhead. The batch functions
return an array of 100 per call; procedural binary forms (uuid_v4_bin() etc.)
skip canonical formatting and return raw 16-byte strings. Million UUIDs/sec:
| Batch operation | fast_uuid (proc) |
|---|---|
uuid_v4_batch |
22.5 |
uuid_v7_batch |
25 |
uuid_v4_bin_batch |
25 |
uuid_v7_bin_batch |
29 |
The fast_uuid operations are fast enough (~50 ns) that scheduler noise
dominates a single run, so read the fast_uuid columns as order-of-magnitude,
not three-significant-digit (roughly ±10% run-to-run). ramsey/uuid (~900 ns)
and PECL (~2 µs) reproduce to within ~3%. Full table, the ARM64/NEON numbers,
the timestamp/DateTime API breakdown, and how to reproduce are in
BENCHMARKS.md.
Testing
make test # run-tests.php against the built .so
The suite (tests/*.phpt) covers every version, all parse forms, per-version getDateTime, fields/integer, node/clockSeq, the exception hierarchy, the procedural functions, the SIMD formatter, and the full compat layer. Verified green on PHP 8.1 / 8.2 / 8.3 / 8.4 / 8.4-ZTS / 8.5 / 8.6 (0 compiler warnings) and clean under an ASan/UBSan-instrumented build.
Contributing
Build instructions, the stub-to-arginfo workflow, and the test conventions are in CONTRIBUTING.md. Run the suite against more than one PHP version when you touch C, and add an ASan/UBSan run for any change to a parse, format, or generation path.
Security
Report a vulnerability by email to ilia@ilia.ws. Details and scope are in SECURITY.md.
🔗 Native PHP extensions
Companion native PHP extensions:
- php_excel: native Excel I/O via LibXL. 7-10× faster than PhpSpreadsheet, full XLS/XLSX with formulas, formatting, and styling.
- mdparser: native CommonMark + GFM markdown parser via md4c. 15-30× faster than pure-PHP libraries.
- php_clickhouse: native ClickHouse client speaking the wire protocol directly. Picks up where SeasClick left off.
- pdo_duckdb: PDO driver for DuckDB, analytical SQL in your PHP stack.
- fastjson: drop-in faster
ext/json, backed by yyjson. 6× encode, 2.7× decode, 5× validate. - phpser: decoder-optimized binary serializer for cache workloads. Faster than igbinary on packed numerics and DTO batches.
- fastchart: native chart-rendering extension. 38 chart types behind one fluent OO API, SVG-canonical with PNG/JPG/WebP and optional PDF output.
- statgrab: system statistics (CPU, memory, disk, network) via libstatgrab, no parsing /proc by hand.
- phonetic: native phonetic name matching (Double Metaphone, Beider-Morse, Daitch-Mokotoff, NYSIIS, Match Rating), the encoders PHP core lacks.
License
BSD-3-Clause. See LICENSE.
Follow @iliaa on X • Blog • If this sped up your UUID generation, ⭐ star it!
iliaal/fast_uuid 适用场景与选型建议
iliaal/fast_uuid 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2 次下载、GitHub Stars 达 20, 最近一次更新时间为 2026 年 06 月 01 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「extension」 「uuid」 「guid」 「rfc4122」 「rfc9562」 「uuid7」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 iliaal/fast_uuid 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 iliaal/fast_uuid 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 iliaal/fast_uuid 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Paramconverter, Normalizer and Form Type for Ramsey Uuid
A custom URL rule class for Yii 2 which allows to create translated URL rules
The Yii2 extension uses jQuery jquery.carousel-1.1.min.js and makes image carousel from php array of structure defined.
A PHP library for generating and working with identifiers, including UUIDs, ULIDs, and Snowflakes
TYPO3 CMS extension to create gallery content element with preset crop ratios and pagination
UI Kit 3 Extension for Yii2
统计信息
- 总下载量: 2
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 20
- 点击次数: 41
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: BSD-3-Clause
- 更新时间: 2026-06-01
