关于不建议使用$ HTTP_RAW_POST_DATA的警告


121

我切换到PHP 5.6.0,现在到处都收到以下警告:

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will
be removed in a future version. To avoid this warning set
'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream
instead. in Unknown on line 0

Warning: Cannot modify header information - headers already sent in Unknown on line 0

很好,我依靠一些不推荐使用的功能。除了我不知道!

  1. 我从未在任何脚本中使用过此变量。老实说,我什至不知道它甚至存在。
  2. phpinfo()显示我已always_populate_raw_post_data设置为0(禁用)。那么发生了什么?

我不想通过将此值设置为-1来“避免警告”。这只会隐藏警告,而我仍将弃用配置。我想从HTTP_RAW_POST_DATA根本上解决问题,并且知道PHP为什么认为打开了填充。


相同的问题,但可能的原因/解决方案有所不同:stackoverflow.com/questions/25984623/…–
rr

在PHP> = 5.6上运行PHP SoapServer的handle()时,此警告给我带来麻烦。该警告将始终在SOAP响应中输出,因此SoapClient的__soapCall()将获得“ SoapFault异常:[客户端]看起来我们没有XML文档”异常。很难调试,因为此警告通常不会显示。
Johnny Wong

Answers:


135

事实证明,我对错误消息的理解是错误的。我会说它的单词选择能力很差。环顾四周,向我展示了其他人完全像我一样误解了该消息-请参阅PHP bug#66763

完全无济于事之后,“这就是客户经理想要的方式。” 针对Mike的错误,Tyrael解释说,将其设置为“ -1”并不仅会使警告消失。它做正确的事情,也就是说,它完全禁用填充的罪魁祸首变量。事实证明,在某些情况下,将其设置为0 仍可填充数据。谈论糟糕的设计!引用PHP RFC

更改always_populate_raw_post_data INI设置以接受三个值,而不是两个。

  • -1:主人的行为;永远不要填充$ GLOBALS [HTTP_RAW_POST_DATA]
  • 0 /关闭/任何:BC行为(如果未注册content-type或请求方法不是POST,则填充)
  • 1 / on / yes / true:BC行为(始终填充$ GLOBALS [HTTP_RAW_POST_DATA])

因此,是的,将其设置为-1不仅可以避免警告(如消息所述),而且还最终禁止填充此变量,这正是我想要的。


23
tl; dr这是一个愚蠢的警告,即使您不使用它警告的内容,它也会出现;将always_populate_raw_post_data设置为-1
srcspider 2015年

7
我已经设置好了always_populate_raw_post_data = -1。现在仍然出现警告,并且破坏了json响应
itsazzad 2015年

2
因此,有效的答案是转到您的php.ini文件并进行设置(或取消注释)always_populate_raw_post_data = -1
约翰

但是我真的不明白这一点。这正是警告在说什么?To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead.
安德里亚斯(Andreas)

@Andreas的原因是它这么说的原因,即0(显然是“禁用”)和-1(即...“更强禁用”)之间的差?→困惑→这个问题(和答案)的原因。
rr-

39

过了一段时间,直到我遇到这个错误。为可能会偶然发现此问题的任何人提供我的答案。

该错误仅表示您正在发送一个空的POST请求。通常在没有传递参数的HTTPRequests上发现此错误。为避免此错误,您始终可以在不更改php.ini的情况下向POST添加参数。

喜欢:

$.post(URL_HERE
    ,{addedvar : 'anycontent'}
    ,function(d){
       doAnyHere(d);
    }
    ,'json' //or 'html','text'
);

4
这是我找到的最佳答案!我一直在处理这个问题一个月,这让我朝错误的方向看。我只是一个空的POST意外事故,一旦解决,一切都很好!谢谢您让我免于头痛!
Craig Howell

34

我在nginx服务器(DigitalOcean)上遇到了相同的问题-我要做的就是以as身份登录root并修改文件/etc/php5/fpm/php.ini

要找到与always_populate_raw_post_data我首先运行的行grep

grep -n 'always_populate_raw_post_data' php.ini

那回线 704

704:;always_populate_raw_post_data = -1

然后只需php.ini使用vi编辑器在该行上打开:

vi +704 php.ini

删除半冒号以取消注释并保存文件 :wq

最后重新启动服务器,错误消失了。


3
如果该行在您的注释中被注释掉,则您php.ini可能正在使用php.ini的开发配置。
BadHorsie 2015年

13

如果您正在使用WAMP ...

您应该在中添加或取消注释该属性always_populate_raw_post_dataphp.ini并将其值设置为-1。在我的情况下php.ini位于:

C:\wamp64\bin\php\php5.6.25\php.ini

..但是如果您仍然收到警告(像我一样)

你也应该设定always_populate_raw_post_data = -1phpForApache.ini

C:\wamp64\bin\php\php5.6.25\phpForApache.ini

如果找不到此文件,请打开浏览器窗口,然后转到:

http://localhost/?phpinfo=1

并查找“ 已加载的配置文件”密钥的值。就我而言php.ini,WAMP使用的位于:

C:\wamp64\bin\apache\apache2.4.23\bin\php.ini (符号链接到C:\ wamp64 \ bin \ php \ php5.6.25 \ phpForApache.ini)

