<?php
/*
Author: Silviu Schiau (@sschiau on Twitter)
Web: www.schiau.co
File: Particle.php
Created: 1364036124000 (UNIX Time)
Modified: 1378831167000 (UNIX Time)
About: PHP implementation of Twitter Snowflake ID Generator (Extended to 42bits epoch for 96 years 1 month 21 days 16 hours 42 minutes 24 seconds in the future)
License: Apache License Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt
Thanks to Twitter for Snowflake.
This header should NOT be removed if you want to use Particle.
*/
class Particle
{
const EPOCH=1378831167000;
final public function generateParticle($machine_id)
{
//Time - 42 bits (millisecond precision w/ a custom epoch gives us 96 years 1 month 21 days 16 hours 42 minutes 24 seconds in the future)
$time = floor(microtime(true) * 1000);
//Substract custom epoch from current time
$time -= self::EPOCH;
//Add to base
$base = pow(2,41);
$base += $time;
$base = decbin($base);
//configured machine id - 10 bits - to 1024 machines
$machineid = decbin($machine_id);
//sequence number - 12 bits - up to 4096 random numbers per machine
$random = mt_rand(0,pow(2,12)-1);
$random = decbin($random);
//Pack
$base = $base.$machineid.$random;
return base_convert($base,2,10);
}
final public function timeFromParticle($particle)
{
return base_convert(substr(base_convert($particle,10,2),0,42),2,10)-pow(2,41)+self::EPOCH;
}
}
function getId($machine_id = 0, $sleep = true) {
// Without sleeping 1ms two elements created at the very
// same time will collide when generated on the same machine
if ($sleep) {
usleep(1000);
}
$particle = new Particle;
return $particle->timeFromParticle($particle->generateParticle($machine_id));
}
// We need to verify that there are no ID conflicts
echo "Same machine same time\n";
echo getId(1, false) . "\n";
echo getId(1, false) . "\n";
echo getId(1, false) . "\n";
echo getId(1, false) . "\n";
echo getId(1, false) . "\n";
echo getId(1, false) . "\n";
echo "Different machine same time\n";
echo getId(10, false) . "\n";
echo getId(20, false) . "\n";
echo getId(30, false) . "\n";
echo getId(10, false) . "\n";
echo getId(20, false) . "\n";
echo getId(30, false) . "\n";
echo "Same machine different time\n";
echo getId(1) . "\n";
echo getId(1) . "\n";
echo getId(1) . "\n";
echo getId(1) . "\n";
echo getId(1) . "\n";
echo getId(1) . "\n";
Same machine same time
1671750942004
1671750942005
1671750942005
1671750942005
1671750942005
1671750942005
Different machine same time
1671750942005
1671750942005
1671750942005
1671750942005
1671750942005
1671750942005
Same machine different time
1671750942006
1671750942007
1671750942008
1671750942009
1671750942010
1671750942011
Output for git.master_jit
Same machine same time
1671750942004
1671750942004
1671750942004
1671750942004
1671750942004
1671750942004
Different machine same time
1671750942004
1671750942004
1671750942004
1671750942004
1671750942004
1671750942004
Same machine different time
1671750942005
1671750942006
1671750942007
1671750942008
1671750942009
1671750942010
This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.