【问题标题】:Warning: Input variables exceeded 1000警告:输入变量超过 1000
【发布时间】:2013-05-04 10:41:36
【问题描述】:

我正在用 PHP 构建一个类似 RESTS 的服务,它应该接受一个大的 JSON 帖子作为主要数据(我发送和读取数据很像这里讨论的:http://forums.laravel.io/viewtopic.php?id=900

问题是 PHP 给了我以下警告:

<b>Warning</b>:  Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in <b>Unknown</b> on line <b>0</b><br />

有什么方法可以让 PHP 不计算输入变量(或者我应该只是取消启动警告)?

【问题讨论】:

  • 为什么不按照警告建议更改max_input_vars
  • 因为我不喜欢更改它的想法,所以我发布的 JSON 数据可能非常大。我不需要 PHP 的帮助来解析我的变量,因为我不发送任何变量,只发送 JSON 编码数据。
  • PHP 不在乎您使用的是 JSON。数据被计为输入变量,因此会触发警告。您认为按预期使用配置选项有什么缺点?
  • laravel 链接失效了,能发一些示例代码吗?
  • 使用JSON.stringify() 将JSON 发布为字符串,并在接收端使用PHP 函数json_decode 将数据转换为数组。

标签: php json


【解决方案1】:

根据php manualmax_input_varsphp.ini的作用是:

可以接受多少个输入变量(限制应用于$_GET$_POST$_COOKIE 分别是超全局)。该指令的使用 减轻使用哈希的拒绝服务攻击的可能性 碰撞。如果输入变量多于此指定的 指令,发出E_WARNING,进一步的输入变量是 从请求中截断。此限制仅适用于每个嵌套 多维输入数组的级别。

您只需在php.ini 中将更大的数字归因于max_input_vars

【讨论】:

  • 所以,由于我无法真正预测我的 JSON 数据将持续多长时间,我应该将其更改为无穷大!?将我的 JSON 作为 POST var 提交会更好吗(比如将文件上传到 PHP 时)?
  • 即使您在一个 POST 变量中发送它,您最终也必须解析它并且您必须创建更多变量(除非您正在处理整个 JSON 字符串,仅此而已)。您不知道 JSON 对象可以有多长的情况很少见,但在这种情况下,您可以将其更改为 INF 或非常大的东西。不过要小心 DoS!
  • “此限制仅适用于多维输入数组的每个嵌套级别。” 你从哪里得到的?好像这不是真的。从快速测试来看,限制似乎适用于数组中的单元格总数,而不是嵌套级别。
【解决方案2】:

在 php.ini 中更改 max_input_vars 对我不起作用

使用 .htaccess 文件更改 max_input_vars 有效。

如果您想使用 .htaccess 文件更改“max_input_vars”,请转到 C:\xampp\apache\conf\httpd.conf 文件(在 xampp 中)在您的 .htaccess 文件中添加以下代码。

php_value max_input_vars 10000

【讨论】:

  • 如果我们尝试使用 cli 导入 sql 怎么办?
【解决方案3】:

真的,使用.htaccess 更改max_input_vars 文件正在运行,但您需要重新启动Apache 服务。

遵循完整的流程:

  1. 转到C:\xampp\apache\conf\httpd.conf
  2. 打开文件httpd.conf
  3. 在文件中查找xampp/htdocs
  4. 再低一点,你可能会看到这样一行:AllowOverride
  5. 如果此行在AllowOverride 之前显示#,请删除#
  6. AllowOverride 之后的下一行插入 php_value max_input_vars 10000
  7. 保存文件并关闭
  8. 最后停止 Apache 并重新启动(它会在重新启动 apache 后工作)

【讨论】:

    【解决方案4】:

    出了点问题,你不需要 1000 个变量。重新编码您的程序以接受 1 个具有 1000 个键的变量数组。这个错误是为了警告你你没有按照推荐的方式做事。不要以任何方式禁用、扩展或隐藏它。

    【讨论】:

    • 如果 Magento 有 1.9 GB 怎么办?
    • 我有一个 70 行 13 列的表格,每个单元格中有 2 个文本框。是的,我绝对不会按照推荐的方式做事。 ^_^
    • 我尝试使用关联数组作为变量名,但是我仍然收到警告(并且数据仍然被截断)。我希望 POST 数组中的一个数组算作一个变量,但显然它仍然算作数组中的元素数。
    • 我现在使用 JavaScript 将文本框表转换为 JSON 数组,然后在 POST 中将其作为单个变量传递。在 PHP 中,我将其解码为我需要的关联数组。完美运行,只有 1 个变量而不是 1,820 个变量 :)
    • 这是不正确的。我有 2 个变量,每个变量有 500 个键,这会触发错误
    【解决方案5】:

    我发现直接在 PHP(通过file_get_contents('php://input'))中处理 json 数据的正确方法是确保请求在 HTTP 请求标头中设置正确的内容类型,即Content-type: application/json

    在我的情况下,我正在使用 curl 向 php 请求页面:

    function curl_post($url, array $post = NULL, array $options = array()) {
      $defaults = array(
        CURLOPT_POST => 1,
        CURLOPT_HEADER => 0,
        CURLOPT_URL => $url,
        CURLOPT_FRESH_CONNECT => 1,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_FORBID_REUSE => 1,
        CURLOPT_TIMEOUT => 600
      );
      if(!is_null($post))
        $defaults['CURLOPT_POSTFIELDS'] = http_build_query($post);
      $ch = curl_init();
      curl_setopt_array($ch, ($options + $defaults));
      if(($result = curl_exec($ch)) === false) {
        throw new Exception(curl_error($ch) . "\n $url");
      }
      if(curl_getinfo($ch, CURLINFO_HTTP_CODE) != 200) {
        throw new Exception("Curl error: ". 
          curl_getinfo($ch, CURLINFO_HTTP_CODE) ."\n".$result . "\n");
      }
      curl_close($ch);
      return $result;
    }
    
    $curl_result = curl_post(URL, NULL,
        array(CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
          CURLOPT_POSTFIELDS => json_encode($out))
        );
    

    请注意CURLOPT_HTTPHEADER =&gt; array('Content-Type: application/json') 部分。

    在接收端,我使用以下代码:

    $rawData = file_get_contents('php://input');
    $postedJson = json_decode($rawData,true);
    if(json_last_error() != JSON_ERROR_NONE) {
      error_log('Last JSON error: '. json_last_error(). 
        json_last_error_msg() . PHP_EOL. PHP_EOL,0);
    }
    

    不要更改 max_input_vars 变量。 自从更改请求以设置正确的标头后,max_input_vars 的问题就消失了。显然 PHP 不会评估设置了某些 Content-type 的 post 变量。

    【讨论】:

      【解决方案6】:

      改变这个

      ; max_input_vars = 1000
      

      到这里

      max_input_vars = 3000
      

      php.ini 文件中的注释行是

      ;
      

      【讨论】:

        【解决方案7】:

        我认为大多数时候没有必要增加max_input_vars的大小

        但要优化您的代码

        我在从一个 ajax 请求中获取所有结果并将结果发送到另一个 ajax 请求时遇到了这个问题。

        所以我所做的是从数据库结果中对数组进行字符串化

        JSON.stringify(totalResults);
        

        in javascript JSON.stringify convert array to string 所以在转换后我已经将该字符串发送到另一个请求并 在 php 中使用json_decode 再次将该字符串解码为数组,

        <?php $totalResults = json_decode($_POST['totalResults']); ?>
        

        所以我又得到了那个原始数组,

        我希望这可以帮助某人,所以我分享了它,谢谢。

        【讨论】:

        • 是的,这正是我的情况。我本可以轻松地将 max_input_vars 更改为更大的数字。但是我怎么知道对于我无法控制的数据集大小来说更大的数字是最大的呢?所以这些转换就是我现在所做的。现在我只需要担心 post_max_size....
        【解决方案8】:

        我可以接受 PHP 有这样的限制;这确实有道理。我不能接受的(也是让我很难将 PHP 作为一种编程语言认真对待的众多原因之一)是处理然后继续处理截断的数据,可能会用不完整的数据覆盖好的数据。是的,数据应该在持久化之前进行额外验证。但这种行为只是自找麻烦。

        也就是说,我实施了以下措施来防止这种情况再次发生:

        $limit = (int)ini_get('max_input_vars');
        if (count($_GET) >= $limit) {
            throw new Exception('$_GET is likely to be truncated by max_input_vars (' . $limit . '), refusing to continue');
        }
        if (count($_POST) >= $limit) {
            throw new Exception('$_POST is likely to be truncated by max_input_vars (' . $limit . '), refusing to continue');
        }
        if (count($_COOKIE) >= $limit) {
            throw new Exception('$_COOKIE is likely to be truncated by max_input_vars (' . $limit . '), refusing to continue');
        }
        

        请注意,截断不一定发生在极限处。我的限制设置为默认的 1000,但 $_POST 最终仍然有 1001 个元素。

        【讨论】:

          【解决方案9】:

          我遇到了同样的问题。我发现我在 POST 数据中发送了一个 2Mb 的文件,有时会被奇怪地解释为 JSON,它会找到所有这些变量。

          我最终使用文件参数发送了信息,但文件内容仍在 POST 数据中。

          curl_setopt($ch, CURLOPT_PUT, true);
          curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
          curl_setopt($ch, CURLOPT_INFILE, ($fp = fopen("filename.txt", "r")));
          fclose($fp);
          

          【讨论】:

            【解决方案10】:

            我在使用响应数据进行另一个 AJAX 调用时遇到了斜杠问题,我使用 stripslashes() 函数来解决这个问题。

            Javascript AJAX:

            course_data: JSON.stringify(response.data)
            

            PHP 后端:

            $course_data = json_decode(stripslashes($_POST['course_data']));
            

            【讨论】:

              猜你喜欢
              • 2012-03-29
              • 1970-01-01
              • 1970-01-01
              • 2015-06-21
              • 2015-08-02
              • 1970-01-01
              • 2014-02-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多