How to detect if a user uploaded a file larger than post_max_size?

后端 未结 6 1369
没有蜡笔的小新
没有蜡笔的小新 2020-12-06 12:00

How should I go about handling http uploads that exceeds the post_max_size in a sane manner?

In my configuration post_max_size is a few MB

相关标签:
6条回答
  • 2020-12-06 12:06

    You can solve this on the server side without resorting to a query string. Just compare the *post_max_size* setting to the expected content length of the request. The following code is how Kohana does it.

    public static function post_max_size_exceeded()
    {
        // Make sure the request method is POST
        if (Request::$initial->method() !== HTTP_Request::POST)
            return FALSE;
    
        // Get the post_max_size in bytes
        $max_bytes = Num::bytes(ini_get('post_max_size'));
    
        // Error occurred if method is POST, and content length is too long
        return (Arr::get($_SERVER, 'CONTENT_LENGTH') > $max_bytes);
    }
    
    0 讨论(0)
  • 2020-12-06 12:08

    Per the PHP documentation:

    If the size of post data is greater than post_max_size, the $_POST and $_FILES superglobals are empty. This can be tracked in various ways, e.g. by passing the $_GET variable to the script processing the data, i.e. <form action="edit.php?processed=1">, and then checking if $_GET['processed'] is set.

    If you need the limit increased for a specific script, you can try ini_set('post-max-size', $size_needed);. I'm not sure if it can be overridden within a script, though; that limit is probably there to specifically keep you from doing what you're trying to do.

    0 讨论(0)
  • 2020-12-06 12:09

    I liked @Matthew answer, but needed a version that checked for multiple upload files.

    This was my solution:

    function checkAttachmentsSize() {
        var total = 0;
        var count = 0;
    
        jQuery('input[type="file"]').each(
            function() {
                if (typeof this.files[0] != 'undefined') {
                    total+= this.files[0].size;
                    count++;
                }
            }   
        );
    
        var word = (count > 1) ? 's are' : ' is';
        if (total > (uploadMax * 1000 * 1000)) {
            alert("The attachment file" + word + " too large to upload.");
            return false;
        }
    
        return true;
    }
    

    And, for completeness, here's the binding of the function to the form being submitted:

    jQuery(function($) {
        $("form").submit(
            function() {
                return checkAttachmentsSize();
            }   
        });
    );
    

    NOTE:
    uploadMax is a variable that I set via php after calculating the maximum size of the allowable upload.

    0 讨论(0)
  • 2020-12-06 12:16

    You may need to revert to something that uses flash/silverlight etc. such as: http://www.plupload.com/

    Or look at a Java-based solution...

    Basically something that will break the upload into more managable (and resumable) chunks, and then re-assemble them on the server side.

    0 讨论(0)
  • 2020-12-06 12:24

    Unless your upload form has fields other than the file input field, then $_POST should be empty - files are handled exclusively through the $_FILES. It's very odd that $_FILES would be empty if the post size is exceeded - the upload handlers have a specific error code (1/UPLOAD_ERR_INI_SIZE) to report such a condition. Also check that memory_limit is larger than the upload_max_filesize.

    Your webserver may be blocking the upload as well, which would occur before PHP is invoked. On Apache, it's controlled by LimitRequestBody.

    0 讨论(0)
  • 2020-12-06 12:26

    For a simple fix that would require no server side changes, I would use the HTML5 File API to check the size of the file before uploading. If it exceeds the known limit, then cancel the upload. I believe something like this would work:

    function on_submit()
    {
      if (document.getElementById("upload").files[0].size > 666)
      {
        alert("File is too big.");
        return false;
      }
    
      return true;
    }
    
    <form onsubmit="return on_submit()">
    <input id="upload" type="file" />
    </form>
    

    Obviously it's just a skeleton of an example, and not every browser supports this. But it wouldn't hurt to use this, as it could be implemented in such a way that it gracefully degrades into nothing for older browsers.

    Of course this doesn't solve the issue, but it will at least keep a number of your users happy with minimal effort required. (And they won't even have to wait for the upload to fail.)

    --

    As an aside, checking $_SERVER['CONTENT_LENGTH'] vs the size of the post and file data might help detect if something failed. I think it when there is an error it will be non zero, while the $_POST and $_FILES would both be empty.

    0 讨论(0)
提交回复
热议问题