Search by

mitoop / snowflake

Mitoop

snowflake

Package info

github.com/mitoop/snowflake

pkg:composer/mitoop/snowflake

Statistics

Installs: 314

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 1

v1.0.3 2026-10-24 08:14 UTC

This package is auto-updated.

Last update: 2026-10-24 08:15:41 UTC


README

64 位雪花算法的 PHP 实现。

要求

  • PHP >= 7.0
  • 使用 RedisSequenceStrategy 时需要 phpredis 扩展

安装

composer require mitoop/snowflake

快速开始

use Mitoop\Snowflake\Snowflake;

$snowflake = (new Snowflake('2020-10-24 10:24:00'))
    ->setDatacenterId(1) // 0–31,不设置则每次随机
    ->setWorkerId(1);    // 0–31,不设置则每次随机

$id = $snowflake->id();

默认序列策略是 RandomSequenceStrategy(进程内随机序列号)。多机 / 多进程要保证同一毫秒内不撞号时,请改用 Redis 策略。

Redis 序列策略

use Mitoop\Snowflake\RedisSequenceStrategy;
use Mitoop\Snowflake\Snowflake;
use Redis;

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$snowflake = (new Snowflake('2020-10-24 10:24:00'))
    ->setDatacenterId(1)
    ->setWorkerId(1)
    ->setSequenceStrategy(new RedisSequenceStrategy($redis)); // 可选第二参数:key 前缀,默认 snowflake:

$id = $snowflake->id();

RedisSequenceStrategy 用 Lua 在 Redis 里按毫秒自增序列;key 带 5 秒过期。

若 eval() 返回 false(连接失败、OOM 等),会抛出 RuntimeException,并附带 getLastError() 信息,不会把失败当成序列号 0 继续发号。Redis 客户端自身抛出的异常会原样向上抛。

解析 ID

$parts = $snowflake->parseId($id, true);
// timestamp / datacenter_id / worker_id / sequence(十进制)

第二个参数为 false(默认)时,各字段仍是二进制字符串。

说明

字段 位数 范围
时间戳(相对纪元) 41 —
数据中心 5 0–31
机器 5 0–31
序列号 12 0–4095
  • 纪元时间(构造函数参数)不能晚于当前时间。
  • 生成 ID 长度大约在 7–19 位;把纪元设得更近,ID 会更短。
  • 同一毫秒内序列超过 4095 时会短暂等待下一毫秒再生成。

测试

无需 Composer 依赖即可跑回归测试(-n 禁用扩展,改用 Redis 替身):

composer test
# 或
php -n tests/redis-sequence.php

真实 Redis 集成测试需要 phpredis,以及可丢弃的独立实例(会临时把 maxmemory 设为 1 模拟 OOM,结束后恢复)。不要连共享 / 生产库:

SNOWFLAKE_TEST_REDIS_ISOLATED=1 SNOWFLAKE_TEST_REDIS_PORT=6379 composer test:redis

License

MIT