为上载生成基于时间的唯一文件名,而不会创建竞争条件

时间:2009-08-11 17:19:39

标签: php uniqueidentifier

我正在使用以下代码生成上传文件的唯一文件名

$date = date( 'U' );
$user = $_SERVER[REMOTE_ADDR];
$filename = md5($date.$user);

问题是我想稍后在脚本中再次使用此文件名,但如果脚本需要一秒钟才能运行,那么第二次尝试使用此变量时,我将获得不同的文件名。 / p>

例如,我正在使用上传/调整大小/保存图片上传脚本。该脚本的第一个操作是复制并保存已调整大小的图像,我使用日期函数为其分配唯一的名称。然后脚本处理保存并保存整个上载,并为其指定名称。在脚本结束时($thumb$full是变量),我需要在MySQL数据库中插入我保存上传时使用的文件名。

问题是,有时在大型图像上需要一秒钟以上(或者在此过程中,秒数会发生变化),导致数据库中放入的文件名与文件实际保存的文件名不同。

使用这种命名方法这不是一个好主意吗?

6 个答案:

答案 0 :(得分:5)

AFAIK这是一个命名文件的好方法,虽然我会检查file_exists()并可能使用随机数字。

您需要将该文件名存储在变量中并稍后再次引用它,而不是每次都依赖于该算法。这可以存储在页面加载之间的用户$_SESSION,cookie,GET变量等中。

希望有所帮助

答案 1 :(得分:2)

我建议在会话中存储文件名(根据AI)。如果将其存储在其他变量之一中,最终用户更有可能通过它攻击系统。与rand()连接的用户的MD5将是获取一长串唯一值的好方法。只使用rand()可能会有更高比例的冲突。

我不确定您要上传文件的过程,但处理文件上传的另一种方法是使用PHP的内置处理程序。您可以上传文件,然后使用“安全”方法将上传的文件从临时空间中提取出来。 (此实例中的临时空间可以安全地位于open base dir指令之外,以防止篡改)。 is_uploaded_file()和move_uploaded_file()来自:http://php.net/manual/en/features.file-upload.post-method.php示例2可能会处理您遇到的问题。

如果您正在选择文件名,请务必检查该位置的现有文件。如果以任何形式或形式允许用户输入,请验证并过滤参数以确保其安全。此外,如果存储文件夹可通过Web访问,请确保您也可以使用名称和扩展名。您不希望有人能够上传代码然后能够执行它。这正式导致了BAD活动。

答案 2 :(得分:2)

只想添加php有一个函数来创建标识符:uniqid。您还可以在标识符前加一个字符串(日期可能是?)。

始终验证用户的输入和服务器标题!

答案 3 :(得分:1)

我刚刚发现PHP有一个内置函数,称为tempnam。它甚至可以避免竞争条件。请参阅http://php.net/manual/en/function.tempnam.php

答案 4 :(得分:0)

为什么不使用

$filename = md5(rand());

在每种情况下,这都是非常独特的。如果您发现$filename已经存在,则可以再次调用它。

答案 5 :(得分:0)

使用依赖于时间的ID不是一个好主意 - 如果您同时上传两个图像,后一个可以覆盖之前的图像。你应该看看uniqid()等功能。但是,如果这个上传/调整大小/保存脚本是“单用户”,那么这不是一个大问题。

问题本身。如果我是你,我只是将计算出的文件名保存到某个变量a使用该点的变量。已计算的计算是浪费时间。当一次上传一些非常大的图像或更多图像时,脚本甚至可以花费20秒。你不能依赖事实,你会在一秒钟内完成你想要的一切。

相关问题