Php 随机文件名生成函数需要几分钟才能生成唯一的文件名

Php 随机文件名生成函数需要几分钟才能生成唯一的文件名,php,random,filenames,uniqueidentifier,Php,Random,Filenames,Uniqueidentifier,我需要为上传的文件生成唯一的文件名。我将这些名称存储在数据库中,并在生成文件名时进行检查以确保其唯一性。我知道在这个主题上有很多问题,但我想理解的是为什么我的脚本不起作用 这是我获取文件名并检查其唯一性的代码: do { $newName = generateRandomString(10, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'); $stmt = $this->db->p

我需要为上传的文件生成唯一的文件名。我将这些名称存储在数据库中,并在生成文件名时进行检查以确保其唯一性。我知道在这个主题上有很多问题,但我想理解的是为什么我的脚本不起作用

这是我获取文件名并检查其唯一性的代码:

do {
    $newName  = generateRandomString(10, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

    $stmt = $this->db->prepare('SELECT id FROM images WHERE file_name = :newName');
    makeQuery($stmt, array(':newName' => $newName));
    $row = $stmt->fetch(\PDO::FETCH_ASSOC);
} while(!empty($row));
其中
generateRandomString()
是:

function generateRandomString($length, $characters) {
    $randomString = '';

    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }

    return $randomString;
}
函数生成器域字符串($length,$characters){
$randomString='';
对于($i=0;$i<$length;$i++){
$randomString.=$characters[rand(0,strlen($characters)-1)];
}
返回$randomString;
}
现在,当我在数据库中用大约30000个文件名运行这个程序时,返回一个文件名需要几秒钟到几分钟的时间

文件名(0-9a-zA-Z)中使用的字符数与我使用的字符数一样多,长度为10,因此应该有大量潜在的文件名(如果我计算正确的话,大约1070亿)。看起来根本不应该有任何冲突,至少是我得到的所有数字(我分析的一个XDebug配置文件快照说,
generateRandomString()
在返回之前运行了100000次!)

为什么这不起作用?我能做些什么来修复它


编辑:哎呀,我误解了xdebug数据。它不需要100000次函数调用,只需要123502毫秒(所以是时间,不是函数调用)。

我想我已经为您找到了解决方案:


此代码生成的所有ID都是唯一的

此代码存在许多问题:

  • 选择
    ,然后
    插入
    容易出现竞争条件(在两条语句之间,另一个进程插入了相同的ID)。干净的方法是优化地插入一行,并在出现重复的键错误时重试,最好还是使用确定唯一的函数
  • 为每个循环准备一个新语句。干净的方法是准备一次语句,然后使用不同的参数重复执行它。这就是为什么它们被称为准备好的声明
  • 您的实现使用PHP的
    rand()
    函数,根据PHP版本和操作系统的不同,该函数会产生截然不同的随机性。使用
    mt_rand()

我建议您在数据库中创建标识符:请参见我的

链接的资源可能对作者有用,但(1)它不是OP真正想要的;(2)你应该在你的答案中包含解决方案,链接到外部资源。我将
rand()
更改为
mt\u rand()
,并且在数千次上传后没有一个重复的文件名!谢谢你的其他建议。