为我的用户上传的图片创建唯一名称的好方法是什么?
我不想有任何重复项,所以像MD5($ filename)这样的东西不合适。
有什么想法吗?
答案 0 :(得分:15)
如上所述,我认为创建唯一文件名的最佳方法是简单地添加time()。就像
$image_name = time()."_".$image_name;
答案 1 :(得分:6)
从上传的文件中抓取文件扩展名:
$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;
我怀疑它会不会发生碰撞 - 如果你不介意很长的文件名,你甚至不能截断它。
答案 2 :(得分:4)
如果你确实需要一个文件名(你的问题并不完全清楚),我会使用tempnam()
,其中:
在指定目录中创建具有唯一文件名的文件,其访问权限设置为0600。
...让PHP完成解决唯一性的繁重工作。请注意,除了返回文件名,tempnam()
实际上创建了文件;你可以在那里删除图像文件时覆盖它。
答案 3 :(得分:2)
您可以获取图像数据本身的哈希值(例如,md5,sha)。这也有助于识别重复的图像(如果它是逐字节的,相同的)。但任何足够长的随机字符串都可以。
您始终可以采用文件名的方式进行装配:
/image/0/1/012345678/original-name.jpg
这样文件名看起来很正常,但它仍然是唯一的。
答案 4 :(得分:1)
我建议sha1_file()
超过md5_file()
。它不太容易发生碰撞。
您还可以使用hash_file('sha256', $filePath)
来获得更好的结果。
答案 5 :(得分:0)
http://php.net/manual/en/function.uniqid.php也许?
答案 6 :(得分:0)
$newfilename = md5(time().'image');
if(file_exists('./images/'.$newfilename)){
$newfilename = md5(time().$newfilename);
}
//uploadimage
答案 7 :(得分:0)
简称:
$i = 0;
while(file_exists($name . '_' . $i)){
$i++;
}
警告:如果两个用户同时上传具有相同名称的图像,则多线程服务器上的此操作可能会失败。 在这种情况下,您应该包含用户名的md5。
答案 8 :(得分:0)
两个用户在相同的微秒上上传同名图像的概率有多大?
试
$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 ...
}
这也可以帮助您跟踪文件的上传时间以进行分析。或者可以对文件进行排序,管理文件。
答案 9 :(得分:0)
为了获得良好的性能和独特性,您可以使用以下方法:
文件将存储在名称为md5_file($file).jpg
存储文件的目录,从md5文件名定义,通过剥离前两个字符(第一级)和第二个二级(第二级),如下所示:
uploaded_files \ 30 \ c5 \ 30 c5 67139b64ee14c80cc5f5006d8081.pdf
使用file_id,原始文件名,上传的用户ID和服务器上的文件路径在数据库中创建记录
在服务器端创建脚本,它将获得下载提供的角色 - 它将从db获取id的文件,并使用用户提供的原始文件名输出其内容(请参阅codeigniter {{3}的php示例})。所以url to file看起来像那样:
优点:
缩小碰撞威胁
在文件查找方面表现良好(1个目录中的文件不多,同一级别的目录不多)
原始文件名已保存
您可以通过服务器端脚本调整对文件的访问权限(检查会话或Cookie)
缺点:
答案 10 :(得分:0)
尝试以下文件格式:
$filename = microtime(true) . $username . '.jpg';
答案 11 :(得分:0)
这样的事可能适合你:
while (file_exists('/uploads/' . $filename . '.jpeg')) {
$filename .= rand(10, 99);
}
答案 12 :(得分:0)
我认为这对您有好处。
<?php
$name=uniqid(mt_rand()).$image_name;
?>
答案 13 :(得分:0)
您应该尝试实现两个目标:唯一性和有用性。
使用GUID可以保证唯一性,但是有一天,文件可能会与原始来源分离,然后就会遇到麻烦。
我典型的解决方案是将关键信息嵌入文件名中,例如userID(如果它属于用户)或上传的日期和时间(如果重要)或上传文件时使用的文件名。
例如,当文件名中嵌入的信息使您能够从错误中恢复或意外删除记录时,这可能真的可以节省一天的时间。如果您只拥有GUID,并且丢失了目录,那么您将很难进行清理。
例如,如果用户ID 98765在2013/04/04 12:51:23上载了文件“我的假期:佛罗里达州23.jpg”,则我会这样命名,并添加一个随机字符串ad8a7dsf9 :
20130404125123-ad8a7dsf9-98765-my-holiday-florida-23.jpg
唯一性由日期和时间以及随机字符串(只要它是从/ dev / urandom或CryptGenRandom正确随机提供的)来确保。 如果文件曾经分离过,则可以标识用户,日期和时间以及标题。 一切都折叠成小写,任何非字母数字都被删除并用破折号代替,这使得文件名易于使用简单的工具处理(例如,没有空格可能会使书写不良的脚本迷惑,没有冒号或其他字符在某些文件系统上被禁止) ,依此类推)。
答案 14 :(得分:-2)
即用型代码:
$file_ext = substr($file['name'], -4); // e.g.'.jpg', '.gif', '.png', 'jpeg' (note the missing leading point in 'jpeg')
$new_name = sha1($file['name'] . uniqid('',true)); // this will generate a 40-character-long random name
$new_name .= ((substr($file_ext, 0, 1) != '.') ? ".{$file_ext}" : $file_ext); //the original extension is appended (accounting for the point, see comment above)