PHP 接收 POST 數據的方式取決於 Content-Type 與客戶端類型。本文系統對比 $_POST、php://input、$HTTP_RAW_POST_DATA 三大通道的適用場景、數據格式限制、內存影響與代碼實戰,助你精準選型。
| 通道 | 適用 Content-Type | 數據結構 | 內存影響 | PHP 版本狀態 |
|---|---|---|---|---|
$_POST | application/x-www-form-urlencodedmultipart/form-data | 關聯陣列 (自動解析) | 低 (已解析) | 全版本穩定 |
php://input | 任意 (除 multipart/form-data) | 原始字符串流 | 中 (按需讀取) | 全版本推薦 |
$HTTP_RAW_POST_DATA | 未識別 MIME 類型 | 原始字符串 (自動填充) | 高 (始終填充) | PHP 7.0 棄用, 8.0 移除 |
<?php // 瀏覽器表單提交 / AJAX application/x-www-form-urlencoded $name = $_POST['name'] ?? ''; $email = $_POST['email'] ?? ''; // 自動解析鍵值對,支援多維陣列 name="user[name]" ?>
application/json、text/xml、application/octet-stream 等非標準表單類型。<?php
// 讀取原始 POST 體
$raw = file_get_contents('php://input');
// 應用場景 A: JSON API
$data = json_decode($raw, true); // 關聯陣列
// 應用場景 B: XML/SOAP
$xml = simplexml_load_string($raw);
// 應用場景 C: 文件上傳 (非 multipart)
file_put_contents('upload.bin', $raw);
// 應用場景 D: 簽名驗證 (需原始體計算 HMAC)
$signature = hash_hmac('sha256', $raw, $secret);
?>
$_POST 解析內存,大數據流優勢明顯。<?php // 需 php.ini: always_populate_raw_post_data = On (PHP 5.6 預設 Off) $raw = $GLOBALS['HTTP_RAW_POST_DATA']; // 或 $HTTP_RAW_POST_DATA ?>
always_populate_raw_post_data 選項控制是否自動填充。php://input。<?php
// post_receiver.php
header("Content-Type: text/html; charset=utf-8");
echo "1. \$_POST 接收:<br/>";
print_r($_POST);
echo "<hr/>";
echo "2. \$GLOBALS['HTTP_RAW_POST_DATA'] 接收:<br/>";
print_r($GLOBALS['HTTP_RAW_POST_DATA'] ?? '未填充 (需啟用 always_populate_raw_post_data)');
echo "<hr/>";
echo "3. php://input 接收:<br/>";
$raw = file_get_contents('php://input');
print_r(urldecode($raw)); // 表單數據需手動 urldecode
echo "<hr/>";
?>
<form action="post_receiver.php" method="post">
Name: <input name="name"><br>
Email: <input name="email"><br>
<input type="submit">
</form>
$_POST。php://input。$_SERVER['CONTENT_TYPE'] 分流處理。<?php
function getPostData() {
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (strpos($contentType, 'application/json') === 0) {
return json_decode(file_get_contents('php://input'), true);
}
if (strpos($contentType, 'application/xml') === 0 || strpos($contentType, 'text/xml') === 0) {
return simplexml_load_string(file_get_contents('php://input'));
}
// 默認表單
return $_POST;
}
$data = getPostData();
// 統一業務邏輯處理 $data
?>
理解三通道本質差異,按 Content-Type 精準分流,是構建健壯 API 接入層的關鍵。