微信开发中$GLOBALS[‘HTTP_RAW_POST_DATA’]失效的解决方案与PHP7兼容性指南
最近,在微信公众号开发中使用$GLOBALS["HTTP_RAW_POST_DATA"]去获取微信公众平台推送过来的 post 数据。结果让人惊奇,发现微信号总是提示“该微信公众号暂时无法提供服务”。仔细去检查代码,并未发现错误,然而就是无法提供服务。今天进行了一次检查,仍然没有发现语法错误。接着,我把中间的所有数据都写入了 html 文件中。通过记事本发现,获取到的$GLOBALS["HTTP_RAW_POST_DATA"]的数据为空。
![微信开发中$GLOBALS[‘HTTP_RAW_POST_DATA’]失效的解决方案与PHP7兼容性指南 微信开发中$GLOBALS[‘HTTP_RAW_POST_DATA’]失效的解决方案与PHP7兼容性指南](http://blog.seo.xz.cn/zb_users/upload/sanimg/91af858e9be657788455e5525e384932.png)
php7 不再对 HTTP_RAW_POST_DATA 提供支持,在微信开发过程中,无法通过 $GLOBALS['HTTP_RAW_POST_DATA']获取到数据。以下是解决方法:可以使用 php://input 来替代 $GLOBALS['HTTP_RAW_POST_DATA']。
比如:
$GLOBALS['HTTP_RAW_POST_DATA'] 的值被赋给了 $data 。
//替换为:
从“php://input”获取到的内容被赋值给了变量 $data 。
对于PHP5.6以前版本,进行一下测试,总结一下测试结果:
$GLOBALS["HTTP_RAW_POST_DATA"]与$_POST的file_get_contents('php://input')较为相似。通常使用$GLOBALS["HTTP_RAW_POST_DATA"]或file_get_contents('php://input'),是为了获取$_POST无法接收的数据类型,比如 XML 数据。
如果$GLOBALS ["HTTP_RAW_POST_DATA"]取不到值,那么可以通过以下方式进行排查:
使用 file_get_contents('php://input') 来获取数据。倘若无法获取到数据,那就有可能是出现了数据传输错误。此时需要对请求进行捉包,以便分析数据。
如果 file_get_contents('php://input')存在数据,那么就去查看 php.ini 配置文件。
找到如下,如果没开启则开启
始终填充原始帖子数据为开启状态。
这种处理方式仅在 php 版本较低时,才存在于 php-ini 中的配置。而当 php 版本升级到 7 或更高时,该机制就被废弃了。
下边归纳几种php获取post数据的方式:
RPC 规定了要通过 $GLOBALS['HTTP_RAW_POST_DATA'] 这种方式来接收取值。
PHP 默认能识别的是一种标准的数据类型,其类型标识为 application/x-。
1、$_POST['paramName']
只能接收 Content-Type 为 application/x-www-form-urlencoded 提交的数据。php 会把 http 请求 body 中的相应数据填入到数组 $_POST 里。填入到 $_POST 数组中的数据是经过 urldecode()解析后的结果。其实,除了该 Content-Type 之外,还有 multipart/form-data 这种情况表示数据是表单数据。
获取通过 PHP 输入流读取的内容,即使用 file_get_contents 函数读取 php://input 这个输入流中的数据。
php://input 可用于读取 POST 的原始数据,适用于大多数类型的 Content-type。与 $HTTP_RAW_POST_DATA 相比,它给内存带来的压力较小,且无需任何特殊的 php.ini 设置。php://input 无法被用于 enctype="multipart/form-data"这种情况。
'HTTP_RAW_POST_DATA' 在 $GLOBALS 里 ;
$HTTP_RAW_POST_DATA 变量会总是产生,并且其中包含原始的 POST 数据。此变量的产生是有条件的,仅在碰到未识别 MIME 类型的数据时才会产生。同时需要注意的是,$HTTP_RAW_POST_DATA 对于 enctype="multipart/form-data" 这种表单数据是不可用的。
如果有数据通过 post 方式传递过来,但这些数据不是 PHP 能够识别的,那么你可以借助 $GLOBALS['HTTP_RAW_POST_DATA']来进行接收,像 text/xml 这种类型或者 soap 之类的情况都可以。要使 PHP 总是将 POST 数据填入变量$http_raw_post_data,就需要将 php.ini 中的 always_populate_raw_post_data 值设置为 On。
Content-Type 只有在取值为 application/x-www-data-urlencoded 和 multipart/form-data 这两种情况时,PHP 才会把 http 请求数据包里相应的数据填入全局变量 $_POST 。
当遇到 PHP 不能识别的 Content-Type 类型时,会把 http 请求包中的相应数据填充到变量$HTTP_RAW_POST_DATA 中。
当 Coentent-Type 不为 multipart/form-data 时,PHP 不会将 http 请求数据包中的相应数据填入 php://input;而在其他情况下,都会填入。填入的长度由 Coentent-Length 指定。
当 Content-Type 为 application/x-www-data-urlencoded 时,php://input 数据才会跟 $_POST 数据相一致。
php://input 数据通常与$HTTP_RAW_POST_DATA 是相同的。然而,php://input 比$HTTP_RAW_POST_DATA 更有效。并且,使用 php://input 不需要对 php.ini 进行特殊设置。
PHP 会把 PATH 字段的 query_path 这部分内容填入全局变量 $_GET 。一般来讲,通过 GET 方法提交的 http 请求,其 body 是为空的。
【查了一下,手册里这么写的】:
变量有时会包含原始的 POST 数据。如果不是这种情况,那么此变量仅在遇到未识别 MIME 类型的数据时才会产生。然而,访问原始 POST 数据的更佳方式是 php://input。$HTTP_RAW_POST_DATA 对于 enctype="multipart/form-data" 表单数据是不可用的。