$_POST,$HTTP_RAW_POST_DATA 和php://input 的區別
PHP 7 已經取消了$HTTP_RAW_POST_DATA,請用php://input 代替。
HTML <form> 標籤的enctype 屬性
首先來了解什麼是<form> 標籤的enctype 屬性,enctype 屬性規定了在發送到服務器之前應該如何對錶單數據進行編碼,有三種類型:
屬性值 | 描述 |
---|---|
application/x-www-form-urlencoded | 默認模式,在發送到服務器之前,所有字符都會進行編碼(空格轉換為“+” 加號,特殊符號轉換為ASCII HEX 值) |
multipart/form-data | 不對字符編碼,在使用包含文件上傳控件的表單時,必須使用該值。 |
text/plain | 空格轉換為“+” 加號,但不對特殊字符編碼。 |
當在網頁提交了一個表單之後,可以使用三種PHP 方式來獲取Post 數據:$_POST,$HTTP_RAW_POST_DATA 和php://input,有什麼區別呢?
$_POST
$_POST 是獲取表單POST 過來數據(body部分)的最常用方法,上傳的文件信息使用$_FILES 獲取。
$HTTP_RAW_POST_DATA
當瀏覽器從表單發送POST 請求的時候,默認的media type 是“application/x-www-form-urlencoded”,意思就是字段名和值都編碼了,每個key-value 對使用’&’ 字符分隔開,key 和value 使用’=’ 分開,並且key 和value 中的空格都會被替換成+ ,其他特殊字符都會被使用urlencode 方式進行編碼。
比如下面的key-value 對:
name: Jonathan Doe
age: 23
formula: a + b == 13%!
會被編碼下面的原始數據:
name=Jonathan+Doe&age=23&formula=a+%2B+b+%3D%3D+13%25%21
PHP 會解析這些原始的POST 數據,並且格式化成數組,填充到$_POST 中:
Array
(
[name] => Jonathan Doe
[age] => 23
[formula] => a + b == 13%!
)
$HTTP_RAW_POST_DATA 是PHP 的一個預定義的變量,用來獲取原始的POST 數據,比如上面的情況下,$HTTP_RAW_POST_DATA 的值就是:
name=Jonathan+Doe&age=23&formula=a+%2B+b+%3D%3D+13%25%21
但是$HTTP_RAW_POST_DATA 需要在php.ini 中設置開啟:
always_populate_raw_post_data = On
還有一點,$HTTP_RAW_POST_DATA 不支持enctype=”multipart/form-data” 方式傳遞的數據,這種情況下,我們要用$_POST 獲取字段的內容,$_FILES 來獲取上傳的文件信息。
php://input
由於$HTTP_RAW_POST_DATA 取決於php.ini 設置,有沒有更好的方法呢?
我們可以使用php://input 來獲取原始的POST 數據,並且php://input 比$HTTP_RAW_POST_DATA 更少消耗內存,當然php://input 和$HTTP_RAW_POST_DATA 一樣,它也不支持enctype=”multipart/form -data” 方式傳遞的數據。
由於php://input 只是數據流,我們可以使用file_get_contents() 函數去獲取它的內容:
$post_data = file_get_contents('php://input');
print_r($post_data);
獲取到的內容和$HTTP_RAW_POST_DATA 是一樣的。
原始的POST 數據有什麼用?
那麼原始的POST 數據有什麼用?因為很多時候,接收到不是網頁POST 過來的數據,而是可能通過其他方式POST 過來的“text/xml” 格式的數據,這些內容無法解析成$_POST 數組,這個時候我們就需要原始的POST 數據進行處理。