2011-05-31 54 views
8

我该如何去处理一个理智的方式来处理超过post_max_size的http上传?如何检测用户上传的文件是否大于post_max_size?

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

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

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

我确实可以使用_SERVER变量,并且可以获得关于发生了什么的线索,即CONTENT_TYPE,CONTENT_LENGTHREQUEST_METHOD。然而,根据这些内容进行猜测似乎很成问题。发现MEMORY_LIMIT(设置为相关尺寸的10倍)并且Apaches LimitRequestBody(设置为无限制)被发现没有错。

就目前而言,即使向用户提供任何有意义的消息,我也很难。

有什么方法可以保留一些表单数据,以获得更好的线索,看看出了什么问题?我非常不愿意离开php。

回答

8

对于不需要更改服务器端的简单修复,我会在上传之前使用HTML5文件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'] VS岗位和文件数据的大小可能帮助检测,如果事情失败。我认为当出现错误时它将不为零,而$_POST$_FILES都将为空。

+0

要清楚,我会在@King Skippus的答案中引用类似的内容。即使用此客户端解决方案让人们开心,然后查找服务器端的空邮件并采取相应措施。 – Matthew 2011-05-31 17:18:32

+0

这很有用。我主要担心的是无法以适当的方式通知我的用户。任何关于当前浏览器支持的想法? – 2011-05-31 17:20:16

+1

@Captain长颈鹿,我认为每个非IE浏览器的常见使用允许你通过JavaScript来检查文件大小,但我并不确定。 (再一次,它会优雅地降级,所以使用它作为解决方案的一部分没有任何坏处。)另外,请参阅我的编辑以查看是否发生上传问题。 – Matthew 2011-05-31 17:25:48

0

您可能需要恢复到使用闪存/ Silverlight的等,如东西: http://www.plupload.com/

还是看一个基于Java的解决方案...

基本的东西,将打破上传到更多的可管理(和可恢复)块,然后在服务器端重新组装它们。

0

除非您的上传表单中的字段不是文件输入字段,否则$ _POST应该为空 - 文件通过$ _FILES完全处理。非常奇怪的是,如果邮件大小超过$ _FILES将是空的 - 上传处理程序有一个特定的错误代码(1/UPLOAD_ERR_INI_SIZE)来报告这种情况。还要检查memory_limit是否大于upload_max_filesize。

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

+0

是的一些其他领域,在正常情况下,有识别它是什么样的上传。在这种情况下,LimitRequestBody被设置为高于php设置,并且不会产生干扰。 – 2011-05-31 16:46:08

+0

是的,我也非常惊讶地发现_FILES因为这个而变空了。 – 2011-05-31 16:48:08

+0

PHP和/或Apache错误日志中的任何内容? – 2011-05-31 17:15:56

3

PHP documentation

如果POST数据的大小大于post_max_size中,$ _ POST和$ _FILES superglobals便会为空。这可以通过各种方式进行跟踪,例如,通过将$ _GET变量传递给处理数据的脚本,即< form action =“edit.php?processed = 1”>,然后检查是否设置了$ _GET ['processed']。

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

+1

我很满意自己的限制,但并不是php超过这些限制时的反应方式。另外GET的想法是有用的,但我希望它对用户是透明的,并且感觉“hackish”。 – 2011-05-31 16:52:30

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进行设置。

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

我自己并没有处理上传。 PHP的确如此。如果我可以从浏览器中截取“content_length”,那么所有的都是粉红色的独角兽和蝴蝶。虽然我很欣赏你的意见。 – 2013-08-22 22:28:11

相关问题