首页 » 前端开发 » 正文

提交数据过多导致Apache报Input variables exceeded 1000错误的原因及解决方案

由于之前一个小项目上的需求,在一个页面上会提交很多数据到PHP端,一次偶然的机会,发现提交失败,查看Apache的错误日志(apache_error.log),发现报了如下错误:

PHP Warning:  Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in Unknown on line 0, referer: http://localhost:8000/*/***.php

简单地说就是该错误的原因就是传入的变量太多,超过了1000个(PHP默认值是1000)。

当然,首先想到的方式就是修改这个php.ini中max_input_vars的值。

解决方案1

找到php.ini文件,打开它,查找到max_input_vars字段,如果找不到,可以在任何空白的行上添加一句:

max_input_vars=5000

当然你也可以把5000改成其他数值。

稍微注意一下的是,max_input_vars只能通过修改php.ini的形式去改变他的值。在PHP中有一个ini_set(),但是该函数设置max_input_vars的值是无效的:


ini_set("max_input_vars",700);
echo ini_get("max_input_vars");//输出1000,如果没有修改过php.ini中该属性的值

所以一定注意,max_input_vars只能在php.ini中进行修改 事实上,PHP对于ini_set()可以配置的选项是已经告知了的,详情请参考参考文档1。

解决方案2

事实上,上面这个方法不一定好,但是他的确是解决这个问题的最直接有效的方法,但是可能存在的问题是,你现在设置到5000,你并不能保证下一次不会超过5000。解决方案2主要是讨论一个避开该问题的方法。

我这边遇到该问题的代码如下(为了方便,做了简化处理)

JS端(jQuery代码):


function submitAllData(){
    var data = [];
    for(var i=0;i<9999;i++){
        data[i] = i;
    }
    var sendData = data;
    $.post("test.php",{data:sendData}).done(function(data){
        //其他操作
        console.log("here");
    });
}

当调用submitAllData()后,以上代码先生成一个有9999个值的data数组,然后通过$.post方法,用post的方式,将这个data数组提交给test.php,完成后进行其他操作。(test.php中可以暂时什么事情都不做)

由于data数组有9999个元素,这直接导致我们设定的max_input_vars值不够用,所以在apache错误日志上看到前文提到的信息。

那么应该如何解决这个问题呢?显然我们不打算增加max_input_vars的值了,因为我们并不知道究竟有多少个传入的参数,于是我们想,能否让这么多的参数融合成一个,这样就不会出现超过max_input_vars的情况了。于是我们想到了JSON,由于JS原生支持JSON,所以使用非常方便。

JSON的相关基础知识这里不进行介绍,相关知识可以直接阅读参考文档2(或者直接点这里:《介绍 JSON》),这里提供了很简单高效的理解方式。

修改JS端代码:


function submitAllData(){
    var data = [];
    for(var i=0;i<9999;i++){
        data[i] = i;
    }
    var sendData = JSON.stringify(data);
    $.post("test.php",{data:sendData}).done(function(data){
        //其他操作
        console.log("here");
    });
}

此时,传入到PHP端的代码就不是原来的9999个参数,而是1个参数了。

PHP端在取用数据的时候只需要简单地decode一下即可将这传入的1个参数还原成原来的9999个参数:


if(isset($_POST['data])){

    $d = json_decode($_POST['data],true);//第二个参数表示将其转化为数组而不是默认的对象

}

这样就绕过了max_input_vars的问题,并且处理起来实际上和之前是几乎一样的。

最后提一下的是,JSON在IE6 IE7 IE8(Quirks模式)下是不支持的,有兴趣的读者请阅读参考文档3.

参考文档

1. 《php.ini 配置选项列表

2. 《介绍 JSON

3.《SJ9012: IE6 IE7 IE8(Q) 不支持 JSON 对象

发表评论