Twitter Snowflake for PHP implementation.
composer require chivincent/snowflake
<?php
require __DIR__ . '/vendor/autoload.php';
use Chivincent\Snowflake\Snowflake;
$snowflake = new Snowflake();
// Generate single unique ID.
$snowflake(); // It will return int.
$snowflake->gen(); // It will return an array with single element.
// Generate 10 unique IDs
$snowflake->gen(10);
// Generate 1000 unique IDs
$snowflake->gen(1000);
It is an array contains 1 or more 64 bits integer, which can be store in MySQL as bigint data type.
The value is generated by millisecond, machine id and sequence number.
When use it on more then one machine , you should set MACHINE_ID
(0 ~ 8191) as your local environment.
In the same millisecond, it will use Sequence for promising the value is unique.
+---------------------------------+----------------------+-------------------+
| millisecond timestamp (41 bits) | machine id (13 bits) | sequence (9 bits) |
+---------------------------------+----------------------+-------------------+
You can reset this data storage for machine id and sequence when construct Chivincent\Snowflake\Snowflake
<?php
require __DIR__ . '/vendor/autoload.php';
use Chivincent\Snowflake\Snowflake;
use Chivincent\Snowflake\StaticSequence;
$snowflake = new Snowflake(StaticSequence::class, 14, 8);
// The machine id length is 14 bits.
// The sequence length is 8 bits.
// Note: The sum of machine id length and sequence length should be 22.
Unfortunately, it is possible.
This package is using static
variable for controlling sequence, but it could be repeat in different requests.
Make a sequence class which implements Chivincent\Snowflake\Sequencer
interface, you can define the static method next
for generating sequence by redis or memcached.
Example:
<?php
namespace MyAwesome\Project;
use Chivincent\Snowflake\Sequencer;
class RedisSequence implements Sequencer
{
protected $redis;
public static function next(int $timestamp): int
{
if (!$redis->timestampExists($timestamp)) {
$redis->insertCurrentTimestamp($timestamp);
return 0;
}
if ($redis->isLimit()) {
return self::WAIT_FOR_NEXT_TIME;
}
return $redis->getNextNumber();
}
}
// Use your RedisSequence when Snowflake's constructor.
new Snowflake(RedisSequence::class);
This library is under MIT LICENSE.