使用php上传多个文件而不覆盖以前的文件

时间:2013-05-17 17:08:11

标签: php file upload

所以我试图一次上传多个文件,但每次我这样做只会上传我尝试做的每个文件上传的循环中的最后一个文件。最终它只是将一个文件上传到我的服务器,我的数据库中的多个点正在引用。

我尝试使用独立的函数和变量在循环外执行上传文件函数,但它仍在执行。

我的代码:

<?php $image_number = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$image_allowed = array('jpg', 'jpeg', 'gif', 'png');
if (empty($errors) === true) {
  foreach ($image_number as $value) {
    if (isset($_FILES['story_image_' . $value]) === true) {
        if (empty($_FILES['story_image_' . $value]['name']) === false) {
            if (in_array(strtolower(end(explode('.', $_FILES['story_image_' . $value]['name']))), $image_allowed) === false) {
                $errors[] = 'Incorrect file type for \'Story image ' . $value . '\'. Allowed file types: ' . implode(', ', $image_allowed);
            } else if ($_FILES['story_image_' . $value]['size'] > 1048576) {
                $errors[] = 'Story image ' . $value . '\'s file size may not exceed 1 MB, or 1048576 Bytes.';
            }
        }
    }
  }
}

foreach ($image_number as $value) {
    if ($_POST['removeImage' . $value] === 'on') {
        remove_story_image($story_data['story_id'], $value, $story_data['story_image_' . $value]);
    } else {
        if (isset($_FILES['story_image_' . $value]) === true) {
            if (empty($_FILES['story_image_' . $value]['name']) === false) {


                $file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                $movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                move_uploaded_file($_FILES['story_image_' . $value]['tmp_name'], $movefile_path);
                mysql_query("UPDATE `stories` SET `story_image_" . $value . "` = '" . mysql_real_escape_string($file_path) . "' WHERE `story_id` = " . $story_data['story_id']);
            }
        }   
    }
}
?>

我检查了我的表单,以及所有独立命名和匹配的文件字段名称。这不是语法问题,因为第一次循环检查错误是完美无缺的。它只有在我尝试上传文件时才会开始覆盖。

任何人都可以开导我吗? (我是一个非常大的菜鸟,所以请尽量保持新手说话)

** * ** 更新 * ** * ** * ****

所以我现在解决了这个问题,下面是工作代码:

foreach ($image_number as $value) {
    if ($_POST['removeImage' . $value] === 'on') {
        remove_story_image($story_data['story_id'], $value, $story_data['story_image_' . $value]);
    } else {
        if (isset($_FILES['story_image_' . $value]) === true) {
            if (empty($_FILES['story_image_' . $value]['name']) === false) {


                $file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                $movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                if (file_exists($movefile_path) === true) {
                    $file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . substr(md5(rand()),0,10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                    $movefile_path = $_SERVER['DOCUMENT_ROOT'].$file_path;
                }
                move_uploaded_file($_FILES['story_image_' . $value]['tmp_name'], $movefile_path);
                mysql_query("UPDATE `stories` SET `story_image_" . $value . "` = '" . mysql_real_escape_string($file_path) . "' WHERE `story_id` = " . $story_data['story_id']);
            }
        }   
    }
}

对于那些可能在将来遇到类似问题并且需要一个简单解释的人,我常常在其他人提供时解释,这里简要说明问题是什么以及我如何修复它。

问题是当我在循环中迭代时,我是md5哈希,用这行代码重写相同的文件名:

$movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));

您注意到我有两个文件路径。这不是混淆任何人,它是允许我上传一个绝对路径到数据库,html可以稍后引用($ file_path)并有一个绝对路径,PHP可以使用上传文件($ movefile_path)。

为了解决这个问题,我进行了循环检查,看看文件是否已经存在,如果确实存在,只需在md5散列时间戳后面添加一个md5哈希值的随机字符串,以创建一个新的唯一文件名。我使用$ movefile_path文件路径来检查文件是否存在,因为这是php可以使用的路径。

我还确保在更新的$ movefile_path中包含更新的$ file_path变量,否则重新散列随机字符串会给我一个不同的文件名,以便从我的数据库中引用html,而不是php上传的实际文件名

1 个答案:

答案 0 :(得分:1)

您应重命名要上传的文件,绝不相信用户输入... 您可以在图像名称后面加上一个unix时间戳或唯一ID