PHP 原生提供 $_GET、$_POST 超全域變數,但沒有 $_PUT。處理 RESTful API 的 PUT 請求時,需自行解析原始輸入流。
<?php
$_PUT = [];
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
parse_str(file_get_contents('php://input'), $_PUT);
}
// 使用:$_PUT['id'], $_PUT['title']
php://input 讀取原始請求主體parse_str() 解析查詢字串格式當 Content-Type: multipart/form-data(檔案上傳)時:
$_FILES、$_POSTphp://input 為空,無法讀取原始資料$_PUTApache mod_headers 強制改寫 Content-Type:
<Location "/demo.php">
RequestHeader set Content-Type foobar
</Location>
將 Content-Type 改為非 multipart/form-data,php://input 即會有資料,但 $_FILES 會消失。生產環境不可用。
| 場景 | 建議做法 |
|---|---|
| 純資料更新(JSON/表單) | Client 發送 Content-Type: application/json 或 application/x-www-form-urlencoded,Server 端 php://input + json_decode()/parse_str() |
| 檔案上傳 | 使用 POST + _method=PUT 偽裝,或改用 POST 語義上傳,PUT 僅用於資源更新 |
| 需原始 multipart 解析 | 使用 PEAR HTTP_Request2_MultipartBody 或手寫解析器(複雜,不推薦) |
# 表單格式
curl -X PUT https://domain.com/api/item -d "id=1" -d "title=test"
# JSON 格式
curl -X PUT https://domain.com/api/item \
-H "Content-Type: application/json" \
-d '{"id":1,"title":"test"}'
Request::input() 自動處理 PUT/PATCH/DELETERequest::createFromGlobals() 內建支援Request::put() 方法若維護舊專案需自行實作,建議封裝為 Middleware/Filter 統一處理,並明確文檔說明不支援 multipart PUT。