Reputation: 1727
I am trying to upload multiple images to a folder at a time by using AJAX, JQuery, and PHP. The code is running for single file upload but not running for multiple image upload. If I am uploading a single image without loop then its working fine but in case of loop it's not working.
I am using the following code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Iamge</title>
<link href="style.css" rel="stylesheet" type="text/css">
<script src="jquery-1.12.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#but_upload").click(function(){
var fd = new FormData();
//following code is working fine in for single image upload
// var files = $('#file')[0].files[0];
// fd.append('file',files);
//this code not working for multiple image upload
var names = [];
for (var i = 0; i < $('#file').get(0).files.length; ++i) {
names.push($('#file').get(0).files[i].name);
}
fd.append('file[]',names);
/*var ins = document.getElementById('file').files.length;
for (var x = 0; x <ins; x++) {
fd.append("file", document.getElementById('file').files[x]);
}*/
$.ajax({
url:'upload.php',
type:'post',
data:fd,
contentType: false,
processData: false,
success:function(response){
if(response != 0){
$("#img").attr("src",response);
}
},
error:function(response){
alert('error : ' + JSON.stringify(response));
}
});
});
});
</script>
</head>
//HTML Part
<body>
<div class="container">
<h1>AJAX File upload</h1>
<form method="post" action="" id="myform">
<div>
<img src="" id="img" width="100" height="100">
</div>
<div>
<input type="file" id="file" name="file" multiple="multiple" />
<input type="button" class="button" value="Upload"
id="but_upload">
</div>
</form>
</div>
</body>
</html>
//PHP Code
<?php
/* Getting file name */
echo "<script>alert('yes');</script>";
//without loop working fine
$count = count($_FILES['file']['name']);
for ($i = 0; $i < $count; $i++) {
$filename = $_FILES['file']['name'][$i];
/* Location */
$location = "upload/".$filename;
/* Upload file */
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){
echo $location;
} else {
echo 0;
}
}
?>
Upvotes: 1
Views: 3702
Reputation: 401
I'm not sure about the current answer, as I couldn't get it to work in my current implementation, so I'll post another answer that worked in my situation.
I'll give the file name, relevant code, and then a summary of important notes for each file.
form.html
<form class='myForm' enctype='multipart/form-data'>
<input type='file' name='myFileInput[]' multiple>
<button class='mySubmitButton'>Submit</button>
</form>
First, it's important to point out that the form element's enctype='multipart/form-data'
is REQUIRED when submitting a file. You should also name your file inputs as an array (notice the name of my input is myFileInput[] and not myFileInput without the square brackets. This will make sure to POST your files as an array, not as an object!
You'll also notice I don't use an <input type='submit'>
. This is just personal preference, since I don't have to prevent default submit behavior and can just as easily target the element for a click
listener later on.
form.js
$('.mySubmitButton').click(async function() {
let formData = new FormData($('.myForm')[0]);
let myAjax = $.ajax(
{
type: 'POST',
url: 'form.php'
contentType: false,
processData: false,
data: formData
}
);
});
That easy! Just make sure when you target your form
element via jQuery, you get the first index ($('.myForm')[0]
) to get the DOM element, and not the jQuery object. I use an async function here because in my tiny asynchronous brain, that makes more sense to me, and callbacks and promises scare me, but you can easily use the success/failure
members of the $.ajax
object, or the .done()
methods.
form.php
if (myPostSubmitCondition) {
//check upload errors, (PLEASE) do server side validation, etc.
for (var $f = 0; $f < count($_FILES['myFileInput']['name']); $f++) {
$uploadedFile = array(
'name' => $_FILES['myFileInput']['name'][$f],
'type' => $_FILES['myFileInput']['type'][$f],
'tmp_name' => $_FILES['myFileInput']['tpm_name'][$f],
'error' => $_FILES['myFileInput']['error'][$f],
'size' => $_FILES['myFileInput']['size'][$f]
); //I just do this to make my life easier, since the $_FILES global has a weird structure
//do other file stuff here
if (!move_uploaded_file($uploadedFile['tmp_name'], $destination)) {
//handle errors here
)
}
}
<Insert mandatory warning about over-simplification, and neglect of server-side verification (including MIME types!) here>
That's it! This should work for both single file and multi-file uploads.
Upvotes: 0
Reputation: 2317
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload Iamge</title>
<script type="text/javascript">
$(document).ready(function(){
$("#but_upload").click(function(){
var fd = new FormData();
//following code is working fine in for single image upload
// var files = $('#file')[0].files[0];
// fd.append('file',files);
//this code not working for multiple image upload
var names = [];
var file_data = $('input[type="file"]')[0].files;
// for multiple files
for(var i = 0;i<file_data.length;i++){
fd.append("file_"+i, file_data[i]);
}
fd.append('file[]',names);
/*var ins = document.getElementById('file').files.length;
for (var x = 0; x <ins; x++) {
fd.append("file", document.getElementById('file').files[x]);
}*/
$.ajax({
url:'upload.php',
type:'post',
data:fd,
contentType: false,
processData: false,
success:function(response){
if(response != 0){
$("#img").attr("src",response);
}
},
error:function(response){
alert('error : ' + JSON.stringify(response));
}
});
});
});
</script>
</head>
//HTML Part
<body>
<div class="container">
<h1>AJAX File upload</h1>
<form method="post" action="" id="myform">
<div>
<img src="" id="img" width="100" height="100">
</div>
<div>
<input type="file" id="file" name="file" multiple="multiple" />
<input type="button" class="button" value="Upload"
id="but_upload">
</div>
</form>
</div>
</body>
</html>
have made changes in below code
var file_data = $('input[type="file"]')[0].files; // for multiple files
for(var i = 0;i<file_data.length;i++){
fd.append("file_"+i, file_data[i]);
}
fd.append('file[]',names);
And there are also changes in PHP code
<?php
/* Getting file name */
//without loop working fine
$count = count($_FILES);
for ($i = 0; $i < $count; $i++) {
$filename = $_FILES['file_'.$i];
/* Location */
echo $location = "upload/".$filename['name'];
/* Upload file */
if(move_uploaded_file($filename['tmp_name'],$location)){
echo $location;
} else {
echo 0;
}
}
?>
count of files and file name are comming in a different way so I have made the changes as required instead of if gives file array like $_FILE['file_0']
,$_FILE['file_1']
and so on, I have also change the permission of upload directory please check if your directory have read and write permission (777) or not, this code works for me you can try I hope it will work for you also :-)
Upvotes: 2
Reputation: 3531
In the loop you will need to add index
of particular file
move_uploaded_file($_FILES['file']['tmp_name'][$i],$location); // $i is index
Upvotes: 0