创建唯一的图像名称

时间:2011-03-18 07:28:26

标签: php filenames

为我的用户上传的图片创建唯一名称的好方法是什么?

我不想有任何重复项,所以像MD5($ filename)这样的东西不合适。

有什么想法吗?

15 个答案:

答案 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也许?

  • 您可以在前面添加用户ID,以避免2个用户之间发生冲突(小于1毫秒)。

答案 6 :(得分:0)

lol有大约6334000000000000000000000000000000000000000000 md5可以产生的可能性 另外,你可以使用安全的方式

$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看起来像那样:

    download_helper


优点:

  • 缩小碰撞威胁

  • 在文件查找方面表现良好(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)