1

The problem

I'm trying to make an AJAX file uploader with Php and Javascript. The problem I'm having is that in my upload.php script where I'm trying to use the move_uploaded_file function, the $_FILES array is always empty.

Here's what I've tried thus far

  • Checked file_uploads = On in /etc/php/7.2/apache2/php.ini
  • Checked the current working directory of uploader.php and upload.php
  • Checked the file permissions of uploads
  • Changed the uploads_tmp_dir in /etc/php/7.2/apache2/php.ini

The MWE

Html in uploader.php:

<form class="form" id="upload_form">
    <input type="file" name="file_to_upload" id="file_to_upload"><br>
    <input class="button" type="submit" value="Upload">
</form>

Javascript in uploader.php:

<script>
  var upload_form    = document.getElementById('upload_form');
  var file_to_upload = document.getElementById('file_to_upload');

  upload_form.addEventListener("submit", upload_file);

  function upload_file (e) {
    e.preventDefault();

    var xhr = new XMLHttpRequest()
    xhr.open("POST", "upload.php");
    xhr.setRequestHeader("Content-Type", "multipart/form-data");
    xhr.send(new FormData(upload_form));
  }
</script>

upload.php:

<?php
//$target_path = "uploads/".basename($_FILES["file_to_upload"]["name"]);
$uploaded_file = $_FILES['file_to_upload']['tmp_name'];
var_dump($_FILES); // This is always array(0) { }

if(file_exists($uploadedFile)) {
   echo "file uploaded to temp dir";
} else {
   echo "file upload failed"; // This is always the outcome
}
//move_uploaded_file($_FILES["file_to_upload"]["tmp_name"], $target_path);
?>
compuphys
  • 1,289
  • 12
  • 28
  • 1
    Just use `enctype` attribute as the following `
    `
    – unclexo Apr 08 '20 at 04:06
  • Thanks, @unclexo! You should have put this as an answer so I could have accepted. I added `enctype="multipart/form-data"` and `method="POST"` to my form tag and removed the `xhr.setRequestHeader("Content-Type", "multipart/form-data");` line in the javascript. Also, I had a typo in **upload.php** (or rather an indecision/inconsistency on camel case/snake case), where in my `if(file_exists())` check I used `$uploadedFile` rather than `$uploaded_file`. – compuphys Apr 08 '20 at 11:39
  • It's OK! You're most welcome! If you submit the form without using AJAX, then you must provide encode type `multipart/form-data` with the method type of `post`. But if you use ajax to submit a form with files you don't need to provide them because modern browsers add the encoding type under the hood (and, you tell the method type in your ajax request). But as a good practice, you should provide them. – unclexo Apr 08 '20 at 11:54
  • @unclexo now I'm confused ... I thought in my example I AM submitting the form with AJAX? Isn't that what the `e.preventDefault()` and the `XMLHttpRequest` object are doing? – compuphys Apr 08 '20 at 12:16
  • Don't be confused. Just try various ways. I mean try taking `enctype` and `method` attribute out (for experiment purpose only) Check out [this code](https://pastebin.com/yqfx9UXR). It also works. By the way, refer to [my answer](https://stackoverflow.com/a/59986578/7935051) where you can learn how to properly upload a php file. – unclexo Apr 08 '20 at 13:56

2 Answers2

1

According to the PHP docs, you must specify enctype="multipart/form-data". You must also specify method="post" -- see this answer for an explanation.

So your <form> should read:

<form class="form" id="upload_form" enctype="multipart/form-data" method="post">
kmoser
  • 8,780
  • 3
  • 24
  • 40
  • Thanks, @kmoser. Note, I also had to remove `xhr.setRequestHeader("Content-Type", "multipart/form-data");` from the javascript and I had a typo in my code (see my comment on the question). – compuphys Apr 08 '20 at 11:41
1

In one of my projects using Framework-7. I was doing the same to get file upload form submission using ajax.

Do what @kmoser suggest in his answer but do as below as well.:)

<form class="form" id="upload_form" enctype="multipart/form-data" method="post">
 <input class="button" type="submit" id="submission" value="Upload">

Now, my code:

$$('#submission').on('click', function(){
 //alert('here');
 //var test = $('#upload_form').serializeArray(); 

var fileInputElement = document.getElementById('file_to_upload');   

var formData = new FormData();  
formData.append('myfile', fileInputElement.files[0]);   
var request = new XMLHttpRequest();
request.open("POST", "https://yourwebsite/upload.php");
request.send(formData); 
    //console.log(request.response);

    request.onreadystatechange = function() {//Call a function when the state changes.
    if(request.readyState == 4 && request.status == 200) {
        alert("File has been uploaded successfully!");
        //console.log('here');
        location.reload();
    }
}
});

and at last on upload.php file write below code:

if(isset($_FILES['myfile'])) {       
    //echo "uploaded something";
    if($_FILES['myfile']['tmp_name'] != '') {
        $tmp_filenm = $_FILES['myfile']['tmp_name'];
        $file_name = time()."_".$_FILES['myfile']['name'];
        $file_fullpath = $today_dir."/".$file_name; 
        //echo $file_fullpath;
        move_uploaded_file("".$tmp_filenm,"$file_fullpath");

    }
}
Jimil
  • 650
  • 2
  • 14
  • 37