0

使用 PHP 上传文件以确保数据库也得到更新的最佳实践是什么?

目前的方法

1) 表单验证确认所有字段的类型、长度和 xss 攻击均有效。

2) 使用用户提交的文件名上传到服务器的文件

3) 使用用户提交的详细信息(包括文件名)更新数据库

这是一种安全的方式吗?先更新数据库,然后在数据库中查询文件名,然后使用数据库检索到的文件名上传文件会更好吗?

不一定要寻找代码,而是要寻找哲学。谢谢!

4

2 回答 2

1

我会使用这个命令:

第一种方法:操作顺序依赖

  • 表单验证
  • 检查文件是否已上传(暂时不要将其移出)
  • 根据您的自由选择生成新文件名
  • 使用新生成的文件名将有关文件的数据插入数据库
  • 只有这样,如果没有抛出异常,请使用上面的文件名从 temp 移动文件。否则,文件将在请求结束时自动删除
  • 如果文件移动由于某种原因失败,您应该从数据库中删除记录。

我强烈建议使用一些PDO类似的库与数据库“对话”,因为这些会引发异常,而不是引发错误(如mysql_**函数)。这样您就可以确定您的查询是否成功,而无需不断检查数据库函数的结果......

第二种方法:事务

  • 表单验证
  • 检查文件是否已上传(暂时不要将其移出)
  • 根据您的自由选择生成新文件名
  • 开始交易
  • 使用新生成的文件名将有关文件的数据“插入”到数据库。
  • 使用上面的文件名从 temp 移动文件。如果由于某种原因文件移动失败,则抛出异常。
  • 提交事务
  • 此时,您确定两个文件都已移动并且数据已正确保存。
于 2012-04-04T20:30:53.607 回答
1

表单验证是任何 Web 应用程序的重要组成部分,因此很高兴在列表中看到它。您在这里结合了 Web 应用程序中最危险的两个元素,即文件上传和数据库交互,因此您显然需要谨慎行事。我想这就是你问的原因!

我在方法方面的建议首先是不要使用用户提交的文件名,这会打开你不需要的整个风险领域。除非这是您的应用程序的必需功能,否则请在 PHP 中生成一个新的随机文件名并使用 move_uploaded_file 从 PHP 分配的 tmp_name 复制到您的新随机文件名。

执行此移动后,您可以使用文件的位置更新数据库。

因此,我的方法是:

  1. 根据白名单([az][AZ][0-9] 作为建议)对任何用户提供的输入进行严格验证。
  2. 避免将用户提供的数据回显到屏幕,如果这样做,请将编码输出到 HTML 实体。
  3. 避免使用用户提供的数据作为数据库或文件名的输入,生成一个您可以控制的新文件名。
  4. 自行处理上传,并在执行一些验证检查后根据您生成的文件名将图像移动到其新位置。
  5. 使用新文件名更新数据库。

我知道你不是在追求代码,但这里有几个来自我上传的工作文件的小片段,它不做数据库部分,但添加起来很简单。

function generate_filename() {
    // could be improved upon really
    $random_string = random_string(8);
    $filename = $random_string . time() . ".jpg";
    return $filename;    
}



if ($_FILES["file_upload"]["size"] != 0) {
    $file_name = generate_filename();
    $file_path = "/" . $upload_directory . "/" . $file_name;
    $target_file_name = SITE_ROOT . $file_path; // SITE_ROOT is a constant for the file system location. This could be /var/www/images for example.

    if ($_FILES["file_upload"]["type"] == "image/jpeg") {
        if (getimagesize($_FILES["file_upload"]["tmp_name"])) {
            if (move_uploaded_file($_FILES["file_upload"]["tmp_name"],$target_file_name)) {
                exit_status("File uploaded successfully to $file_path");
            } else {
                exit_status("Eek, something went wrong with your image upload");
            }
        } else {
            exit_status("Not a valid image");
        }
    } else {
        exit_status("Invalid file type. We only support JPEG");
    }
} else {
    exit_status("You didn’t specify a file to upload. Try again");
}
于 2012-04-04T20:54:08.933 回答