thinkphp 6 的 request 对象不支持直接用 input('put.name') 获取 put 参数,因默认仅解析 post/get 表单数据;put 请求需手动读取 body 并根据 content-type 用 json_decode() 或 parse_str() 解析。

ThinkPHP 6 的 Request 对象不直接支持 input('put.name')
很多人习惯用 input() 获取 POST 参数,但 PUT 请求体默认不会被自动解析成数组供 input() 调用。直接写 $request->input('put.name') 或 $request->put('name') 会返回 null 或空字符串——这不是 bug,是设计使然:ThinkPHP 默认只对 POST 和 GET 做了表单编码解析,PUT、PATCH 等请求方法的原始 body 需手动处理。
用 $request->getBody() + json_decode() 解析 JSON 格式的 PUT 数据
绝大多数 RESTful 接口用 PUT 提交的是 JSON,此时必须读取原始请求体并解码:
// 控制器方法内 $body = $request->getBody()->getContents(); $data = json_decode($body, true); $name = $data['name'] ?? null;
注意几点:
-
$request->getBody()返回的是Psr\Http\Message\StreamInterface,必须调用getContents()才能拿到字符串 - 如果前端发的是
Content-Type: application/json,这是最稳妥的方式 - 若
$body为空,检查前端是否真的发送了请求体(比如 axios 中漏了data选项) - 别忘了加
?? null或isset()判断,避免Notice: Undefined index
如果是表单格式(application/x-www-form-urlencoded)的 PUT 请求
部分旧系统或测试工具(如 Postman)可能用表单方式发 PUT,ThinkPHP 不会自动解析它。你需要手动解析:
$body = $request->getBody()->getContents(); parse_str($body, $data); $name = $data['name'] ?? null;
关键点:
- 必须确认请求头
Content-Type是application/x-www-form-urlencoded,否则parse_str()会失败 - 不能依赖
$request->post(),它只响应POST方法,对PUT无效 - ThinkPHP 6.1+ 提供了
$request->param(),但它默认也只合并GET+POST,不包含 PUT body,所以依然要手动读取
想统一用 input()?得自己注册 PUT 解析中间件
如果你项目里大量使用 PUT 且希望保持 input('name') 写法,可以写一个中间件,在请求进入前把 PUT body 注入到 Request 实例中:
public function handle($request, \Closure $next)
{
if (in_array(strtoupper($request->method()), ['PUT', 'PATCH']) &&
strpos($request->header('content-type'), 'application/json') !== false) {
$body = $request->getBody()->getContents();
$data = json_decode($body, true) ?: [];
$request->merge($data); // 合并到 input 数据池
}
return $next($request);
}
这个方案要注意:
- 只建议在明确所有 PUT 都是 JSON 的项目里用,混用格式会导致覆盖冲突
-
$request->merge()会影响后续所有input()调用,包括input('get.name')等,慎用 - 中间件顺序很重要,必须在路由解析之后、控制器执行之前运行
真正麻烦的地方往往不在怎么取值,而在于前端没设对 Content-Type,或者发了个空 body 还以为服务端该有数据——先抓包看一眼请求体和 header,比翻文档快得多。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











