首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 輸入流 php://input 完全指南:讀取原始 POST 數據、對比 $_POST/$HTTP_RAW_POST_DATA、多場景實測

     編輯:PHP 綜合知識

官方定義

php://input 允許讀取原始 POST 數據。比 $HTTP_RAW_POST_DATA 更節省內存,無需特殊 php.ini 設置。不可用於 enctype=multipart/form-data。

核心結論速查表

Content-Type$_POSTphp://input$HTTP_RAW_POST_DATA
application/x-www-form-urlencoded✅ 解析後數組✅ 原始字串✅ 原始字串(需啟用 always_populate_raw_post_data)
multipart/form-data (文件上傳)✅ 解析後數組❌ 空❌ 空
text/xml, application/json 等其他❌ 空數組✅ 原始字串✅ 原始字串(需啟用)
GET 請求N/A (用 $_GET)❌ 空(實體體為空)❌ 空

實測驗證代碼

<?php
// server.php
$raw = file_get_contents('php://input');
echo "---- \$_POST ----\n"; var_dump($_POST);
echo "---- php://input ----\n"; var_dump($raw);
echo "---- \$HTTP_RAW_POST_DATA ----\n"; var_dump($GLOBALS['HTTP_RAW_POST_DATA'] ?? '未啟用');
?>

測試 1:標準表單 POST

POST /server.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 27

name=test&age=25

結果:$_POST 為 ['name'=>'test','age'=>'25'],php://input 為 "name=test&age=25",兩者內容一致(格式不同)。

測試 2:XML-RPC / JSON POST

POST /server.php HTTP/1.1
Content-Type: application/json
Content-Length: 28

{"action":"login","user":"abc"}

結果:$_POST 為 [],php://input 為原始 JSON 字串。這是讀取非表單 POST 數據的標準方式。

測試 3:multipart/form-data 文件上傳

php://input 返回空字串,必須使用 $_POST、$_FILES。

測試 4:GET 請求

查詢字串在 URL 中,HTTP 實體體為空,php://input 讀不到任何內容。

php://input vs $HTTP_RAW_POST_DATA

  • 數據內容完全一致(同源於 SAPI 讀取的原始請求體)。
  • php://input:流式讀取,佔用內存小,無需配置,推薦。
  • $HTTP_RAW_POST_DATA:需 always_populate_raw_post_data = On(PHP 5.6 棄用,PHP 7.0 移除),佔用內存大。

進階用法

流式處理大數據(避免一次性載入內存)

$fp = fopen('php://input', 'r');
while (!feof($fp)) {
    $chunk = fread($fp, 8192);
    // 處理 chunk,如寫入文件、流式解析 JSON
}
fclose($fp);

配合 stream_context 限制讀取長度

$ctx = stream_context_create(['http' => ['max_redirects' => 0]]);
$data = file_get_contents('php://input', false, $ctx);

常見誤區澄清

  1. 誤區:php://input 能讀取 GET 數據。事實:GET 無請求體,數據在 URL 查詢字串,用 $_GET。
  2. 誤區:php://input 總能讀到文件上傳數據。事實:multipart/form-data 時 PHP 直接解析到 $_FILES,不暴露給輸入流。
  3. 誤區:$HTTP_RAW_POST_DATA 是超全局變量。事實:它是普通全局變量,需 $GLOBALS['HTTP_RAW_POST_DATA'] 訪問,且已移除。

最佳實踐建議

  • API 接口接收 JSON/XML:$data = json_decode(file_get_contents('php://input'), true);
  • 需兼容舊版本:優先 php://input,回退 $HTTP_RAW_POST_DATA(極少見)。
  • 大文件上傳:使用 $_FILES + move_uploaded_file(),勿嘗試 php://input。
  • 安全:驗證 Content-Type、限制 Content-Length、防止惡意大請求佔用內存。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved