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

PHP POST 數據處理全解析:表單 vs fsockopen vs php://input

     編輯:PHP 相關知識

三種 POST 數據獲取方式對比

方式適用場景特點獲取變量
表單提交瀏覽器普通表單自動解析、urldecode、編碼轉換$_POST、php://input
fsockopen 模擬服務端之間通訊、爬蟲手動構造 HTTP 報文、完全可控$_POST、php://input
非標準 Content-TypeAPI、JSON、XML、文件上傳PHP 不自動解析php://input、$HTTP_RAW_POST_DATA

核心變量詳解

1. $_POST —— 最常用

  • 僅當 Content-Type: application/x-www-form-urlencoded 或 multipart/form-data 時自動填充。
  • 鍵值對結構,自動 urldecode。
  • 文件上傳時文件信息在 $_FILES,不在 $_POST。

2. php://input —— 原始流(推薦)

  • 讀取未經處理的 HTTP 實體體(Raw Body)。
  • 內存佔用小,無需 php.ini 配置。
  • 不可用於 multipart/form-data(文件上傳)。
  • 典型用途:接收 JSON API 數據 json_decode(file_get_contents('php://input'), true)。

3. $HTTP_RAW_POST_DATA —— 棄用(PHP 7.0 移除)

  • 僅當 Content-Type 為 PHP 無法識別類型時才填充。
  • 需 php.ini 開啟 always_populate_raw_post_data = On(PHP 5.6+ 棄用)。
  • 內存佔用大,新代碼請勿使用。

實戰代碼對比

場景 A:普通表單提交

<?php
// 瀏覽器 POST:name=foo&email=bar@example.com
var_dump($_POST);          // ['name'=>'foo', 'email'=>'bar@example.com']
var_dump(file_get_contents('php://input')); // "name=foo&email=bar@example.com"
?>

場景 B:JSON API 請求

<?php
// Client: Content-Type: application/json
// Body: {"id":1,"action":"buy"}
$data = json_decode(file_get_contents('php://input'), true);
var_dump($data); // ['id'=>1, 'action'=>'buy']
var_dump($_POST); // [] 空!PHP 不解析 application/json
?>

場景 C:fsockopen 模擬 POST

<?php
$sock = fsockopen('localhost', 80, $errno, $errstr, 30);
if (!$sock) die("$errstr ($errno)");

$postData = http_build_query(['txt' => '中文', 'bar' => 'Value']);
$req = "POST /posttest/response.php HTTP/1.1\r\n"
     . "Host: localhost\r\n"
     . "Content-Type: application/x-www-form-urlencoded\r\n"
     . "Content-Length: " . strlen($postData) . "\r\n"
     . "Connection: close\r\n\r\n"
     . $postData;

fwrite($sock, $req);
$resp = '';
while (!feof($sock)) $resp .= fgets($sock, 4096);
fclose($sock);
// $resp 包含響應頭 + 體,需自行分離
echo $resp;
?>

關鍵結論

  1. 優先用 php://input 獲取原始數據,再按業務反序列化(JSON、XML、Protobuf 等)。
  2. $_POST 只處理標準表單編碼,不可靠用於 API。
  3. $HTTP_RAW_POST_DATA 已被移除,舊項目遷移至 php://input。
  4. 文件上傳(multipart/form-data)只能用 $_POST/$_FILES,無法用 php://input。
  5. 手動構造請求時,務必正確設置 Content-Length 與 Content-Type。

最佳實踐封裝

<?php
function getInputData(): array {
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
    $raw = file_get_contents('php://input');

    if (str_starts_with($contentType, 'application/json')) {
        return json_decode($raw, true) ?? [];
    }
    if (str_starts_with($contentType, 'application/x-www-form-urlencoded')) {
        parse_str($raw, $parsed);
        return $parsed;
    }
    // 其他類型(XML、自定義)按需擴展
    return [];
}
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved