微秒级时间戳是否总是唯一的?

15

uniqid()在PHP中根据微秒级的时间戳生成唯一的ID。那真的是生成唯一ID的绝对可靠的方法吗?

即使假设只有一个用户运行单个脚本,并使用循环生成微秒级时间戳,是否仍然可以理论上保证它是唯一的?实际上,这种情况的可能性完全可以忽略不计吗?

为了明确起见,假设您的循环仅如下所示:

foreach($things as $thing){
    var_dump(microtime());
}

在理论上,它可能不是唯一的,如果是这样,在实践中它有多现实呢?


2
这取决于你的循环运行速度有多快。 - Oliver Charlesworth
2个回答

18

微秒级别的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是一个很好的选择(因为它们是为此目的而设计的)。


我没有立即使用它的需求,只是出于好奇。非常感谢您详细的回答并链接 UUID 文章。 - vanamerongen

3

首先要思考为什么需要uniqid。例如,我会将uniqid作为我的网站上传文件的文件名。因为可能有多个用户同时上传文件,所以我担心的是两个或多个文件的id相同。但我知道每个用户一次只能上传一个文件。所以,我在文件名前面加上用户名,这样就保证了唯一性。

echo uniqid('username-'); // username-5621e3335ac0c

当然,您应该始终问自己是否需要首先使用uniquid。 如果您知道创建id的原因只能每x秒,分钟等发生一次,则可以以相同方式创建id,只需使用时间:

echo 'username-'.time(); // username-1445062025

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接