11

PHP 中的 uniqid() 根据当前时间戳(以微秒为单位)生成唯一 ID。这真的是生成唯一 ID 的万无一失的方法吗?

即使假设有一个用户运行单个脚本,并且循环生成以微秒为单位的时间戳,是否真的还有理论上的保证它是 unqiue 的?在实践中,这种可能性是否完全可以忽略不计?

为了清楚起见,说你的循环只不过是这样:

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

是否有任何理论上的机会它可能不是独一无二的,如果是这样,它在实践中的现实程度如何?

4

2 回答 2

13

基于微秒的 id​​ 只保证在限制内是唯一的。在这方面,单台计算机上的单线程脚本可能非常安全。但是,一旦您开始谈论并行执行,无论是简单地在同一台机器内的多个 CPU 上,还是特别是在多台机器上,所有的赌注都没有了。

所以这取决于你想用这个 id 做什么。如果您只是使用它来生成仅在同一脚本中使用的 id,那么它可能足够安全。例如:

<?php $randomId = uniqid(); ?>
<div id="<?php echo $randomId; ?>"></div>
<script>
    var div = document.getElementById('<?php echo $randomId; ?>');
    ...
</script>

在这种有限的使用中,您很可能不会遇到任何问题。

但是,如果您开始使用uniqid或与其他外部脚本共享的其他此类用途生成文件名,我不会依赖它。对于文件名,使用基于文件内容的哈希可能是个好主意。对于通用去中心化随机生成的 id,UUID非常适合(因为它们是为此目的而设计的)。

于 2014-11-12T09:05:28.973 回答
2

首先问问自己为什么需要 uniqid。例如,我使用 uniquid 作为上传到我网站的文件名。可以有任意数量的用户同时上传,所以我关心的是两个或多个具有相同 id 的文件,但我知道一个用户一次只能上传一个文件。因此,我将用户名放在前面,并且始终具有唯一性。

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

当然,您应该始终问自己是否需要首先使用 uniquid。如果您知道创建 id 的原因只能每 x 秒、分钟等发生一次,那么您可以像使用 time 一样创建 id:

echo 'username-'.time(); // username-1445062025
于 2015-10-17T06:14:57.493 回答