2
votes

I've been looking into uploading files via. AJAX using FormData and FileReader, but I keep running into the same problem.

Upon triggering the file upload, it is passed to a PHP script which validates the uploaded file and attempts to move it into a permanent directory. Unfortunately, whilst validation is successful, calling move_uploaded_file() results in the following warnings:

Warning: move_uploaded_file([path\to\temp\directory]\php256.tmp): failed to open stream: No such file or directory in [path/to/script/file.php] on line [line]

Warning: move_uploaded_file(): Unable to move '[path\to\temp\directory]\php256.tmp' to '[path\to\permanent\directory]\[filename.ext]' in [path/to/script/file.php] on line [line]

Uploading files via submitting a form normally and moving the temporary file works as expected.

My php.ini settings are pretty standard:

file_uploads = On
upload_tmp_dir = "[path\to\temp\directory]"
upload_max_filesize = 2M
max_file_uploads = 20

My PHP should also be pretty standard:

$fileField = 'target_file';

if(!(isset($_FILES) && is_array($_FILES) && isset($_FILES[$fileField]))) {
    // No File Sent (Error Out)
}

$file = $_FILES[$fileField];

// Errors in transfer?
if(isset($file['error'])) {

    $haltMessage = false;

    switch($file['error']) {
        /* Switchboard checking through all standard file upload errors. And, of course, ERR_OK */
    }

    if($haltMessage !== false) {

        // An error occured! Error Out

    }

}

// Check if the file was uploaded.
if(!is_uploaded_file($file['tmp_name'])) {

    // No File Uploaded (Error Out)

}

if(/* File type checking.. */)) {

    // Invalid file type (Error Out)

}

$uploadDir = 'path/to/permanent/dir';

$fileName = $file['name'];

$location = $uploadDir . DS . basename($fileName); // DS = '/'

$result = move_uploaded_file($file['tmp_name'], $location);

if($result) {

    // Yes!

} else {

    // Something did indeed go wrong.
    // This block of code is ran after the warnings are issued.


}

So that leaves my JavaScript to be somewhat desired:

(function($) {


    $(document).ready(function(){

        var url = 'url/to/php/script.php',
            input,
            formdata;

        // FormData support? (We have a fallback if not)
        if(window.FormData != null && window.FileReader != null) {

            input = document.getElementById('target_file');
            formdata = new FormData(),

            input.addEventListener('change', function(ev) {

                var reader,
                    file;

                if(this.files.length === 1) {

                    file = this.files[0];

                    if(!!file.type.match(/* File type matching */)) {

                        reader = new FileReader();
                        reader.onloadend = function (e) {

                            // Uploaded Handle

                        }

                        reader.onload = function() {

                            formdata.append('target_file', file);

                            $.ajax({
                                url : url,
                                type : "POST",
                                data : formdata,
                                processData: false,
                                contentType: false,
                                success : function(res) {
                                    console.log(res);
                                }
                            });

                        }

                        reader.readAsDataURL(file);

                    } else {
                        // Invalid file type.
                    }

                } else {
                    // No file / too many files (hack) selected.
                }

            }, false);

        }
    });
}(jQuery));

I'm using FireFox 23.0.1, and I'm running PHP 5.4.7 on the server.

Apologies for the long question, but I'm not sure where the problem seems to be. Dumping the $_FILES variable reveals an array that's full of the expected file information, including a tmp_name too. There's no sign of any error at that point, only when I attempt to move the temp file.

Any help you can give in regards to this question would be much appreciated!

1
Why are you using FileReader here at all? It is completely unnecessary and inefficient to do so unless you actually want to, for example, read the contents of each file. There is no need to read a file if you are simply uploading it. In fact, after the file is read, you're not even doing anything with the contents of the file.Ray Nicholus
I was trying a bunch of alternate suggestions, things like reading the file as binary, beforehand. That was the closest solution I could get to a success. Other attempts and tinkering resulted in the file not being passed through to the server at all. As for not doing anything with the read file contents, another suggestion was to pass through the contents instead of just the file variable. That, too, resulted in failure.Sean
No need to use FileReader, just append the File object your grabbing from your <input type="file"> to your FormData object, and send the FormData object along with your ajax request.Ray Nicholus
Just make sure you have the gd library extension enabled in your php.ini file.KillABug

1 Answers

0
votes

Geht ned mit js ... Link:

move_uploaded_file() ist von den normalen Safe Mode UID-Einschränkungen nicht betroffen. Dies ist nicht unsicher, da move_uploaded_file() nur mit via **PHP hochgeladenen Dateien** arbeitet.