random_int() 仍是生成安全整数的最简选择,Random扩展是补充而非替代;Randomizer提供可测试、可配置的面向对象随机数抽象,支持加密安全引擎与固定种子测试,但不替代array_rand()或shuffle()。

random_int() 是当前最简明安全的选择,Random 扩展不是替代它,而是补充
PHP 8.2 新增的 Random 扩展(全名 ext-random)并不是为了取代 random_int(),而是提供更灵活、可配置、可测试的随机数抽象层。它默认仍基于操作系统熵源(/dev/urandom 或 CryptGenRandom),安全性不打折扣,但多了一层面向对象封装和可替换引擎的能力。
如果你只是生成一个密码重置 token 或验证码整数,继续用 random_int(1, 999999) 完全没问题——它更轻、更直接、无需实例化、无额外依赖。
Random\Randomizer 的价值出现在这些场景里:
- 需要为单元测试注入可控的伪随机行为(比如固定种子重现某次“抽奖失败”)
- 需同时支持多种策略:加密安全生成 + 可预测调试模式 + 性能敏感的快速伪随机(如游戏模拟)
- 要统一管理随机行为(例如全局设置一个
Randomizer实例供多个类复用,避免重复调用系统熵源)
如何用 Randomizer 生成加密安全整数或字符串
它不直接提供 random_int() 那样的函数式接口,所有操作都通过 Random\Randomizer 实例完成。默认构造即启用加密安全引擎:
立即学习“PHP免费学习笔记(深入)”;
<?php $rand = new Random\Randomizer(); echo $rand->getInt(1, 100); // 闭区间,含 1 和 100 echo $rand->getBytes(16); // 返回 string,等价于 random_bytes(16) ?>
注意两点:
-
getInt($min, $max)参数顺序和random_int()一致,$min > $max会抛出ValueError,不会自动交换 - 它没有内置“生成六位数字字符串”的快捷方法;要补零得自己处理:
sprintf('%06d', $rand->getInt(0, 999999))
测试时用 FixedBitGenerator 注入可预测行为
这是 Random 扩展最实用的新能力。你可以在测试中传入一个固定种子的引擎,让每次运行结果完全一致:
<?php // 测试代码 $engine = new Random\Engine\XorShift128Plus(12345); $rand = new Random\Randomizer($engine); var_dump($rand->getInt(1, 6)); // 每次都是同一个数,比如 4 var_dump($rand->getInt(1, 6)); // 还是 4 —— 可重现! ?>
常见翻车点:
- 别在生产环境误用
XorShift128Plus或PCG引擎——它们不加密安全,仅限测试或非敏感模拟 -
FixedBitGenerator是抽象基类,不能直接 new;必须用具体实现如XorShift128Plus - 种子值用 int,别传 float 或字符串,否则构造失败
不要用 Randomizer 替代 array_rand() 或 shuffle()
Random\Randomizer 不提供数组抽样或洗牌方法。它只管“生成随机数”,不封装业务逻辑。想从数组取一个键?还是得用 array_rand($arr, 1);想打乱顺序?shuffle($arr) 内部仍调用 mt_rand()(PHP 8.2 起已改用 Randomizer 重构,但用户无需感知)。
真正容易被忽略的是:即使启用了 Random 扩展,mt_rand() 和 rand() 依然存在且行为不变——它们没被禁用,也没被静默升级。该废弃的还得手动替换,不能指望扩展自动接管。



















