php://input 是 PHP 提供的只讀流,用於讀取請求體原始數據。適用於 Content-Type: application/json、application/xml、application/octet-stream 等非表單編碼場景,是 API 接口、文件上傳、Webhook 處理的核心機制。
POST、PUT、PATCHContent-Type ≠ multipart/form-dataContent-Type ≠ application/x-www-form-urlencoded (此類自動填充 $_POST)<?php
// 獲取原始請求體
$raw = file_get_contents('php://input');
// JSON API 典型處理
$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
exit('Invalid JSON');
}
// 處理業務邏輯...
echo json_encode(['status' => 'ok', 'received' => $data]);
| 特性 | $_POST | php://input | $HTTP_RAW_POST_DATA |
|---|---|---|---|
| 數據來源 | 表單解析結果 | 原始請求體 | 原始請求體 |
| Content-Type 支持 | form-urlencoded, multipart | 所有非 multipart | 所有非 multipart |
| 內存佔用 | 解析後結構 | 流式讀取可控 | 總是全量載入 |
| 配置需求 | 無 | 無 | 需 always_populate_raw_post_data=On (PHP 5.6 棄用, 7.0 移除) |
| 多次讀取 | 可重複訪問 | 單次流 (需手動存儲) | 可重複訪問 |
<?php
$input = fopen('php://input', 'r');
$output = fopen('/uploads/large_file.bin', 'w');
while (!feof($input)) {
$chunk = fread($input, 8192);
if ($chunk === '') break;
fwrite($output, $chunk);
}
fclose($input);
fclose($output);
// 內存佔用恆定 ~8KB,不受文件大小影響
<?php
// 非標準 multipart 或需流式解析時
$raw = file_get_contents('php://input');
// 使用 pecl_http 的 HttpMessage 或手動按 boundary 分割解析
// 一般建議直接用 $_FILES/$_POST
<?php
$raw = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? ''; // GitHub
$secret = 'webhook_secret';
$expected = 'sha256=' . hash_hmac('sha256', $raw, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
$payload = json_decode($raw, true);
// 處理事件...
$xml = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xml);
// XPath 查詢處理...
$raw = file_get_contents(...) 存儲變量複用$_FILESproxy_request_buffering off;php -S 完整支持 php://input$request->getContent() / $request->json()$request->getContent()$request->getBody() (PSR-7 StreamInterface)掌握 php://input 是構建現代 PHP API、Webhook、文件服務的基石。