SnowFlake.php 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. namespace app\common\library;
  3. /**
  4. * 雪花ID生成类
  5. */
  6. class SnowFlake
  7. {
  8. /**
  9. * 起始时间戳
  10. * @var int
  11. */
  12. const EPOCH = 1672502400000;
  13. /**
  14. * @var int
  15. */
  16. const max41bit = 1099511627775;
  17. /**
  18. * 机器节点 10bit
  19. * @var int
  20. */
  21. protected static int $machineId = 1;
  22. /**
  23. * 序列号
  24. * @var int
  25. */
  26. protected static int $count = 0;
  27. /**
  28. * 最后一次生成ID的时间偏移量
  29. * @var int
  30. */
  31. protected static int $last = 0;
  32. /**
  33. * 设置机器节点
  34. * @param int $mId 机器节点id
  35. * @return void
  36. */
  37. public static function setMachineId(int $mId): void
  38. {
  39. self::$machineId = $mId;
  40. }
  41. /**
  42. * 生成雪花ID
  43. * @return float|int
  44. */
  45. public static function generateParticle(): float|int
  46. {
  47. // 当前时间 42bit
  48. $time = (int)floor(microtime(true) * 1000);
  49. // 时间偏移量
  50. $time -= self::EPOCH;
  51. // 起始时间戳加上时间偏移量并转为二进制
  52. $base = decbin(self::max41bit + $time);
  53. // 追加节点机器id
  54. if (!is_null(self::$machineId)) {
  55. $machineId = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT);
  56. $base .= $machineId;
  57. }
  58. // 序列号
  59. if ($time == self::$last) {
  60. self::$count++;
  61. } else {
  62. self::$count = 0;
  63. }
  64. // 追加序列号部分
  65. $sequence = str_pad(decbin(self::$count), 12, "0", STR_PAD_LEFT);
  66. $base .= $sequence;
  67. // 保存生成ID的时间偏移量
  68. self::$last = $time;
  69. // 返回64bit二进制数的十进制标识
  70. return bindec($base);
  71. }
  72. }