javascript - Upload multiple files using ajax

248

Hi I have a modal to upload multiple images as shown below and would like to upload the images and return back the error message or a successful message. The problem is I cannot seem to process all images.I have created a formdata in the javascript where I am appending all files but from the php I seem not to be able to handle all of them. Any idea why?

<!-- Modal -->
<div id="uploadImages" role="dialog">
  <div >
    <!-- Modal content-->
    <div >
      <div >
        <button type="button" data-dismiss="modal">&times;</button>
        <h4 >Upload Scanned Images</h4>
      </div>
      <div id="body">
        <form method="POST" enctype="multipart/form-data">
          Select file : <input type='file' name='file[]' id='file' class='form-control' multiple=""><br>
          <input type='submit' value="Upload File" id='but_upload' name='submit'>
        </form>
        <script src="uploadImages.js"></script>
      </div>
      <div >
        <p>Only jpeg, png, bmp and tiff Images are allowed to be uploaded</p>
      </div>
    </div>
  </div>
</div>

I also have a javascript to send an ajax post:

$(document).ready(function () {

    $("#but_upload").click(function () {
        var filedata = $('#file')[0];
        var formdata = false;
        if (window.FormData) {
            formdata = new FormData();
        }

        var i = 0,
            len = filedata.files.length,
            img, reader, file;
        for (i = 0; i < len; i++) {
            file = filedata.files[i];
            if (formdata) {
                formdata.append("file", file);
            }
        }

        $.ajax({
            url: 'uploadImages3.php',
            type: 'post',
            data: formdata,
            contentType: false,
            processData: false,
            success: function (response) {
                alert(response);
            },
        });
    });
});

and this is my php file

<?php

/* Getting file name */

$filename = $_FILES['file']['name'];

/* Location */
$location = "SavedImages/" . $filename;

$uploadOk = "No Errors";
$imageFileType = pathinfo($location, PATHINFO_EXTENSION);

$extensions = ['jpg', 'jpeg', 'png', 'gif', 'tiff'];

$all_files = count($_FILES['file']['name']);

for ($i = 0; $i < $all_files; $i++) {

  $file_name = $_FILES['file']['name'][$i];
  $file_tmp = $_FILES['file']['tmp_name'][$i];
  $file_type = $_FILES['file']['type'][$i];
  $file_size = $_FILES['file']['size'][$i];
  $file_ext = strtolower(end(explode('.', $_FILES['file']['name'][$i])));
  $file = $path . $file_name;
  if (!in_array($file_ext, $extensions)) {
    $uploadOk = $uploadOk . 'Extension not allowed: ' . $file_name . ' ' . $file_type;
  }

  if ($file_size > 2097152) {
    $uploadOk = $uploadOk . 'File size exceeds limit: ' . $file_name . ' ' . $file_type;
  }

  if (file_exists($file)) {
    $uploadOk = $uploadOk . 'File already exists: ' . $file_name . ' ' . $file_type;
  }


  if ($uploadOk != "No Errors") {
    echo  $uploadOk;
  } else {
    /* Upload file */
    if (move_uploaded_file($_FILES['file']['tmp_name'], $location)) {

      echo "File saved";
    } else {

      echo $uploadOk;
    }
  }
}
826

Answer

Solution:

You have:

formdata.append("file", file);

When working with PHP, if you have multiple form fields with the same name, that name must end in[] or only one of them will be available.

Looping over the files manually in the JS is pointlessly overcomplicated though.

  1. Bind the event handler to the submit event of the form
  2. Use the form to populate the FormData object

You also need to prevent the default behaviour - at the moment you are running your JS when the submit button is clicked, but the normal form submission is going to continue and load a new page (killing the JS program as it goes).

Such:

$("form").on("submit", function(e) {
    e.preventDefault();
    var formdata = new FormData(this);
    $.ajax({
        url: 'uploadImages3.php',
        type: 'post',
        data: formdata,
        contentType: false,
        processData: false,
        success: function(response) {
            alert(response);
        },
    });
});

Then your PHP will have an array of files, each of which will have name, etc. It won't have a file, containing an array of names etc.

$_FILES['file']['name'][$i]; should be$_FILES['file'][$i]['name']; and your count method is wrong too.

It's easier to work with a foreach loop though:

foreach ($_FILES['file'] as $file) {
    $file_name = $file['name'];
    # etc
}

People are also looking for solutions to the problem: caching - APCu TTL not working php 7.0

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.