如何检测用户是否上传了大于post_max_size的文件?

时间:2011-05-31 16:36:57

标签: php file-upload php-5.3

我应该如何以理智的方式处理超过post_max_size的http上传?

在我的配置中,post_max_sizeupload_max_filesize大几MB 我遇到的问题是:
如果用户上传的文件超过post_max_size

  • _POST数组为空
  • _FILES数组为空,当然其中没有任何错误代码。
  • 没有其他信息通过这些方式可以访问哪种形式的帖子。

部分问题是接收脚本根据POST的内容采取不同的操作。

我可以访问_SERVER个变量,可以获得有关发生的事情的线索,例如CONTENT_TYPECONTENT_LENGTHREQUEST_METHOD。然而,基于这些内容进行猜测似乎确实存在问题。

MEMORY_LIMIT(设置为相关大小的10倍)和Apaches LimitRequestBody(设置为无限制)被发现没有错。

现在,即使向用户提供任何有意义的消息,我也很难。

有没有办法保留一些表单数据以获得更好的线索?我非常不愿意离开php。

6 个答案:

答案 0 :(得分:9)

对于不需要服务器端更改的简单修复,我会在上传之前使用HTML5 File API检查文件的大小。如果超出已知限制,则取消上传。我相信这样的事情会奏效:

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>

显然,它只是一个示例的框架,并非每个浏览器都支持这一点。但是使用它并没有什么坏处,因为它可以以这样一种方式实现,即它可以优雅地降级为旧浏览器。

当然,这并不能解决问题,但它至少可以让您的用户满意,并且只需要很少的工作量。 (他们甚至不必等待上传失败。)

-

另外,检查$_SERVER['CONTENT_LENGTH']与帖子和文件数据的大小可能有助于检测是否有失败。我认为当出现错误时它将不为零,而$_POST$_FILES都是空的。

答案 1 :(得分:3)

根据PHP documentation

  

如果发布数据的大小大于post_max_size,则$ _POST和$ _FILES超全局变量为空。这可以以各种方式跟踪,例如,通过将$ _GET变量传递给处理数据的脚本,即&lt; form action =“edit.php?processed = 1”&gt ;,然后检查是否设置了$ _GET ['processed']。

如果您需要为特定脚本增加限制,可以尝试ini_set('post-max-size',$ size_needed);.不过,我不确定它是否可以在脚本中被覆盖;这个限制可能会让你无法做你想做的事情。

答案 2 :(得分:1)

我喜欢@Matthew的答案,但需要一个检查多个上传文件的版本。

这是我的解决方案:

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

而且,为了完整性,这里是函数与提交表单的绑定:

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

注意:
uploadMax是我在计算允许上传的最大大小后通过php设置的变量。

答案 3 :(得分:1)

您可以在服务器端解决此问题,而无需使用查询字符串。只需将* post_max_size *设置与请求的预期内容长度进行比较即可。以下代码是Kohana如何做到的。

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

答案 4 :(得分:0)

您可能需要恢复使用flash / silverlight等的内容,例如: http://www.plupload.com/

或者看一下基于Java的解决方案......

基本上会将上传内容分解为更多可管理(和可恢复)的块,然后在服务器端重新组装它们。

答案 5 :(得分:0)

除非您的上传表单包含文件输入字段以外的字段,否则$ _POST应为空 - 文件仅通过$ _FILES处理。如果超出帖子大小,$ _FILES将为空是非常奇怪的 - 上传处理程序有一个特定的错误代码(1 / UPLOAD_ERR_INI_SIZE)来报告这种情况。另请检查memory_limit是否大于upload_max_filesize。

您的网络服务器也可能阻止上传,这可能会在调用PHP之前发生。在Apache上,它由LimitRequestBody控制。