兩者均可獲取 POST 請求體,但適用場景、數據格式、性能特性截然不同。本文通過原理對比與實戰代碼,助你精準選型。
| 特性 | $_POST | php://input |
|---|---|---|
| 數據格式 | 解析後的關聯數組 | 原始請求體字符串 |
| Content-Type 支援 | application/x-www-form-urlencoded、multipart/form-data | 任意類型(JSON、XML、二進制等) |
| 編碼處理 | 自動 urldecode、字符集轉換 | 無任何處理,原始字節流 |
| 內存佔用 | 解析後結構,略大 | 可流式讀取,壓力更小 |
| php.ini 依賴 | 受 post_max_size 限制 | 不受 enable_post_data_reading 影響(關閉後 $_POST 為空,但 php://input 仍可讀) |
| 多次讀取 | 可重複訪問 | 流只能讀一次(除非用 file_get_contents 緩存) |
<form method="post" enctype="application/x-www-form-urlencoded">
</form>
<?php
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
?>
<?php
// 前端:fetch('/api', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({id:1})})
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
$id = $data['id'] ?? 0;
?>
multipart/form-data 時,php://input 可讀取原始多部分數據,但解析極其複雜,**務必使用 $_FILES**。
<?php
function getRawInput() {
static $cache = null;
if ($cache !== null) return $cache;
return $cache = file_get_contents('php://input');
}
// 解析 JSON 請求
function getJsonInput() {
$raw = getRawInput();
return json_decode($raw, true) ?? [];
}
// 解析 XML 請求
function getXmlInput() {
$raw = getRawInput();
return simplexml_load_string($raw);
}
?>
php://input,$_POST 可能為空(取決於 PHP 版本與 SAPI)。enable_post_data_reading 可節省內存:純 JSON API 服務可關閉,強制統一用 php://input。php://input 會將整個請求體載入內存,極易 OOM,必須用 $_FILES 流式處理。