没有任何东西能保证100%的独特性。
你需要知道独特性与什么进行比较。
并使用任何算法加上检查所有已使用值列表中的每个值。
在编程世界中,你需要的是所谓的“伪随机”数字。因此它的名称实际上解释了我的意思。
数据库系统在创建类似于MySQL的auto_increment
这样的数字时使用独占锁,以处理并发和其他许多复杂细节。
您必须以同样的方式来解决问题 - 从PHP进程获取锁,通过某种持久存储查找当前值,将其增加1,返回并释放锁。
最简单的方法是使用一个老式的文件和独占锁。
我将用一个类进行说明(应该进行调试,因为它不完整):
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;
}
}
使用方法:
$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
}
kernel.pid_max
时几乎不可能)。<?
function getUniqueID() {
return time() . '.' . getmypid();
}
?>
function getserial()
{
$fn='/where_you_want/serial.dat';
$fp = fopen($fn, "r+");
if (flock($fp, LOCK_EX)) { $serial=fgets($fp);$serial++; }
else
{ print('lock error, ABORT'); exit; }
$h=fopen($fn.'.tmp','w'); fwrite($h,$serial);fclose($h);
if (filesize($fn.'.tmp')>0)
{
system('rm -f '.$fn.'.tmp');
fseek ($fp, 0);
fwrite($fp,$serial);
}
flock($fp, LOCK_UN); fclose($fp); @chmod($fn,0777);
return $serial;
}
这个示例将为您获取一个唯一的序列号,之后,您可以确定它只存在一个实例。请注意,在避免数据损坏的情况下,您必须首先创建文件并首先放置一个数字。(例如,写入1而不输入或其他任何内容)
这是一个非常简单的功能,但我现在已经使用它超过10年了...
你可以自己设定递增值来确保100%的唯一性,而无需使用复杂的算法:
会话唯一标识:
session_start();
$_SESSION['increment'] = 5;//i fix 5 but you need to get it in bdd,xml,...
function get_new_id(){
$_SESSION['increment']++;
//store new value of increment
return $_SESSION['increment'];
}
$my_unique_id = get_new_id();
echo $my_unique_id;
function get_new_id(){
$increment = file_get_contents('increment.txt');
$increment++;
file_put_contents('increment.txt', $increment);
return $increment;
}
$my_unique_id = get_new_id();
echo $my_unique_id;
function get_new_id(){
$increment = file_get_contents('increment.txt');
$increment++;
file_put_contents('increment.txt', $increment);
return $increment;
}
$my_unique_id = get_new_id();
echo $my_unique_id;
- Benjamin Poignant
microtime(true)
并将其小数部分附加到整数部分,这将在大多数情况下为您提供一个唯一的值,实际上。 - Tejeshuniqid
实际上是做什么的?你可以将十六进制值转换为十进制。 - Gumbo