我正在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_vars
在php.ini
中的角色为:
可以接受多少个输入变量(限制适用于
$_GET
,$_POST
和$_COOKIE
superglobal分别)。此指令的使用降低了使用哈希的拒绝服务攻击的可能性碰撞。如果有比这个指定的更多的输入变量指令时,发出E_WARNING
,进一步的输入变量为从请求中截断。此限制仅适用于每个嵌套多维输入数组的级别。
你只需要在你的php.ini
中为max_input_vars
设置更大的数字
真的,使用.htaccess
文件更改max_input_vars
是有效的,但是你需要重新启动Apache服务。
遵循完整的流程:
- 转到
C:'xampp'apache'conf'httpd.conf
- 打开
httpd.conf
文件 - 查找
xampp/htdocs
- 稍微低一点,你可能会看到这样的一行:
AllowOverride
- 如果这行显示
#
在AllowOverride
之前,删除#
-
AllowOverride
之后插入php_value max_input_vars 10000
- 保存文件并关闭
- 最后停止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服务器,这就是我如何解决上面提到的问题。
-
打开
php.ini
文件 -
取消注释
; max_input_vars = 1000
,去掉分号 -
像
max_input_vars = 10000
一样改成10000
如果在运行visual studio代码时发生
创建/更新文件 .user.ini
添加行
max_input_vars = 2000
保存文件并重新启动服务器
也就是说,我实现了以下操作来防止这种情况再次发生:
$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个元素。