应改用 ulid/php-ulid:该包是 robinvdvleuten/ulid 的官方替代,兼容 PHP 7.4–8.3 和 Composer 2.5+,生成的 Ulid 对象可直接字符串排序,支持安全解析时间戳,避免废弃包导致的安装失败与运行时错误。

直接装不上,是因为 robinvdvleuten/ulid 已废弃,且不兼容 PHP 8.1+ 和 Composer 2.5+ 默认行为。
composer require robinvdvleuten/ulid 报错:package not found 或 version conflict
这个包早在 2021 年就标记为 abandoned,Packagist 上已重定向到 ulid/php-ulid。Composer 会拒绝安装被废弃的包(除非显式加 --with-all-dependencies,但不推荐)。
- 运行
composer require robinvdvleuten/ulid时,Composer 会返回类似Package robinvdvleuten/ulid is abandoned, you should avoid using it.的警告,并可能中止 - 即使强制安装,它依赖的
ramsey/uuidv3 和paragonie/random_compat在新 PHP 版本下会触发弃用警告或 fatal error - 它生成的 ULID 是字符串,但没内置排序比较逻辑,实际用起来容易误以为“有序”而忽略时间戳解析
改用 ulid/php-ulid:安装、生成与排序的正确姿势
官方推荐替代是 ulid/php-ulid,纯 PHP 实现、无外部依赖、支持 PHP 7.4–8.3,且默认生成的 Ulid 对象可直接用于数据库排序(因为底层按字节序编码时间戳)。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 执行
composer require ulid/php-ulid即可安装(无需额外参数) - 生成 ID:
$ulid = \Ulid\Ulid::generate(); echo $ulid->toBase32();→ 输出类似01HQX2GQYKZQVZ6ZQYQZQVZ6ZQ - 要保证“有序”,必须用对象本身或
toBinary()/toBase32()结果做字符串比较(它们天然按时间前缀排序),不要转成时间戳再比 - 若存入 MySQL,建议字段类型为
VARCHAR(26)(Base32 固定长度),并加索引;避免用TEXT或未索引字段,否则排序性能崩塌
PHP 里手动解析 ULID 时间戳?别绕路,用内置方法
有人想从 ULID 字符串里提取生成时间做条件查询,结果手写 Base32 解码 + 位运算,极易出错。其实 ulid/php-ulid 提供了安全解析接口。
- 从字符串重建对象:
$ulid = \Ulid\Ulid::fromString('01HQX2GQYKZQVZ6ZQYQZQVZ6ZQ'); - 获取时间:
$ulid->getTime();返回DateTimeImmutable,可直接格式化或比较 - 错误场景:传入非法 Base32 字符串(如含小写
i、l、o、u)会抛\Ulid\Exception\InvalidUlidException,需 try/catch - 注意:ULID 时间精度是毫秒,不是微秒;同一毫秒内并发生成多个 ULID 时,后缀随机部分保证唯一,但时间值相同
真正麻烦的是跨服务时间同步——如果机器时钟回拨或 NTP 漂移超过 1ms,ULID 时间部分就不可靠了。这时候与其硬调时钟,不如在业务层加一层序列号兜底,或者直接切到 Snowflake 类方案。

















