user8790423
user8790423

Reputation:

Uploading multiple images and text input with php

I am working on a form which allows users upload text, location and 4 multiple images for a project, I have successfully written a code that uploads form data into my database but the problem I do face is that whenever I upload more than 1 image with this form, the form text and location input are been inserted into my database more than 1 times (to match the number of images I have uploaded). For example I Uploaded 3 images using the form and text "Hello World" and location "NY", output should be;

But instead output is

I will like to stop the duplicate of the form text to match the number of images uploaded using the form for I have tried removing my query from the foreach statement but get no result after upload. Below is my code

<?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> 

Upvotes: 0

Views: 414

Answers (1)

ryantxr
ryantxr

Reputation: 4217

Without going into code in great detail, here is generally what you are doing wrong and how you should do it.

The global $_FILES will contain all the uploaded file information. Its contents from the example form is as follows.

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
            )

    )

)

When you upload files, on the PHP side you will get a structure something like this:

So you have to walk through this structure to get all the files. The form data on the other hand is only stored once in $_POST.

So you must insert the form data once and the files you must use a loop to go through them all.

// 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");
    }
}

Upvotes: 1

Related Questions