PHP生成唯一ID之SnowFlake算法

发布时间 - 2026-01-10 21:53:48    点击率:

前言:最近需要做一套CMS系统,由于功能比较单一,而且要求灵活,所以放弃了WP这样的成熟系统,自己做一套相对简单一点的。文章的详情页URL想要做成url伪静态的格式即xxx.html 其中xxx考虑过直接用自增主键,但是感觉这样有点暴露文章数量,有同学说可以把初始值设高一点,可是还是可以通过ID差算出一段时间内的文章数量,所以需要一种可以生成唯一ID的算法。

考虑过的方法有

  1. 直接用时间戳,或者以此衍生的一系列方法
  2. Mysql自带的uuid

以上两种方法都可以查到就不多做解释了

最终选择了Twitter的SnowFlake算法

这个算法的好处很简单可以在每秒产生约400W个不同的16位数字ID(10进制)

原理很简单

ID由64bit组成

其中 第一个bit空缺

41bit用于存放毫秒级时间戳

10bit用于存放机器id

12bit用于存放自增ID

除了最高位bit标记为不可用以外,其余三组bit占位均可浮动,看具体的业务需求而定。默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id。
下面是PHP源码

<?php
namespace App\Services;

abstract class Particle {
  const EPOCH = 1479533469598;
  const max12bit = 4095;
  const max41bit = 1099511627775;

  static $machineId = null;

  public static function machineId($mId = 0) {
    self::$machineId = $mId;
  }

  public static function generateParticle() {
    /*
    * Time - 42 bits
    */
    $time = floor(microtime(true) * 1000);

    /*
    * Substract custom epoch from current time
    */
    $time -= self::EPOCH;

    /*
    * Create a base and add time to it
    */
    $base = decbin(self::max41bit + $time);


    /*
    * Configured machine id - 10 bits - up to 1024 machines
    */
    if(!self::$machineId) {
      $machineid = self::$machineId;
    } else {
      $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT);
    }
    
    /*
    * sequence number - 12 bits - up to 4096 random numbers per machine
    */
    $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT);

    /*
    * Pack
    */
    $base = $base.$machineid.$random;

    /*
    * Return unique time id no
    */
    return bindec($base);
  }

  public static function timeFromParticle($particle) {
    /*
    * Return time
    */
    return bindec(substr(decbin($particle),0,41)) - self::max41bit + self::EPOCH;
  }
}

?>

调用方法如下

Particle::generateParticle($machineId);//生成ID
Particle::timeFromParticle($particle);//反向计算时间戳

这里我做了改良 如果机器ID传0 就会去掉这10bit 因为有些时候我们可能用不到这么多ID


# php  # 生成唯一id算法  # 唯一id生成算法  # 分布式唯一id生成算法  # 使用PHP uniqid函数生成唯一ID  # PHP之uniqid()函数用法  # PHP实现会员账号单唯一登录的方法分析  # PHP实现的生成唯一RequestID类完整示例  # 完美解决thinkphp唯一索引重复时出错的问题  # 3种php生成唯一id的方法  # PHP实现生成唯一会员卡号  # PHP生成唯一订单号  # PHP随机生成唯一HASH值自定义函数  # PHP生成唯一订单号的方法汇总  # 高并发php uniqid不重复唯一标识符生成方案  # 很简单  # 就会  # 第一个  # 就不  # 这么多  # 两种  # 时间内  # 可以通过  # 均可  # 自带  # 而定  # 多做  # 不可用  # 三组  # 方法如下  # 高一点  # 主键  # 情况下  # 选择了  # 详情页 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 详解Huffman编码算法之Java实现  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  怎样使用JSON进行数据交换_它有什么限制  Laravel如何使用Service Container和依赖注入?(代码示例)  UC浏览器如何设置启动页 UC浏览器启动页设置方法  Python3.6正式版新特性预览  如何在建站宝盒中设置产品搜索功能?  高端建站三要素:定制模板、企业官网与响应式设计优化  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  iOS发送验证码倒计时应用  Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决  Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  智能起名网站制作软件有哪些,制作logo的软件?  如何安全更换建站之星模板并保留数据?  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  iOS中将个别页面强制横屏其他页面竖屏  如何彻底卸载建站之星软件?  Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置  Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案  Swift开发中switch语句值绑定模式  Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境  如何在IIS中新建站点并配置端口与物理路径?  b2c电商网站制作流程,b2c水平综合的电商平台?  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  javascript中闭包概念与用法深入理解  Laravel如何与Inertia.js和Vue/React构建现代单页应用  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  如何快速完成中国万网建站详细流程?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】  详解Android中Activity的四大启动模式实验简述  如何在IIS中新建站点并配置端口与IP地址?  微信小程序 input输入框控件详解及实例(多种示例)  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲  Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  Python文件操作最佳实践_稳定性说明【指导】  Laravel怎么实现支付功能_Laravel集成支付宝微信支付  Linux后台任务运行方法_nohup与&使用技巧【技巧】  Laravel如何使用Gate和Policy进行授权?(权限控制)  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案  如何在阿里云购买域名并搭建网站?  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中