Reputation:
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
Hello World NY
Hello World NY
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
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