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

元气小坏坏 提交于 2019-11-28 00:58:10

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.

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.

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.

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);
}

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!