uniqid()在PHP中根据微秒级的时间戳生成唯一的ID。那真的是生成唯一ID的绝对可靠的方法吗?
即使假设只有一个用户运行单个脚本,并使用循环生成微秒级时间戳,是否仍然可以理论上保证它是唯一的?实际上,这种情况的可能性完全可以忽略不计吗?
为了明确起见,假设您的循环仅如下所示:
foreach($things as $thing){
var_dump(microtime());
}
在理论上,它可能不是唯一的,如果是这样,在实践中它有多现实呢?
uniqid()在PHP中根据微秒级的时间戳生成唯一的ID。那真的是生成唯一ID的绝对可靠的方法吗?
即使假设只有一个用户运行单个脚本,并使用循环生成微秒级时间戳,是否仍然可以理论上保证它是唯一的?实际上,这种情况的可能性完全可以忽略不计吗?
为了明确起见,假设您的循环仅如下所示:
foreach($things as $thing){
var_dump(microtime());
}
在理论上,它可能不是唯一的,如果是这样,在实践中它有多现实呢?
微秒级别的ID仅在一定范围内保证唯一性。对于单线程脚本在单台计算机上运行,这方面可能是相当安全的。然而,一旦你开始谈论并行执行,无论是在同一台机器上的多个CPU还是跨越多台机器,所有赌注都是没有保障的。
因此,这取决于您想要使用此ID的目的。如果您只是使用它来生成一个仅在同一脚本中使用的ID,则可能足够安全。例如:
<?php $randomId = uniqid(); ?>
<div id="<?php echo $randomId; ?>"></div>
<script>
var div = document.getElementById('<?php echo $randomId; ?>');
...
</script>
在这种有限的使用情况下,您很可能不会遇到任何问题。
然而,如果您开始使用uniqid
或其他与外部脚本共享的用途来生成文件名,我不会依赖它。对于文件名,使用基于文件内容的哈希可能是一个好主意。对于通用分散式随机生成的ID,UUIDs是一个很好的选择(因为它们是为此目的而设计的)。
首先要思考为什么需要uniqid。例如,我会将uniqid作为我的网站上传文件的文件名。因为可能有多个用户同时上传文件,所以我担心的是两个或多个文件的id相同。但我知道每个用户一次只能上传一个文件。所以,我在文件名前面加上用户名,这样就保证了唯一性。
echo uniqid('username-'); // username-5621e3335ac0c
当然,您应该始终问自己是否需要首先使用uniquid。 如果您知道创建id的原因只能每x秒,分钟等发生一次,则可以以相同方式创建id,只需使用时间:
echo 'username-'.time(); // username-1445062025