Php 创建唯一的图像名称

Php 创建唯一的图像名称,php,filenames,Php,Filenames,为我的用户正在上载的图像创建唯一名称的好方法是什么 我不想有任何重复,所以像MD5($filename)这样的东西不合适 有什么想法吗?也许 您可以使用用户id作为前缀,以避免两个用户之间的冲突(在不到一毫秒的时间内) lol md5大约可以产生633400000000000000000000000000000000000000000种可能性 另外,为了安全起见,你可以用它 $newfilename = md5(time().'image'); if(file_exists('./images

为我的用户正在上载的图像创建唯一名称的好方法是什么

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

有什么想法吗?

也许

  • 您可以使用用户id作为前缀,以避免两个用户之间的冲突(在不到一毫秒的时间内)

lol md5大约可以产生633400000000000000000000000000000000000000000种可能性 另外,为了安全起见,你可以用它

$newfilename = md5(time().'image');
if(file_exists('./images/'.$newfilename)){
    $newfilename = md5(time().$newfilename);
}
//uploadimage
您可以对图像数据本身进行散列(例如,md5、sha)。这也有助于识别重复的图像(如果是逐字节的,则相同)。但是任何足够长的随机字符串都可以工作

您可以始终以文件名如下所示的方式对其进行装配:

/image/0/1/012345678/original-name.jpg

这样,文件名看起来很正常,但仍然是唯一的。

我建议
sha1\u file()
而不是
md5\u file()
。它不太容易发生碰撞。 您还可以使用
hash_文件('sha256',$filePath)
来获得更好的结果。

对于短名称:

$i = 0;
while(file_exists($name . '_' . $i)){
  $i++;
}
警告:如果两个用户同时上载具有相同名称的图像,则在多线程服务器上可能会失败。
在这种情况下,您应该包括用户名的md5。

如果您确实需要一个文件名(您的问题并不完全清楚),我会使用它:

在指定目录中创建具有唯一文件名且访问权限设置为0600的文件


…让PHP来完成唯一性的繁重工作。请注意,除了返回文件名,
tempnam()
实际上创建了该文件;当你把图像文件放到那里时,你可以直接覆盖它。

两个用户在同一微秒上传同名图像的概率有多大

试一试


这还可以帮助您跟踪文件的上载时间以进行分析。或者可以对文件进行排序、管理文件。

为了获得良好的性能和唯一性,您可以使用以下方法:

  • 文件将存储在名为
    md5\u file($file).jpg的服务器上

  • 要在中存储文件的目录通过剥离前两个字符(第一级)和后两个字符(第二级)定义自md5文件名,如下所示:

    上传的文件\30\c5\30c5 67139b64ee14c80cc5f5006d8081.pdf

  • 使用文件id、原始文件名、上载的用户id和服务器上文件的路径在数据库中创建记录

  • 在服务器端,创建一个脚本,该脚本将扮演下载提供的角色——它将从db中按id获取文件,并使用用户提供的原始文件名输出其内容(参见codeigniter的php示例)。所以文件的url将如下所示:


优点:

  • 缩小碰撞威胁

  • 文件查找性能良好(1个目录中的文件不多,同一级别的目录不多)

  • 保存原始文件名

  • 您可以通过服务器端脚本(检查会话或cookie)调整对文件的访问

缺点:

  • 适用于小文件,因为在用户下载文件之前,服务器必须在内存中读取该文件
尝试以下文件格式:

$filename = microtime(true) . $username . '.jpg';

像这样的东西可能适合你:

while (file_exists('/uploads/' . $filename . '.jpeg')) {
   $filename .= rand(10, 99);
}

如前所述,我认为创建唯一文件名的最佳方法是简单地添加time()。那就像

$image_name = time()."_".$image_name;

从上载的文件中获取文件扩展名:

$ext = pathinfo($uploaded_filename, PATHINFO_EXTENSION);
抓取到秒的时间:
time()

抓住一些随机性:
md5(microtime())

将时间转换为基36:
base\u Convert(time(),10,36)
-基36将10字节的字符串压缩为大约6字节,以允许使用更多的随机字符串

以16个字符的字符串形式发送整个批次:

$unique_id = substr( base_convert( time(), 10, 36 ) . md5( microtime() ), 0, 16 ) . $ext;
我怀疑这会产生冲突-如果您不介意很长的文件名,您甚至无法截断它。

准备使用代码:

$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)

我想这对你有好处

<?php
    $name=uniqid(mt_rand()).$image_name;
 ?>

你应该努力实现两个目标:独特性和实用性

使用GUID可以保证唯一性,但有一天文件可能会从原始源分离,然后您将遇到麻烦

我的典型解决方案是在文件名中嵌入关键信息,例如用户ID(如果它属于用户)或上载的日期和时间(如果这很重要),或者上载时使用的文件名

有一天,当文件名中嵌入的信息允许您(例如)从错误或意外删除记录中恢复时,这可能真的会拯救您的皮肤。如果你所有的都是guid,而你丢失了目录,那么你将有一个非常好的工作来清理它

例如,如果用户ID 98765在2013/04/04 12:51:23上传了一个文件“My Holiday:Florida 23.jpg”,我会将其命名为这样的名称,添加一个随机字符串ad8a7dsf9:

20130404125123-ad8a7dsf9-98765-my-holiday-florida-23.jpg

唯一性由日期和时间以及随机字符串(只要它是从/dev/urandom或CryptGenRandom正确随机的)来保证。 如果文件已分离,则可以标识用户、日期和时间以及标题。
所有内容都折叠成小写,任何非字母数字的内容都被删除并替换为破折号,这使得文件名易于使用简单的工具处理(例如,没有空格会混淆书写糟糕的脚本,没有冒号或某些文件系统上禁止的其他字符,等等).

相同的输入为哈希提供相同的输出。因此,如果问题是输入不唯一(文件名),那么输出也不会是唯一的。不太容易发生冲突?让我们从这里看一看。使用MD5,并考虑生日悖论,您发生冲突的几率小于0。00000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1%有没有办法给出从1,2,3…开始的唯一数字序列,就像它给出的那样A.
<?php
    $name=uniqid(mt_rand()).$image_name;
 ?>