-
-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Все идентификаторы для PHP 8.1+ в одном пакете: UUID версий 1–8 (RFC 9562), ULID, NanoID, Snowflake и Sonyflake — единственная библиотека, покрывающая пять семейств сразу, с PSR-20-часами во всех временных генераторах, жёсткой валидацией ввода и производительностью в группе лидеров.
- 📥 Установка
- ⚡ Быстрый старт
- 🧩 Возможности — страница на каждую фичу
- ⚙️ Конфигурация
- 💡 Примеры
- 🏗️ Архитектура
- 📊 Сравнение
- 🧪 Тестирование
- ❓ FAQ
- 🤝 Contributing
composer require cloudcastle/uuiduse CloudCastle\Uuid\Uuid;
Uuid::uuid4()->toString(); // 'c0a8012e-…' — случайный UUID
Uuid::uuid7()->toString(); // сортируемый: миллисекунды + счётчик
Uuid::fromString($any); // канон / hex / Base58 / ULID-форма / URN / байты
Uuid::uuid7()->toBytes(); // 16 байт для BINARY(16)use CloudCastle\Uuid\Ulid;
use CloudCastle\Uuid\NanoIdFactory;
use CloudCastle\Uuid\SnowflakeFactory;
Ulid::generate()->toString(); // '01ARYZ6S41…' — монотонный ULID
(new NanoIdFactory())->generate(); // 'V1StGXR8_Z5jdHi6B-myT' — NanoID
(new SnowflakeFactory(1, 7))->generate(); // 63-битный Snowflake узла 1/7use CloudCastle\Clock\MockClock;
use CloudCastle\Uuid\UuidFactory;
// Киллер-фича: PSR-20 часы во ВСЕХ временных генераторах —
// UUID v1/v6/v7, ULID, Snowflake и Sonyflake детерминированы в тестах.
$factory = new UuidFactory(clock: MockClock::from('2026-01-01 00:00:00', 'UTC'));
$factory->uuid7()->timestampMs(); // ровно 1767225600000 — всегдаПолные сценарии — на страницах возможностей, каждая с примерами, схемой и жизненным циклом.
flowchart TB
II["IdentifierInterface<br/>toString() toBytes()<br/>equals() compareTo()"] --> TB["TimeBasedIdentifierInterface<br/>+dateTime()"]
TB -.-> U[Uuid]
TB -.-> UL[Ulid]
TB -.-> SF[SnowflakeId]
TB -.-> SY[SonyflakeId]
subgraph Фабрики
UF["UuidFactory<br/>uuid1()…uuid8()"]
ULF[UlidFactory]
SFF[SnowflakeFactory]
SYF[SonyflakeFactory]
NF[NanoIdFactory]
end
PSR["Psr\Clock\ClockInterface (PSR-20)"] --> UF & ULF & SFF & SYF
RND["RandomSourceInterface"] --> UF & ULF & NF
UF --> U
ULF --> UL
SFF --> SF
SYF --> SY
subgraph Кодеки
B58[Base58]
B32[CrockfordBase32]
BM[ByteMath]
end
U --- B58 & B32 & BM
UL --- B32
sequenceDiagram
participant A as Приложение
participant F as UuidFactory
participant C as PSR-20 часы
participant R as RandomSource
rect rgb(235, 245, 235)
note over A,R: Продакшн (часы и случайность системные)
A->>F: uuid7()
F->>F: microtime() — быстрый путь
F->>R: bytes(8)
F-->>A: Uuid (сортируемый)
end
rect rgb(235, 240, 250)
note over A,R: Тест (MockClock + детерминированный random)
A->>F: uuid7()
F->>C: now() — виртуальный момент
F->>R: bytes(8) — заданная последовательность
F-->>A: Uuid — байт в байт воспроизводим
end
Уровни статических анализаторов и порогов пакета против аналогов — значения подставляются из конфигов автоматически:
Сгенерировано из конфигов пакета (composer docs:sync). Уровни Uuid — из phpstan.neon / psalm.xml / infection.json.dist / phpmd.xml / deptrac.yaml; по аналогам — заявленный инструментарий из их composer.json (Composer-дистрибутивы аналогов конфигов качества не содержат, поэтому их уровни — «н/д»).
| Контроль качества | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| PHPStan | ✅ level max + strict-rules | ✅ (уровень: н/д) | ❌ | ❌ | ❌ | ✅ (уровень: н/д) | Uuid (уровень задокументирован) |
| Psalm | ✅ errorLevel 1 | ❌ | ❌ | ❌ | ❌ | ❌ | Uuid |
| Мутационное тестирование (Infection) | ✅ minMSI 98% (факт: 0 выживших) | ❌ | ❌ | ❌ | ❌ | ❌ | Uuid |
| PHPMD | ✅ 10 правил | ❌ | ❌ | ❌ | ❌ | ❌ | Uuid |
| Deptrac (архитектурные слои) | ✅ 5 слоёв | ❌ | ❌ | ❌ | ❌ | ❌ | Uuid |
| Rector (dry-run в CI) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Uuid |
| Код-стайл (PSR-12: phpcs + cs-fixer) | ✅ | ✅ (уровень: н/д) | ❌ | ❌ | ✅ (уровень: н/д) | ❌ | Uuid (уровень задокументирован) |
| Покрытие строк (порог на файл) | ✅ 98% (факт: 100%) | н/д | н/д | н/д | н/д | н/д | Uuid |
| Конфиги качества в дистрибутиве | ✅ поставляются | ❌ | ❌ | ❌ | ❌ | ❌ | Uuid |
Таблицы генерируются автоматически (composer docs:sync): факты поддержки —
из tools/features-data.php, победитель вычисляется по этим фактам.
Сгенерировано из tools/features-data.php (факты о поддержке). Легенда: ✅ полностью ·
| Функция | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| UUID v1 — время Григория + узел | ✅ | ✅ | ✅ | — | — | — | Паритет |
| UUID v2 — DCE Security (домен + локальный ID) | ✅ | ✅ | ❌ | — | — | — | Uuid + ramsey/uuid |
| UUID v3 / v5 — имя в пространстве имён (MD5/SHA-1) | ✅ | ✅ | ✅ | — | — | — | Паритет |
| UUID v4 — случайный | ✅ | ✅ | ✅ | — | — | — | Паритет |
| UUID v6 — переупорядоченное время (сортируемый v1) | ✅ | ✅ | ✅ | — | — | — | Паритет |
| UUID v7 — миллисекунды Unix (сортируемый) | ✅ | ✅ | ✅ | — | — | — | Паритет |
| UUID v8 — пользовательские 122 бита | ✅ | ✅ | ✅ | — | — | — | Паритет |
| Nil и Max UUID | ✅ | ✅ | ✅ | — | — | — | Паритет |
| Монотонность v7 в пределах миллисекунды | ✅ | ✅ | ✅ | — | — | — | Паритет |
| Функция | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Каноническая 8-4-4-4-12 | ✅ | ✅ | ✅ | — | — | — | Паритет |
| 16 сырых байт (BINARY-хранение) | ✅ | ✅ | ✅ | — | — | — | Паритет |
| Hex-строка (32 символа) | ✅ | ✅ | ✅ | — | — | — | Паритет |
| Base58 (22 символа) | ✅ | ❌ | ✅ | — | — | — | Uuid + symfony/uid |
| Base32/Crockford — форма ULID (26 символов) | ✅ | ❌ | ✅ | — | — | — | Uuid + symfony/uid |
| URN «urn:uuid:…» | ✅ | ✅ | ❌ | — | — | — | Uuid + ramsey/uuid |
| Десятичное 128-битное число | ✅ | ✅ | ❌ | — | — | — | Uuid + ramsey/uuid |
| GUID Microsoft (little-endian поля) | ✅ | ✅ | ❌ | — | — | — | Uuid + ramsey/uuid |
| Фигурная форма «{uuid}» | ✅ | ❌ | — | — | — | Uuid | |
| Умный fromString() — любая форма по длине | ✅ | ❌ | ✅ | — | — | — | Uuid + symfony/uid |
| Интроспекция: версия, вариант, метка, узел, последовательность | ✅ | ✅ | — | — | — | Uuid + ramsey/uuid |
| Функция | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Генерация ULID | ✅ | — | ✅ | ✅ | — | — | Паритет |
| Монотонный режим в пределах миллисекунды | ✅ | — | ✅ | ❌ | — | — | Uuid + symfony/uid |
| Бинарная форма 16 байт | ✅ | — | ✅ | ❌ | — | — | Uuid + symfony/uid |
| Метка времени из ULID | ✅ | — | ✅ | ✅ | — | — | Паритет |
| Мост ULID ↔ UUID (байты 1:1) | ✅ | — | ✅ | ❌ | — | — | Uuid + symfony/uid |
| Верхний и нижний регистр вывода | ✅ | — | ✅ | — | — | Uuid + robinvdvleuten/ulid | |
| Nil и Max ULID | ✅ | — | ✅ | ❌ | — | — | Uuid + symfony/uid |
| Функция | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Генерация NanoID (стандартный алфавит) | ✅ | — | — | — | ✅ | — | Паритет |
| Произвольный алфавит и длина | ✅ | — | — | — | ✅ | — | Паритет |
| Несмещённая отбраковочная выборка | ✅ | — | — | — | ✅ | — | Паритет |
| Валидация алфавита (дубликаты, мультибайт) | ✅ | — | — | — | ❌ | — | Uuid |
| Функция | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Snowflake (раскладка Twitter 41/5/5/12) | ✅ | — | — | — | — | ✅ | Паритет |
| Sonyflake (раскладка Sony 39/8/16) | ✅ | — | — | — | — | ✅ | Паритет |
| Разбор идентификатора на поля | ✅ | — | — | — | — | ✅ | Паритет |
| Настраиваемая эпоха | ✅ | — | — | — | — | ✅ | Паритет |
| Обнаружение отката часов без ожидания | ✅ | — | — | — | — | Uuid | |
| Перенос при переполнении последовательности без сна | ✅ | — | — | — | — | Uuid |
| Функция | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| PSR-20 часы во всех временных генераторах | ✅ | ❌ | ❌ | — | Uuid | ||
| Подменяемый источник случайности | ✅ | ✅ | ❌ | ❌ | ✅ | Uuid + ramsey/uuid + hidehalo/nanoid-php | |
| Полный детерминизм в тестах (время + случайность) | ✅ | ❌ | ❌ | Uuid | |||
| Явный момент генерации (в прошлом/будущем) | ✅ | ✅ | ✅ | ✅ | — | ❌ | Uuid + ramsey/uuid + symfony/uid + robinvdvleuten/ulid |
| Единый контракт идентификаторов + сквозное сравнение | ✅ | ❌ | ❌ | ❌ | ❌ | Uuid | |
| Экранирование управляющих символов в ошибках | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | Uuid |
| Функция | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| Одна runtime-зависимость (psr/clock — только интерфейс) | ✅ | ❌ | ✅ | ✅ | ✅ | Uuid + robinvdvleuten/ulid + hidehalo/nanoid-php + godruoyi/php-snowflake | |
| Без polyfill и брендированных зависимостей | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | Uuid + robinvdvleuten/ulid + hidehalo/nanoid-php + godruoyi/php-snowflake |
| Все пять семейств идентификаторов в одном пакете | ✅ | ❌ | ❌ | ❌ | ❌ | Uuid |
Изолированные попроцессные замеры против пяти аналогов (медиана из 7 прогонов, Xdebug выключен, один и тот же цикл у всех) — включая таблицу памяти:
Сгенерировано из composer compare (PHP 8.1.34). Правки в блоке будут перезаписаны.
| Сценарий | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| UUID v4: генерация до канонической строки | 1 046 205 ops/s | 610 239 ops/s | 1 018 006 ops/s | — | — | — | Uuid |
| UUID v7: генерация до канонической строки | 371 194 ops/s | 249 140 ops/s | 314 415 ops/s | — | — | — | Uuid |
| UUID v5: имя в пространстве DNS до строки | 1 180 795 ops/s | 169 722 ops/s | 742 033 ops/s | — | — | — | Uuid |
| UUID: разбор канонической строки в объект | 1 881 107 ops/s | 3 495 373 ops/s | 1 542 031 ops/s | — | — | — | ramsey/uuid |
| UUID: сериализация в Base58 | 267 701 ops/s | — | 99 551 ops/s | — | — | — | Uuid |
| UUID: разбор строки до 16 байт (для BINARY-хранения) | 1 827 324 ops/s | 1 986 579 ops/s | 850 262 ops/s | — | — | — | ramsey/uuid |
| ULID: генерация до канонической строки | 344 694 ops/s | — | 326 323 ops/s | 275 941 ops/s | — | — | Uuid |
| ULID: разбор строки в объект | 549 310 ops/s | — | 1 583 402 ops/s | 1 758 765 ops/s | — | — | robinvdvleuten/ulid |
| ULID: генерация до 16 байт (для BINARY-хранения) | 541 988 ops/s | — | 237 421 ops/s | — | — | — | Uuid |
| ULID: порядковое сравнение двух значений | 8 731 642 ops/s | — | 7 952 315 ops/s | — | — | — | Uuid |
| NanoID: генерация 21 символа | 1 413 007 ops/s | — | — | — | 530 293 ops/s | — | Uuid |
| Snowflake: генерация до десятичной строки | 552 896 ops/s | — | — | — | — | 81 348 ops/s | Uuid |
| Snowflake: разбор идентификатора на поля | 3 017 522 ops/s | — | — | — | — | 1 139 132 ops/s | Uuid |
Память — добавленная пиковая память процесса за сценарий (классы библиотеки + объекты + операции), меньше — лучше:
| Сценарий | Uuid | ramsey/uuid | symfony/uid | robinvdvleuten/ulid | hidehalo/nanoid-php | godruoyi/php-snowflake | 🏆 Победитель |
|---|---|---|---|---|---|---|---|
| UUID v4: генерация до канонической строки | 0.0 КБ | 163.7 КБ | 0.0 КБ | — | — | — | Паритет лидеров |
| UUID v7: генерация до канонической строки | 0.0 КБ | 164.5 КБ | 0.0 КБ | — | — | — | Паритет лидеров |
| UUID v5: имя в пространстве DNS до строки | 0.0 КБ | 218.8 КБ | 0.0 КБ | — | — | — | Паритет лидеров |
| UUID: разбор канонической строки в объект | 0.0 КБ | 0.0 КБ | 0.0 КБ | — | — | — | Паритет лидеров |
| UUID: сериализация в Base58 | 0.0 КБ | — | 0.0 КБ | — | — | — | Паритет лидеров |
| UUID: разбор строки до 16 байт (для BINARY-хранения) | 0.0 КБ | 0.0 КБ | 0.0 КБ | — | — | — | Паритет лидеров |
| ULID: генерация до канонической строки | 0.0 КБ | — | 0.0 КБ | 0.0 КБ | — | — | Паритет лидеров |
| ULID: разбор строки в объект | 0.0 КБ | — | 0.0 КБ | 0.0 КБ | — | — | Паритет лидеров |
| ULID: генерация до 16 байт (для BINARY-хранения) | 0.0 КБ | — | 0.0 КБ | — | — | — | Паритет лидеров |
| ULID: порядковое сравнение двух значений | 0.0 КБ | — | 0.0 КБ | — | — | — | Паритет лидеров |
| NanoID: генерация 21 символа | 0.0 КБ | — | — | — | 0.0 КБ | — | Паритет лидеров |
| Snowflake: генерация до десятичной строки | 0.0 КБ | — | — | — | — | 0.0 КБ | Паритет лидеров |
| Snowflake: разбор идентификатора на поля | 0.0 КБ | — | — | — | — | 0.0 КБ | Паритет лидеров |
Плюсы CloudCastle Uuid:
- Единственный пакет с пятью семействами идентификаторов сразу: UUID 1–8, ULID, NanoID, Snowflake, Sonyflake.
- PSR-20 часы во всех временных генераторах — полный детерминизм в тестах без глобальных моков.
- Байтовая модель значений:
toBytes()/compareTo()/мост UUID↔ULID без перекодирования. - Полная валидация на границе и экранирование управляющих символов в сообщениях ошибок.
- Одна runtime-зависимость (интерфейс
psr/clock).
Минусы (честно):
- Разбор строки в объект медленнее ramsey/uuid и robinvdvleuten/ulid: они возвращают ленивые обёртки без немедленного декодирования и полной валидации — мы сразу материализуем и проверяем 16 байт. Это два единственных сценария из тринадцати, где пакет не первый.
Когда какую библиотеку выбирать:
- CloudCastle Uuid — нужны несколько семейств идентификаторов, тестируемость времени (PSR-20), BINARY-хранение, честная валидация ввода.
- ramsey/uuid — глубокая экосистема Doctrine-типов и legacy-интеграций только вокруг UUID.
- symfony/uid — вы уже в Symfony-стеке и нужен только UUID/ULID со строковым выводом.
- robinvdvleuten/ulid — минимальный ULID-генератор без валидации диапазона и бинарной формы.
- hidehalo/nanoid-php — только NanoID, без остальных семейств.
- godruoyi/php-snowflake — только Snowflake/Sonyflake, с Redis/Laravel-резолверами последовательности.
CloudCastle Uuid · · PHP 8.1+
GitHub · Packagist · Releases · Discussions · Issues
Email · Telegram · VK · Сетка · 💜 Поддержать проект
Исходники Wiki — каталог wiki/ в репозитории (синхронизация через GitHub Actions)