Check file size before upload

118,617

Solution 1

Client side Upload Canceling

On modern browsers (FF >= 3.6, Chrome >= 19.0, Opera >= 12.0, and buggy on Safari), you can use the HTML5 File API. When the value of a file input changes, this API will allow you to check whether the file size is within your requirements. Of course, this, as well as MAX_FILE_SIZE, can be tampered with so always use server side validation.

<form method="post" enctype="multipart/form-data" action="upload.php">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" value="Submit" />
</form>

<script>
document.forms[0].addEventListener('submit', function( evt ) {
    var file = document.getElementById('file').files[0];

    if(file && file.size < 10485760) { // 10 MB (this size is in bytes)
        //Submit form        
    } else {
        //Prevent default and display error
        evt.preventDefault();
    }
}, false);
</script>

Server Side Upload Canceling

On the server side, it is impossible to stop an upload from happening from PHP because once PHP has been invoked the upload has already completed. If you are trying to save bandwidth, you can deny uploads from the server side with the ini setting upload_max_filesize. The trouble with this is this applies to all uploads so you'll have to pick something liberal that works for all of your uploads. The use of MAX_FILE_SIZE has been discussed in other answers. I suggest reading the manual on it. Do know that it, along with anything else client side (including the javascript check), can be tampered with so you should always have server side (PHP) validation.

PHP Validation

On the server side you should validate that the file is within the size restrictions (because everything up to this point except for the INI setting could be tampered with). You can use the $_FILES array to find out the upload size. (Docs on the contents of $_FILES can be found below the MAX_FILE_SIZE docs)

upload.php

<?php
if(isset($_FILES['file'])) {
    if($_FILES['file']['size'] > 10485760) { //10 MB (size is also in bytes)
        // File too big
    } else {
        // File within size restrictions
    }
}

Solution 2

I created a jQuery version of PhpMyCoder's answer:

$('form').submit(function( e ) {    
    if(!($('#file')[0].files[0].size < 10485760 && get_extension($('#file').val()) == 'jpg')) { // 10 MB (this size is in bytes)
        //Prevent default and display error
        alert("File is wrong type or over 10Mb in size!");
        e.preventDefault();
    }
});

function get_extension(filename) {
    return filename.split('.').pop().toLowerCase();
}
Share:
118,617
cchap
Author by

cchap

Updated on April 29, 2020

Comments

  • cchap
    cchap about 4 years

    I am using this javascript that I got from here, and it works perfectly for what I need it to.

    var _validFileExtensions = [".jpg", ".jpeg"]; 
    
    function File_Validator(theForm){
        var arrInputs = theForm.getElementsByTagName("input"); 
        for (var i = 0; i < arrInputs.length; i++) { 
        var oInput = arrInputs[i]; 
        if (oInput.type == "file") { 
            var sFileName = oInput.value; 
            var blnValid = false; 
                for (var j = 0; j < _validFileExtensions.length; j++) { 
                    var sCurExtension = _validFileExtensions[j]; 
                    if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) { 
                        blnValid = true; 
                        break; 
                        } 
                    } 
    
                    if (!blnValid) { 
                        alert("Invalid image file type!"); 
                        return false; 
                    } 
            } 
        } 
    
    return true; 
    } 
    

    Now, I was wondering if, in addition, I could check the file size and fail if the file is bigger than 500kb -> all before pressing the submit/upload button?

    EDIT

    After looking into what PHPMyCoder suggested, I end up solving by using this javascript code:

    <script language='JavaScript'>
    function checkFileSize(inputFile) {
    var max =  3 * 512 * 512; // 786MB
    
    if (inputFile.files && inputFile.files[0].size > max) {
        alert("File too large."); // Do your thing to handle the error.
        inputFile.value = null; // Clear the field.
       }
    }
    </script>
    

    This checks the file size, and alert the user before submitting the form.

  • cchap
    cchap almost 12 years
    editing the php.ini upload_max_filesize didn't work exactly for the same reason you mentioned, unfortunately it applies to all file uploads. I tried html5 file api, but it still passes the submit action
  • cchap
    cchap almost 12 years
    "if($_FILES['file']['size'] > 10485760) {" I am already using it, and it works, the file never gets uploaded if bigger than 500kb, but I wanted to alert before submitting the form.
  • Bailey Parker
    Bailey Parker almost 12 years
    @cchap Did you read the text under the "Client side canceling" of my answer? That bit will allow you to alert the user before he/she submits the form.
  • Sebastien C.
    Sebastien C. almost 10 years
    That's not entirely true : HTML5 APIs added the possibility to read a specific file with javascript as soon as the user choosed it in an input.
  • kano
    kano almost 8 years
    The get_extension function could also be written as return filename.split('.').pop().toLowerCase();
  • doubleOrt
    doubleOrt almost 7 years
    Is this $_FILES['file']['size'] check secure ? Wouldn't a hacker be able to change the headers (including ['size']) ?