$_POST和$GLOBALS['HTTP_RAW_POST_DATA'] 的區別

HTTP 協議是創建在 TCP/IP 協議之上的應用層規範,它把 HTTP 請求分爲三個部分:請求行、請求頭、消息主體。協議規定 POST 提交的數據必須放在消息主體(entity-body)中,但協議並無規定數據使用什麼編碼方式。
服務端一般是根據請求頭(headers)中的 Content-Type 來獲知請求中的消息主體是用何種方式編碼的,再對消息主體進行解析。

當客戶端經過 POST 請求訪問服務器時,可經過下面三種方式來獲取 POST 提交的數據:
1. $_POST
僅當請求頭中的  Content-Type 爲 application/x-www-data-urlencoded 或 multipart/form-data時,PHP 纔會將 POST 數據填充到全局變量 $_POST。
如:表單數據的POST方式提交或curl模擬POST請求時傳入數組格式的POST數據(不要使用二維數組)。

2. $HTTP_RAW_POST_DATA
當請求頭中的 Content-Type 不是 PHP 可以識別的(如:xml、json),且 php.ini 中已經配置 always_populate_raw_post_data = On,纔可使用 $HTTP_RAW_POST_DATA。但對於enctype="multipart/form-data",它是無效的。
$HTTP_RAW_POST_DATA 或 $GLOBALS['HTTP_RAW_POST_DATA'] 中包含的是原生的 POST 數據。
自 PHP 5.6.0 版本,就不同意使用它;在 PHP 7.0.0 中已經將其移除。不過,訪問原始 POST 數據的更好方法是 php://input。$HTTP_RAW_POST_DATA 對於 enctype="multipart/form-data" 表單數據不可用。
那麼問題來了: $HTTP_RAW_POST_DATA == $_POST 嗎?
NO
The RAW / uninterpreted HTTP POst information can be accessed with:
$GLOBALS['HTTP_RAW_POST_DATA']
This is useful in cases where the post Content-Type is not something PHP understands (such as text/xml).

也就是說,基本上$GLOBALS['HTTP_RAW_POST_DATA'] 和 $_POST是同樣的。可是若是post過來的數據不是PHP可以識別的,你能夠用 $GLOBALS['HTTP_RAW_POST_DATA']來接收,好比 text/xml 或者 soap 等等。

PHP默認識別的數據類型是application/x-www.form-urlencoded標準的數據類型

用Content-Type=text/xml 類型,提交一個xml文檔內容給了php server,要怎麼得到這個POST數據。

The RAW / uninterpreted HTTP POST information can be accessed with: $GLOBALS['HTTP_RAW_POST_DATA'] This is useful in cases where the post Content-Type is not something PHP understands (such as text/xml).

因爲PHP默認只識別application/x-www.form-urlencoded標準的數據類型,所以,對型如text/xml的內容沒法解析爲$_POST數組,故保留原型,交給$GLOBALS['HTTP_RAW_POST_DATA'] 來接收。

另外還有一項 php://input 也能夠實現此這個功能

php://input 容許讀取 POST 的原始數據。和 $HTTP_RAW_POST_DATA 比起來,它給內存帶來的壓力較小,而且不須要任何特殊的 php.ini 設置。php://input 不能用於 enctype="multipart/form-data"。
3. php: //input
當請求頭中的 Content-Type 不是 PHP 可以識別的(如:xml、json),就可使用 php: //input。
如:curl模擬POST請求時傳入的json格式的字符串(能夠是二維json)或任意字符串。

php: //input 是一個只讀的數據流,經過它能夠獲取請求主體中的原始數據。POST請求時,通常使用 php: //input 來代替 $HTTP_RAW_POST_DATA,由於 php: //input 不用激活always_populate_raw_post_data,這樣就減小了潛在的內存消耗。
但對於enctype="multipart/form-data",php: //input 是無效的。
經過 file_get_contents('php://input') 獲取原生的POST數據。

應用實例:
客戶端頁面:php

<form action="post.php" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit">
</form>

後端post.php:json

<? echo file_get_contents("php://input"); ?>
相關文章
相關標籤/搜索