很不幸,这里@EatOng的回答是不正确的。在阅读他的回答后,我为每个AJAX请求添加了一个虚拟变量(即使有些请求已经有了一些字段),只是为了确保错误永远不会出现。
但现在我遇到了同样的PHP错误。我再次确认我发送了一些POST数据(除了虚拟变量还有其他一些字段)。PHP版本5.6.25
,always_populate_raw_post_data
值设置为0
。
此外,由于我正在发送一个application/json
请求,PHP并没有将它们填充到$_POST
中,而是我必须使用json_decode()
解码原始POST请求体,它可以通过php://input
访问。
正如@rr-引用的回答所述:
0/off/whatever: BC行为(如果内容类型未注册或请求方法不是POST,则填充)。
因为请求方法肯定是POST,我想PHP没有识别/喜欢我的Content-Type: application/json
请求(为什么?)。
选项1:
手动编辑php.ini
文件,并将罪魁祸首的变量设置为-1
,正如这里的许多答案所建议的那样。
选项2:
这是PHP 5.6的一个错误。升级PHP。
选项3:
就像@user9541305在这里回答的那样,更改AJAX请求的Content-Type
为application/x-www-form-urlencoded
或multipart/form-data
将使PHP从POSTed body填充$_POST
(因为PHP喜欢/识别这些content-type
头!?)。
选项4:最后的办法
好吧,我不想改变AJAX的Content-Type
,这会给调试带来很多麻烦。(Chrome DevTools能够很好地查看JSON请求的POST变量。)
我正在为客户开发这个东西,不能要求他们使用最新的PHP,也不能要求他们编辑php.ini文件。作为最后的选择,我将检查它是否设置为0
,如果是,就在我的PHP脚本中编辑php.ini
文件。当然,我必须要求用户重新启动Apache。真丢人!
这是一个示例代码:
<?php
if(ini_get('always_populate_raw_post_data') != '-1')
{
$iniFilePath = php_ini_loaded_file();
$iniContent = file_get_contents($iniFilePath);
$iniContent = preg_replace('~^\s*;?\s*always_populate_raw_post_data\s*=\s*.*$~im', 'always_populate_raw_post_data = -1', $iniContent);
file_put_contents($iniFilePath, $iniContent);
exit;
}