公司的微信公衆號最近出現問題,全部的功能都不能用,一開始覺得是微信公衆號驗證的問題,通過排查才發現是$GLOBALS['HTTP_RAW_POST_DATA']這裏的問題,微信公衆號會把用戶的一些操做和輸入已數據的格式發送到在微信公衆號中配置的url地址(通常是項目的服務器),由於是數據因此就用$GLOBALS['HTTP_RAW_POST_DATA']接收,而後在作數據轉換,可是在日誌中發現這個值是null,而後通過排查發現不知道何時在php.ini中禁掉了這個函數php
always_populate_raw_post_data = -1json
值的一提的是: PHP 5.6.0及更高版本不支持always_populate_raw_post_data,所以須要將其設置爲-1。 也就是說PHP5.6以後再也不支持此全局變量數組
因此爲了項目更好的維護能夠把這個變爲 file_get_contents('php://input');服務器
$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"]取不到值的狀況下能夠按如下方式排查:
1.用file_get_contents('php://input')獲取數據。若是獲取不到,則多是數據傳輸錯誤,對請求進行捉包,分析數據。
2.若是file_get_contents('php://input')有數據。則查看php.ini配置文件。
找到以下,若是沒開啓則開啓app
always_populate_raw_post_data = On函數
如今來講一下 $_POST $GLOBALS['HTTP_RAW_POST_DATA'] file_get_contents('php://input') 的區別,他們都是PHP獲取post數據的方式,但仍是有一些區別的post
RPC 規定接收取值方式 $GLOBALS['HTTP_RAW_POST_DATA'];
PHP默認識別的數據類型是application/x-www.form-urlencoded標準的數據類型。
一、$_POST['paramName']
只能接收Content-Type: application/x-www-form-urlencoded提交的數據,php會將http請求body相應數據會 填入到數組$_POST,填入到$_POST數組中的數據是進行urldecode()解析的結果。(其實,除了該Content-Type,還有 multipart/form-data表示數據是表單數據)
url
二、file_get_contents("php://input")
適用大多數類型的Content-type,php://input 容許讀取 POST 的原始數據。和 $HTTP_RAW_POST_DATA 比起來,它給內存帶來的壓力較小,而且不須要任何特殊的 php.ini 設置。php://input 不能用於 enctype="multipart/form-data"。
spa
三、$GLOBALS['HTTP_RAW_POST_DATA'];
老是產生 $HTTP_RAW_POST_DATA 變量包含有原始的 POST 數據。此變量僅在碰到未識別 MIME 類型的數據時產生。$HTTP_RAW_POST_DATA 對於 enctype="multipart/form-data" 表單數據不可用。
1,Coentent-Type僅在取值爲application/x-www-data-urlencoded和multipart/form- data兩種狀況下,PHP纔會將http請求數據包中相應的數據填入全局變量$_POST
2,PHP不能識別的Content-Type類型的時候,會將http請求包中相應的數據填入變量$HTTP_RAW_POST_DATA
3, 只有Coentent-Type爲multipart/form-data的時候,PHP不會將http請求數據包中的相應數據填入php: //input,不然其它狀況都會。填入的長度,由Coentent-Length指定。
4,只有Content-Type爲application/x-www-data-urlencoded時,php://input數據才 跟$_POST數據相一致。
5,php://input數據老是跟$HTTP_RAW_POST_DATA相同,可是php://input 比$HTTP_RAW_POST_DATA更湊效,且不須要特殊設置php.ini
6,PHP會將PATH字段的query_path部分,填入全局變量$_GET。一般狀況下,GET方法提交的http請求,body爲空。
總結以下:
一、若是是 application/x-www-form-urlencoded 和 multipart/form-data 格式 用 $_POST;
二、若是不能獲取的時候好比 text/xml、application/json、soap,使用 file_get_contents('php://input'),$GLOBALS['HTTP_RAW_POST_DATA']最好別用;