最后重新启动WAMP(或单击重新启动所有服务)


6

如果该.htaccess文件不可用,请在根文件夹上并在此代码行之后创建它。

将此.htaccess文件放入文件中(已测试API正常运行)

<IfModule mod_php5.c>
    php_value always_populate_raw_post_data -1
</IfModule>

2
请解释我的主
Zohaib 18/09/17

5

取消注释

always_populate_raw_post_data = -1 

在php.ini中(行号703)并重新启动APACHE服务有助于我摆脱该消息

; Always populate the $HTTP_RAW_POST_DATA variable. PHP's default behavior is
; to disable this feature and it will be removed in a future version.
; If post reading is disabled through enable_post_data_reading,
; $HTTP_RAW_POST_DATA is *NOT* populated.
; http://php.net/always-populate-raw-post-data
; always_populate_raw_post_data = -1

4

对于在更改php.init后仍仍在解决此问题的任何人,这都是公认的答案。由于在POST没有任何参数的情况下进行Ajax请求时会发生错误,因此您要做的就是将send方法更改为GET

var xhr = $.ajax({
   url:  url,
   type: "GET",
   dataType: "html",
   timeout: 500,
});

如果您POST出于任何原因想要保留此方法,则还有一个选择是向ajax petititon添加一个空的JSON对象。

var xhr = $.ajax({
   url:  url,
   type: "POST",
   data: {name:'emtpy_petition_data', value: 'empty'}
   dataType: "html",
   timeout: 500,
});

4

从html表单(Post方法)发送数据时收到此错误消息。我要做的就是将编码形式从“文本/纯文本”更改为“ application / x-www-form-urlencoded”或“ multipart / form-data”。该错误信息是非常令人误解的。


2

不幸的是,@ EatOng在此给出的答案不正确。阅读他的回答后,我向我触发的每个AJAX请求中都添加了一个虚拟变量(即使其中一些已经具有某些字段),以确保错误不会出现。

但是现在,我遇到了来自PHP的同样该死的错误。我再次确认我已经发送了一些POST数据(其他一些字段以及哑变量)。PHP版本5.6.25always_populate_raw_post_data值设置为0

另外,在发送application/json请求时,PHP并未将其填充到$_POST,而是必须填充到json_decode()原始POST请求正文(可通过访问)php://input

作为@ rr-的答案,

0 / off /无论如何:BC行为(如果未注册content-type请求方法不是POST,填充)。

因为request方法是确定的POST,所以我猜PHP无法识别/喜欢我的Content-Type: application/json请求(再次,为什么?)。

选项1:

php.ini手动编辑文件,并将罪魁祸首变量设置为-1,如此处的许多答案所示。

选项2:

这是一个PHP 5.6错误。升级PHP。

选项3:

正如@ user9541305在此处回答的那样,将Content-TypeAJAX请求的更改为application/x-www-form-urlencodedmultipart/form-data将使PHP $_POST从POSTed主体中填充(因为PHP喜欢/识别这些content-type标头!?)。

选项4:最后的度假胜地

好吧,我不想更改Content-TypeAJAX的代码,这会给调试带来很多麻烦。(Chrome DevTools很好地查看了JSON请求的POSTed变量。)

我正在为客户端开发此东西,不能要求他们使用最新的PHP,也不能编辑php.ini文件。作为最后的选择,我将只检查它是否设置为0,如果设置为,请php.ini在我的PHP脚本本身中编辑文件。当然,我将不得不要求用户重新启动apache。多可惜!

这是一个示例代码:

<?php

if(ini_get('always_populate_raw_post_data') != '-1')
{
    // Get the path to php.ini file
    $iniFilePath = php_ini_loaded_file();

    // Get the php.ini file content
    $iniContent = file_get_contents($iniFilePath);

    // Un-comment (if commented) always_populate_raw_post_data line, and set its value to -1
    $iniContent = preg_replace('~^\s*;?\s*always_populate_raw_post_data\s*=\s*.*$~im', 'always_populate_raw_post_data = -1', $iniContent);

    // Write the content back to the php.ini file
    file_put_contents($iniFilePath, $iniContent);

    // Exit the php script here
    // Also, write some response here to notify the user and ask to restart Apache / WAMP / Whatever.
    exit;
}

0

好吧,如果有人在共享主机上,并且无法访问php.ini文件,则可以在PHP文件的顶部设置以下代码行:

ini_set('always_populate_raw_post_data', -1);

作品更多相同。我希望它可以节省一些调试时间:)


0

注意:如果您正在使用PHPSTORM 在此处输入图片说明


我花了一个小时试图解决这个问题,以为那是我的php服务器问题,因此我在php.ini中将“ always_populate_raw_post_data”设置为“ -1”,但没有任何效果。

直到我发现使用内置服务器中的phpStorm才是导致问题的原因,如这里的答案所述:LazyOne的回答在这里,所以我考虑过共享它。



-1

我刚刚从朋友那里得到了解决这个问题的方法。他说:添加ob_start(); 在您的会话代码下。您可以添加exit(); 在标题下。我尝试了一下,它奏效了。希望这可以帮助

这适用于租用托管服务器且无法访问php.init文件的用户。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.