首页 > 解决方案 > 使用 php 上传多个图像和文本输入

问题描述

我正在开发一个表单,它允许用户为一个项目上传文本、位置和 4 张多张图片,我已经成功编写了一个代码,可以将表单数据上传到我的数据库中,但我面临的问题是,每当我上传超过 1 张图片时这个表单,表单文本和位置输入被插入到我的数据库中超过 1 次(以匹配我上传的图像数量)。例如,我使用表单和文本“Hello World”和位置“NY”上传了 3 张图片,输出应该是;

但相反的输出是

我想停止表单文本的重复,以匹配使用表单上传的图像数量,因为我尝试从 foreach 语句中删除查询,但上传后没有结果。下面是我的代码

<?php  
    // start session
    session_start();

    // db
    include db.php";

    // random_char
    include "random_char.php";

    // compress image
    include "compress_image.php";

    // from user id
    $id = $_SESSION["id"];
    $user = $_SESSION["name"];

    if ($_SERVER["REQUEST_METHOD"] == "POST") {

        // post validations
        if (empty(trim($_POST['photo_post_box']))) {
            // $post_box = null; // post box
            $post_box_error = true; // post box is empty
        } elseif (strlen($_POST['photo_post_box']) > 500) {
            $post_box_error = true; // characters is greater than 500
        } else {
            $post_box = $_POST['photo_post_box'];
            $post_box_error = false;
        }

        // location validation
        if (empty(trim($_POST['photo_location']))) {
            $location = ""; // location
            $location_error = false; // location is empty
        } elseif (strlen(preg_replace('/[^a-zA-Z]/m', '', $_POST["photo_location"])) < 2) {
            $location_error = true; // location is less than 2
        } elseif (strlen(preg_replace('/[^a-zA-Z]/m', '', $_POST["photo_location"])) > 20) {
            $location_error = true; // location is greater than 20
        } elseif (!preg_match("/^[A-Za-z-,\s]+$/ ", $_POST["photo_location"])) {
            $location_error = true; // location has unwanted characters
        } else {
            $location = trim($_POST['photo_location']); // location
            $location_error = false;
        }

        // image validations
        $accepted_extensions = array(
            "gif",
            "png",
            "jpg",
            "jpeg"
        ); // extensions

        $img = $_FILES["img"]; // images

        foreach($img['name'] as $key => $name) {

            $files = $_FILES['img'];

            $img_extension = pathinfo($files["name"][$key], PATHINFO_EXTENSION); // image extention
            $img_extension = strtolower($img_extension); // image extension

            if (!file_exists($files['tmp_name'][$key])) {
                $img_error = true;
            } elseif (!in_array($img_extension, $accepted_extensions)) {
                echo "<font color='red'>Invalid format</font>";
                $img_error = true;
            } elseif ($files["size"][$key] > 10485760) {
                $img_error = true; // image is larger than 10mb
            } else {
                $img_error = false;
            }

            if ($post_box_error == false && $location_error == false && $img_error == false) {
                $time = md5(microtime()); // micro time hashed with md5
                $name_file = $project_name.".com(@".$user.")_".$time.$id; // rename image
                $ext = substr($name, strrpos($name, '.') + 1); // extension
                $uploaded_img = $name_file.'.'.$ext; // uploaded image
                $save_to_dir = __DIR__."/../../img/".$uploaded_img; // save image to directory
                $post_id = random_alphanumeric_string(8).'b'.$id; // post id

                // `users_post`
                $insert = "INSERT INTO users_post(post_id, by_user_id, post, post_location, date_n_time) VALUES(?, ?, ?, ?, NOW())";
                $stmt = mysqli_prepare($db, $insert);
                mysqli_stmt_bind_param($stmt, "siss", $post_id, $id, $post_box, $location);
                mysqli_stmt_execute($stmt);

                // `users_post_images`
                $insert = "INSERT INTO users_post_images(post_id, image) VALUES(?, ?)";
                $stmt = mysqli_prepare($db, $insert);
                mysqli_stmt_bind_param($stmt, "ss", $post_id, $uploaded_img);
                mysqli_stmt_execute($stmt);

                // compress and save uploaded image in directory
                compressImage($files['tmp_name'][$key], $save_to_dir, 60);
            }
            // close statement
            mysqli_stmt_close($stmt);   
        }   
    }
    // close db connection
    mysqli_close($db);
?> 

<form id="photo_post_box" method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" name="post_box" enctype="multipart/form-data" accept-charset="utf-8">
    <textarea class="form-control" name="photo_post_box" placeholder="Write something..."></textarea>
    <div class="mt-1">
        <input class="form-control" type="text" name="photo_location" placeholder="City, State">
    </div>
    <div class="mt-1">
        <input type="file" name="img[]" id="img1" accept=".gif, .jpg, .png" required="required">
        <input type="file" name="img[]" id="img2" accept=".gif, .jpg, .png">
        <input type="file" name="img[]" id="img3" accept=".gif, .jpg, .png">
        <input type="file" name="img[]" id="img4" accept=".gif, .jpg, .png">
    </div>
    <div class="mt-1">
        <button name="upload">
            <b>Upload</b>
        </button>
    </div>
</form> 

标签: php

解决方案


在不详细介绍代码的情况下,这里通常是您做错了什么以及应该如何做。

全局 $_FILES 将包含所有上传的文件信息。其示例形式的内容如下。

Array
(
[img] => Array
    (
        [name] => Array
            (
                [0] => bears.jpeg
                [1] => big cat.jpeg
                [2] => butterfly2.jpeg
                [3] => chipmunk.jpeg
            )

        [type] => Array
            (
                [0] => image/jpeg
                [1] => image/jpeg
                [2] => image/jpeg
                [3] => image/jpeg
            )

        [tmp_name] => Array
            (
                [0] => /tmp/phpNKGKa2
                [1] => /tmp/phpOCopiT
                [2] => /tmp/phphEGfqK
                [3] => /tmp/phpguKfyB
            )

        [error] => Array
            (
                [0] => 0
                [1] => 0
                [2] => 0
                [3] => 0
            )

        [size] => Array
            (
                [0] => 162804
                [1] => 133032
                [2] => 118203
                [3] => 164941
            )

    )

)

当你上传文件时,在 PHP 端你会得到一个类似这样的结构:

因此,您必须遍历此结构才能获取所有文件。另一方面,表单数据只存储一次$_POST

因此,您必须插入一次表单数据,并且必须使用循环来遍历所有文件。

// INSERT form data first outside the loop

// Then go through the files in a loop
foreach ($_FILES["img"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {
        // INSERT file here
        $tmp_name = $_FILES["pictures"]["tmp_name"][$key];
        $name = basename($_FILES["pictures"]["name"][$key]);
        // Usually you have to do this
        move_uploaded_file($tmp_name, "some/real/dir");
    }
}

推荐阅读