2

I'm sending (possibly) multiple user-input files via ajax to server-side PHP. I send it using a FormData() object, and when I call $_FILES in the PHP it says the file object key inside FormData is an "unidentified index." I know I butchered the explanation, so here's context:

HTML:

<form id="subForm" action="" method="post" enctype="multipart/form-data">
    <input type="file" name="file" multiple/>
    <button type="submit">Post</button>
</form>

JQuery:

var files = $('input[type=file]').prop('files')[0]; //File list
var formData = new FormData();  

//Cycle through files (if many)
for (var i = 0; i < files.length; i++) {
    var file = files[i]; //File

    //Type and size check
    if (!file.type.match('image/*') && !file.type.match('video/*') && file.size > 8388608){
        continue;
    }

    // Add the file to the request.
    formData.append('files', file, file.name);
}
$.ajax({
    type: 'POST',
    url: 'submission.php', //Serverside handling script
    enctype: 'multipart/form-data',
    dataType: 'text', //Get back from PHP
    processData: false, //Don't process the files
    contentType: false,
    cache: false,
    data: formData,
    success: function(php_script_response){
        console.log(php_script_response);
    }
});

PHP:

foreach($_FILES['files']['tmp_name'] as $key => $tmp_name){
    if(is_uploaded_file($_FILES['files']['tmp_name'][$key]) && $_FILES['files']['tmp_name'][$key]['error']==0) {
        $path = 'uploads/' . $_FILES['files']['name'][$key];
        $upload = true;

        if(file_exists($path)){
            //Re-Upload
            $upload = false;
        }

        if(move_uploaded_file($_FILES['files']['name'][$key], $path)){
            //Success
        }else{
            //Failure
        }
    }else{
        //File not uploaded/ saved?
    }
}

Line 1 in the PHP returns:

Undefined index: files in C:\xampp\htdocs\submission.php

My speculation is that something is either wrong with my local apache server, or the JQuery?

Thanks in advance

Lolechi
  • 151
  • 1
  • 3
  • 20

1 Answers1

1

The append is never reached because you are grabbing only a single value from the input with .prop('files')[0]. So, files.length is undefined in your loop. You should be grabbing the entire array of files:

var files = $('input[type=file]').prop('files'); //File list
Derek
  • 3,438
  • 1
  • 17
  • 35
  • Ah yes, that was the problem. Could you explain the difference between getting the files by `$(...).files` and `$(...).prop('files')` and why one would use `[0]`? – Lolechi May 17 '16 at 20:31
  • 1
    [This answer](http://stackoverflow.com/a/13747921) has a good explanation. Basically, `.files` won't work on a jQuery object, so we need to use `.prop('files')` or select the first DOM element in the object. `[0]` just returns the first item in the FileList or jQuery object. – Derek May 17 '16 at 20:39