Gabriel
Gabriel

Reputation: 51

How to prevent empty files on html form on PHP

I have a website where users fill a form and upload their CVs (Curriculum Vitae). 95% of the time it works like it should and I get the CV file on the server. Althought I tried, I could never reproduce the error of the 5% users that fail. I know that most of them uses Android to upload the files but not all of them. We even have people on Chrome running on Windows 7 that fail so the problem could be a poor connection. Still I was not able to reproduce the error.

This is a simplified version of the form:

<html>
    <form action="get_file.php" method="POST" enctype="multipart/form-data">
        Here goes the file: <input name="curriculo" type="file"><br>
        <input type="submit">
    </form>
</html>

And this is a simplified version of what I have on the backend.

<pre>
<?php
print_r($_FILES);
?>
</pre>

This is what I get 95% of the time which is fine:

Array
(
    [curriculo] => Array
        (
            [name] => cora.rtf
            [type] => application/msword
            [tmp_name] => /tmp/phpk0caxk
            [error] => 0
            [size] => 542
        )
)

And this is the other 5% (not fine!)

Array
(
    [curriculo] => Array
        (
            [name] => 
            [type] => 
            [tmp_name] => 
            [error] => 4
            [size] => 0
        )

)

Array
(
    [curriculo] => Array
        (
            [name] => curriculo.odt
            [type] => 
            [tmp_name] => 
            [error] => 3
            [size] => 0
        )

)
Array
(
    [curriculo] => Array
        (
            [name] => jeisuana_almeida_de_sousa_jeise.pdf
            [type] => application/pdf
            [tmp_name] => /tmp/php7QmGOk
            [error] => 0
            [size] => 0
        )

)

On the last example, note that the file made it whithout any errors but the size is 0 which is also a problem.

I have this on my php.ini:

file_uploads = On
upload_max_filesize = 6M
max_file_uploads = 20

I know that if the file size exceeds the upload_max_filesize the file doesn't make. That is not the case. When the file exceeds the 6M that the $_FILES array is empty and I treat this error accordingly.

I also know what those error codes are. They are documented here.

http://php.net/manual/en/features.file-upload.errors.php

My question is: is there anything I'm missing to prevent loosing those 5% resumes? Any configuration? Or could be that the problem is definitely on the users crappy connections?

Like I said I get this errors either with users on Android or Chrome/Safari/Firefox on Windows/Mac.

Thanks!

Upvotes: 1

Views: 888

Answers (2)

cssyphus
cssyphus

Reputation: 40076

Instead of using a traditional <form> with a type="submit" button, use AJAX and provide instant feedback if the file is not received.

If you haven't AJAX'd before, here are some good posts for getting the basics. It's a lot easier than it sounds.

A simple example

More complicated example

Populate dropdown 2 based on selection in dropdown 1


Also, check out Ravishanker Kusuma's Hayageek jQuery File Upload plugin:

http://hayageek.com/docs/jquery-upload-file.php

He breaks down the process into three simple steps, that basically look like this:

<head>
    <link href="http://hayageek.github.io/jQuery-Upload-File/uploadfile.min.css" rel="stylesheet">  // (1)
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="http://hayageek.github.io/jQuery-Upload-File/jquery.uploadfile.min.js"></script>   // (1)
</head>
<body>
    <div id="fileuploader">Upload</div>  // (2)
    <script>
        $(document).ready(function(){
            $("#fileuploader").uploadFile({  // (3)
                url:"my_php_processor.php",
                fileName:"myfile"
            });
        });
    </script>
</body>

The final step is to have the PHP file specified in the jQuery code (in this case my_php_processor.php) to receive and process the file:

my_php_processor.php:

<?php
    $output_dir = "uploads/";
    $theFile = $_FILES["myfile"]["name"];
    move_uploaded_file($_FILES["myfile"]["tmp_name"],$output_dir.$fileName);

Note the relationship between myfile in the PHP ($_FILES["myfile"]), and the filename specified in the jQuery code block.

Upvotes: 1

GluePear
GluePear

Reputation: 7735

Why not test for the file size before doing anything? Something like:

<?php
if (isset($_FILES) && $_FILES['size'] > 0) {
  // Do stuff here
}
?>

Upvotes: 1

Related Questions