我应该如何以理智的方式处理超过post_max_size
的http上传?
在我的配置中,post_max_size
比upload_max_filesize
大几MB
我遇到的问题是:
如果用户上传的文件超过post_max_size
部分问题是接收脚本根据POST的内容采取不同的操作。
我可以访问_SERVER
个变量,可以获得有关发生的事情的线索,例如CONTENT_TYPE
,CONTENT_LENGTH
和REQUEST_METHOD
。然而,基于这些内容进行猜测似乎确实存在问题。
MEMORY_LIMIT(设置为相关大小的10倍)和Apaches LimitRequestBody(设置为无限制)被发现没有错。
现在,即使向用户提供任何有意义的消息,我也很难。
有没有办法保留一些表单数据以获得更好的线索?我非常不愿意离开php。
答案 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)
如果发布数据的大小大于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
控制。