I need to generate unique numeric id.
I could use uniqid, but it generates alphanumeric value.
And again I could use time, but there is no guarantee that it will be unique always.
And again I could use the auto increment property of a field in a database to get an unique id, but here we must need a database.
So what can be the best way to generate an unique numeric id?
Nothing can guarantee 100% uniqueness.
You need to know uniqueness comparing with what do you need.
And use any algorythm plus check each value in list of all used values.
In the world of programming what you need is called pseudo random
number. So it's name actually explains what I mean.
Database systems use exclusive locking when creating numbers such as MySQL's auto_increment
which takes care of concurrency and many other intricate details.
You have to approach the problem you have the same way - acquire a lock from the PHP process that's serving the request, look up the current value within some sort of persistent storage, increment it by 1, return it and release the lock.
The easiest way to do this is to use a good old file and exclusive locking.
I'll illustrate with a class (which should be debugged since it's not complete):
class MyAutoIncrement
{
protected $fh = null;
protected $file_path = '';
protected $auto_increment_offset = 1;
public function __construct($file_path, $offset = 1)
{
$this->file_path = $file_path;
$this->auto_increment_offset = $offset;
}
public function autoincrement()
{
if($this->acquire())
{
$current = (int)fread($this->fh);
$next += $this->auto_increment_offset;
fwrite($this->fh, $next);
$this->release();
return $next;
}
return null;
}
public function acquire()
{
$handler = $this->getFileHandler();
return flock($handler, LOCK_EX);
}
public function release($close = false)
{
$handler = $this->getFileHandler();
return flock($handler, LOCK_UN);
if($close)
{
fclose($handler);
$this->fh = null;
}
}
protected function acquireLock($handler)
{
return flock($handler, LOCK_EX);
}
protected function getFileHandler()
{
if(is_null($this->fh))
{
$this->fh = fopen($this->file_path, 'c+');
if($this->fh === false)
{
throw new \Exception(sprintf("Unable to open the specified file: %s", $this->file_path));
}
}
return $this->fh;
}
}
Usage:
$ai = new MyAutoIncrement('/path/to/counter/file.txt');
try
{
$id = $ai->autoincrement();
if(!is_null($id))
{
// Voila, you got your number, do stuff
}
else
{
// We went wrong somewhere
}
}
catch(\Exception $e)
{
// Something went wrong
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With