Webman默认不自动解析PUT/DELETE请求体,因PHP仅对application/x-www-form-urlencoded和multipart/form-data自动填充$_POST;application/json需手动读取php://input并json_decode校验。

Webman 默认不自动解析 PUT 和 DELETE 请求体,这是最常卡住新手的地方——你以为数据在 $_POST 里,其实它根本没被 PHP 自动填充。
Webman 中 PUT 请求体为空的真正原因
PHP 只对 application/x-www-form-urlencoded 和 multipart/form-data 类型的请求自动解析进 $_POST;而 RESTful API 普遍用 application/json 发送 PUT,此时 $_POST 始终为空数组。
-
file_get_contents('php://input')是唯一可靠读取原始请求体的方式 - 必须手动
json_decode(..., true),且要检查返回是否为null(JSON 格式错误或空体) - 不要依赖
$_REQUEST或框架“自动注入”,Webman的中间件链默认不处理这个
示例判断逻辑:
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
}如何从 URL 路径提取资源 ID(如 /api/users/123)
Webman 的路由支持参数捕获,但你得在定义路由时显式声明,不能靠 $_GET 或字符串截取。
立即学习“PHP免费学习笔记(深入)”;
- 路由写法必须是
GET /api/users/{id}、PUT /api/users/{id},而非/api/users/* - 控制器方法签名需匹配:例如
public function update($request, $id) - 若用闭包路由,参数会以索引数组形式传入,顺序与花括号占位符一致
别手写 parse_url($_SERVER['REQUEST_URI']) 提 ID —— 容易漏掉前缀、编码问题、多层嵌套路径,也绕过了路由匹配逻辑。
DELETE 请求不该带请求体,但客户端可能乱发
HTTP 规范明确建议 DELETE 不应携带 body;但现实中有些前端库(比如旧版 Axios)会把 data 强塞进去,导致 file_get_contents('php://input') 非空。
- 严格场景下应拒绝带 body 的
DELETE:检查file_get_contents('php://input')是否非空,若是,返回400 Bad Request - 更务实的做法是忽略 body,只认 URL 中的 ID —— 因为语义上删除动作只由资源标识决定
- 切勿把
DELETE当成“软删 POST”,避免混用逻辑
响应状态码必须是 204 No Content(不是 200 OK),且响应体为空字符串:echo '';
中间件里统一处理请求体的隐患
有人试图在全局中间件中对所有 PUT/DELETE 预解析 JSON 并挂到 $request->getParsedBody() 上。这看似方便,但有风险:
- 多次调用
file_get_contents('php://input')会失败(流只能读一次) - 若后续中间件或控制器又读了一次,就会得到空内容
-
Webman的Request对象本身不缓存原始体,也不自动做 JSON 解析
正确做法是:只在真正需要的控制器方法里按需解析,或封装一个工具函数,内部用静态变量缓存解析结果。
真正容易被忽略的是:你永远不能假设客户端发送的 Content-Type 是对的。哪怕路由进了 PUT 分支,也要校验 Content-Type: application/json 头是否存在且匹配,否则 json_decode 可能静默失败或解析出错。



















