如何为用户上传的图像创建唯一的名称?
我不想有任何重复,因此类似于MD5($filename)的方法不适用。
有什么好的建议吗?
正如之前提到的,我认为创建唯一文件名的最佳方式是简单地添加time()。就像这样:
$image_name = time()."_".$image_name;
$ext = pathinfo($uploaded_filename, PATHINFO_EXTENSION);
精确到秒的时间获取:time()
获取一些随机数:md5(microtime())
将时间转换为36进制:base_convert (time(), 10, 36)
- 36进制可以将一个10字节的字符串压缩到约6字节,以便更多地使用随机字符串
将所有内容发送出去作为16个字符的字符串:
$unique_id = substr( base_convert( time(), 10, 36 ) . md5( microtime() ), 0, 16 ) . $ext;
我认为那不太可能发生冲突 - 如果您不介意文件名很长,甚至可以不截断它。
tempnam()
,它可以创建一个具有唯一文件名的文件,并将访问权限设置为0600,放在指定的目录中。让PHP来处理独特性的工作。请注意,tempnam()
不仅返回文件名,而且实际上还创建了文件;当你放置图像文件时,你可以直接覆盖它。您可以对图像数据本身进行哈希处理(例如md5,sha)。这有助于识别重复图像(如果它们是逐字节相同的)。但是,任何足够长的随机字符字符串都可以使用。
您始终可以通过某种方式操纵文件名,使其看起来像:
/image/0/1/012345678/original-name.jpg
这样文件名看起来很正常,但仍然是唯一的。
sha1_file()
而不是md5_file()
。它更不容易发生碰撞。
你也可以使用hash_file('sha256', $filePath)
来获得更好的结果。哈哈,MD5算法可以产生大约63340000000000000000000000000000000000000000000000种可能性。此外,为了保险起见,您还可以使用它。
$newfilename = md5(time().'image');
if(file_exists('./images/'.$newfilename)){
$newfilename = md5(time().$newfilename);
}
//uploadimage
对于短名称:
$i = 0;
while(file_exists($name . '_' . $i)){
$i++;
}
警告:如果两个用户同时上传具有相同名称的图像,则在多线程服务器上可能会失败。在这种情况下,您应该包括用户名的md5。
两个用户在同一微秒上传具有相同名称的图像的概率有多大?
尝试
$currTime = microtime(true);
$finalFileName = cleanTheInput($fileName)."_".$currTime;
// you can also append a _.rand(0,1000) in the end to have more foolproof name collision
function cleanTheInput($input)
{
// do some formatting here ...
}
这也有助于您跟踪文件上传时间以进行分析,或者可能对文件进行排序、管理。
http://php.net/manual/zh/function.uniqid.php 可能是一个不错的选择?
为了获得良好的性能和独特性,您可以采用以下方法:
文件将存储在服务器上,名称类似于md5_file($file).jpg
定义存储文件的目录是通过剥离第一个字符(第一级)和第二个字符(第二级)来从MD5文件名中确定的,例如:
uploaded_files\30\c5\30c567139b64ee14c80cc5f5006d8081.pdf
在数据库中创建记录,包括文件ID、原始文件名、上传用户ID以及文件在服务器上的路径。
在服务器端创建脚本,用于提供下载角色 - 它将从数据库中按ID获取文件,并输出其内容以及用户提供的原始文件名(参见CodeIgniter download_helper的PHP示例)。因此,文件的URL将如下所示:
优点:
压缩冲突威胁
在文件查找方面表现良好(一个目录中没有太多文件,在同一级别上没有太多目录)
原始文件名被保存
您可以通过服务器端脚本(检查会话或cookie)调整对文件的访问权限
缺点: