PHP - 从动态表单上传图片 - 文件命名问题

时间:2016-03-26 15:49:33

标签: php mysql file-upload

我正在构建一个动态表单,允许用户为每个条目创建可变数量的行。表单包括图像上传功能。我可以让图片上传工作,但不完全符合我的意愿 - 问题是我似乎被迫使用' tmp_name'该文件,并且无法获取原始文件名。

首先,这是我的PHP(前往MySQL)......

require '../credentials.php';
$servername = "localhost";
$dbname = "dynamic_test";
$target_dir = "uploads/";

$conn = new mysqli($servername, $username, $password, $dbname);

$sql = '';

$name = $_POST['name'];
$route = $_POST['route'];

$site_array = $_POST['site'];

foreach($site_array as $siteNumber => $value){

    $species_array[$siteNumber] = $_POST['species'.$siteNumber.''];
    $deadinjured_array[$siteNumber] = $_POST['deadinjured'.$siteNumber.''];
    $image_array[$siteNumber] = $_FILES['image'.$siteNumber.'']['tmp_name'];

    foreach($species_array[$siteNumber] as $key => $species){

        if($image_array[$siteNumber][$key]){
            $target_file = ($target_dir . rand(1, 9999999) . strtolower(basename($image_array[$siteNumber][$key])));

            if(move_uploaded_file($image_array[$siteNumber][$key], $target_file)){
                $image_url = $target_file;
            } 
        };        

    $deadinjured = $deadinjured_array[$siteNumber][$key];

    $sql .= "INSERT INTO test (volunteer, route, site, species, deadinjured, image_url)
    VALUES ('$name', '$route', '$siteNumber', '$species', '$deadinjured', '$image_url');";

    };
};


if ($conn->multi_query($sql) === TRUE) {
    echo "MySQL thanks you";
    $conn->close();
};

注意这一行 -

$image_array[$siteNumber] = $_FILES['image'.$siteNumber.'']['tmp_name'];

为了将图片放入$ image_array,他们需要[' name']或[' tmp_name']后缀 - 使用[' name'这里会导致move_uploaded_file函数失败 - 这会产生错误Undefined variable: image_url。但是,我发现通过将[' tmp_name']构建到$ image_array变量中,我能够使move_uploaded_file函数起作用,因为该函数期待[&#39] ; tmp_name']后缀在第一个参数中。

所以我的问题是 - 有没有办法使用实际的文件名而不是临时名称将图像放入图像数组?这不是什么大问题 - 上面的代码确实有用,我不需要保留这个特定项目的实际文件名 - 但我仍然想知道正确的方法。

谢谢。

2 个答案:

答案 0 :(得分:0)

只需将整个_FILE存储在数组中:

require '../credentials.php';
$servername = "localhost";
$dbname = "dynamic_test";
$target_dir = "uploads/";

$conn = new mysqli($servername, $username, $password, $dbname);

$sql = '';

$name = $_POST['name'];
$route = $_POST['route'];

$site_array = $_POST['site'];

foreach($site_array as $siteNumber => $value){

    $species_array[$siteNumber] = $_POST['species'.$siteNumber];
    $deadinjured_array[$siteNumber] = $_POST['deadinjured'.$siteNumber];
    $image_array[$siteNumber] = $_FILES['image'.$siteNumber];

    foreach ($species_array[$siteNumber] as $key => $species) {
        $image_url = false;

        if (isset($image_array[$siteNumber][$key])) {
            $target_file = ($target_dir . $image_array[$siteNumber][$key]['name']);

            if (move_uploaded_file($image_array[$siteNumber][$key]['tmp_name'], $target_file)) {
                $image_url = $target_file;
            } 
        }       

        $deadinjured = isset($deadinjured_array[$siteNumber][$key]) ? $deadinjured_array[$siteNumber][$key] : false;

        $sql .= "INSERT INTO test (volunteer, route, site, species, deadinjured, image_url)
        VALUES ('$name', '$route', '$siteNumber', '$species', '$deadinjured', '$image_url');";

    };
};

请注意,您有SQL注入威胁。另外,我建议使用唯一名称存储文件。如果确实需要保留原始名称,请将原始名称与自动生成的名称一起存储在数据库中。因此,您的用户在上传时会看到文件名,但实际上它将以不同的名称存储在服务器上。使用prepared statement或类似的东西生成随机名称。

答案 1 :(得分:0)

我发现这里的问题出在语法上。 Eihwaz提出了一些很好的建议,但这是最后一段工作代码 - 请参阅我的注释,了解已发生的变化......(SQL注入威胁被中和)

require '../credentials.php';
$servername = "localhost";
$dbname = "dynamic_test";
$target_dir = "uploads/";

$conn = new mysqli($servername, $username, $password, $dbname);

$sql = '';

$name = $conn->real_escape_string($_POST['name']);
$route = $conn->real_escape_string($_POST['route']);

$site_array = $_POST['site'];

foreach($site_array as $siteNumber => $value){

    $siteNumber = $conn->real_escape_string($siteNumber);

    $species_array[$siteNumber] = $_POST['species'.$siteNumber.''];
    $deadinjured_array[$siteNumber] = $_POST['deadinjured'.$siteNumber.''];

    //IT IS NECESSARY TO SUFFIX THIS WITH ['name'], 
    $image_array[$siteNumber] = $_FILES['image'.$siteNumber.'']['name'];

    foreach($species_array[$siteNumber] as $key => $species){

        if($image_array[$siteNumber][$key]){
            $target_file = ($target_dir . rand(1, 9999999) . strtolower(basename($image_array[$siteNumber][$key])));

            //ALTHOUGH SLIGHTLY LESS ELEGANT THAN USING A VARIABLE, I FOUND THAT THIS WORKED BECAUSE ['tmp_name'] MUST PRECEDE [$key] - I WAS THINKING IT HAD TO BE THE OTHER WAY AROUND
            if(move_uploaded_file($_FILES['image'.$siteNumber.'']['tmp_name'][$key], $target_file)){
                $image_url = $conn->real_escape_string($target_file);
            } 
        };        

    $deadinjured = $deadinjured_array[$siteNumber][$key];

    $sql .= "INSERT INTO test (volunteer, route, site, species, deadinjured, image_url)
VALUES ('$name', '$route', '$siteNumber', '$species', '$deadinjured', '$image_url');";

    };
};
相关问题