【问题标题】:Generating a time-based unique file name for uploads without creating a race condition为上传生成基于时间的唯一文件名,而不创建竞争条件
【发布时间】:2009-08-11 17:19:39
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: php uniqueidentifier


    【解决方案1】:

    AFAIK 这是命名文件的好方法,尽管我会检查 file_exists() 并可能添加一个随机数。

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

    希望有帮助

    【讨论】:

    • 这似乎没有解决实际问题,它不是关于“我如何生成唯一名称”而是“我如何防止两次生成名称”。
    【解决方案2】:

    只想补充一点,php 具有创建标识符的功能:uniqid。您还可以在标识符前面加上一个字符串(可能是日期?)。

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

    【讨论】:

      【解决方案3】:

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

      我不确定您上传文件所遵循的流程,但处理文件上传的另一种方法是使用 PHP 的内置处理程序。您可以上传文件,然后使用“安全”方法将上传的文件拉出临时空间。 (在这种情况下,临时空间可以安全地位于 open base dir 指令之外,以防止篡改)。 is_uploaded_file() 和 move_uploaded_file() from: http://php.net/manual/en/features.file-upload.post-method.php 示例 2 可能会解决您遇到的问题。

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          为什么不使用

          $filename = md5(rand());
          

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

          【讨论】:

          • rand() 将是“几乎”唯一的,但 $date.$time 将是唯一的。为什么要以一个换另一个,除此之外,这并不能解决实际问题。
          【解决方案6】:

          使用依赖于时间的 ID 不是一个好主意 - 如果您同时上传两张图片,后面的一张可能会覆盖前面的一张。您应该查看诸如uniqid() 之类的函数。但是,如果这个上传/调整大小/保存脚本是“单用户”的,那么这不是什么大问题。

          到问题本身。如果我是你,我只会将计算出的文件名保存到某个变量中,然后使用该变量。已经计算的计算是浪费时间。而当上传一些非常大的图像,或者一次上传更多图像时,脚本甚至可能需要 20 秒。你不能相信你会在一秒钟内做出你想要的一切。

          【讨论】:

            猜你喜欢
            • 2010-09-29
            • 1970-01-01
            • 2019-02-15
            • 2016-06-12
            • 2012-01-01
            • 1970-01-01
            • 2015-06-10
            • 2017-03-31
            • 2010-12-07
            相关资源
            最近更新 更多