警告:输入变量超过1000


Warning: Input variables exceeded 1000

我正在PHP中构建一个类似rest的服务,它应该接受一个大的JSON post作为主要数据(我发送和读取数据就像这里讨论的那样: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 = 1000

max_input_vars = 3000
php.ini文件中的注释行为
;

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

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

但是优化你的代码

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

所以我所做的是字符串化数组从db的结果,

JSON.stringify(totalResults);

在javascript JSON.stringify 转换数组到字符串所以转换后,我已经发送字符串到另一个请求和解码字符串到数组再次使用json_decode 在php中,

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

我又得到了原始数组

我希望这能帮助别人,所以我已经分享了,谢谢。

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

在我的情况下,我请求页面从php使用curl与以下代码:

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 => 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设置后的变量。

根据php手册max_input_varsphp.ini中的角色为:

可以接受多少个输入变量(限制适用于$_GET$_POST$_COOKIE superglobal分别)。此指令的使用降低了使用哈希的拒绝服务攻击的可能性碰撞。如果有比这个指定的更多的输入变量指令时,发出E_WARNING,进一步的输入变量为从请求中截断。此限制仅适用于每个嵌套多维输入数组的级别。

你只需要在你的php.ini中为max_input_vars设置更大的数字

真的,使用.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后工作)

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

使用。htaccess文件更改max_input_vars是否有效

如果你想改变" max_input_vars "使用。htaccess文件,然后去C:'xampp'apache'conf'httpd.conf文件(在xampp)添加以下代码在你的。htaccess文件。

php_value max_input_vars 10000

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

Javascript AJAX:

course_data: JSON.stringify(response.data)
PHP后端:

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

我也有同样的问题。我发现我在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);

我在pc上运行Apache服务器,这就是我如何解决上面提到的问题。

  1. 打开php.ini文件

  2. 取消注释; max_input_vars = 1000,去掉分号

  3. max_input_vars = 10000一样改成10000

如果在运行visual studio代码时发生

创建/更新文件 .user.ini

添加行

max_input_vars = 2000

保存文件并重新启动服务器

我可以接受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个元素。