ThinkPHP 6 中应使用 $request->post() 获取纯 POST 数据,避免 param() 或 input() 混合 GET 导致参数被意外覆盖;post() 支持 JSON、x-www-form-urlencoded 和 form-data,自动解析 JSON,但不支持点号取嵌套字段,上传文件须用 file()。

ThinkPHP 6 的 Request 对象怎么取 POST 数据
直接用 $request->post(),不是 input() 或 param() —— 后两者会合并 GET 和 POST,容易在接口场景下被 GET 参数意外覆盖。
常见错误是写成 $request->param('name'),结果前端只传了 POST,但 URL 里恰好带了 ?name=test,值就被悄悄替换了。
-
$request->post()只读 POST(含 JSON、x-www-form-urlencoded、form-data)原始数据 -
$request->post('name')获取单个字段,未传时返回null -
$request->post('name/s')自动过滤空格(/s是过滤修饰符) - 如果 Content-Type 是
application/json,post()默认能自动解析,无需手动json_decode(file_get_contents('php://input'))
POST 数据为空?先看请求头和编码类型
空不是代码问题,大概率是客户端没发对。ThinkPHP 的 post() 不处理 multipart/form-data 以外的 raw body,但 JSON 和普通表单都支持。
检查三件事:
立即学习“PHP免费学习笔记(深入)”;
- 前端是否设置了正确的
Content-Type:JSON 要application/json,表单要application/x-www-form-urlencoded或multipart/form-data - 如果是 axios/fetch,确认没漏掉
headers: {'Content-Type': 'application/json'},否则默认发的是 form-data 且 body 是字符串而非对象 - 用
$request->header('content-type')打印实际接收的类型,比猜更可靠
post() 和 param() 混用时的坑
别在一个接口里交替用 post('id') 和 param('name') —— 它们来源不同,行为不一致,调试时容易误判。
-
param()是混合来源:POST > GET > route > default,适合 Web 表单页(允许 URL 覆盖) -
post()是纯 POST 来源,适合 API 接口(必须严格按 body 传) - 如果用了
validate()验证器,默认校验的是param(),想验证纯 POST 就得显式传$request->post() - 上传文件必须用
$request->file(),post()拿不到
获取 JSON POST 时注意键名大小写和嵌套
前端传 {"user_info": {"name": "Tom"}},PHP 里不能直接 $request->post('user_info.name') —— ThinkPHP 的点号语法只对一维有效。
- 正确写法:
$data = $request->post(); $name = $data['user_info']['name'] ?? null; - 或者用
input()(不是post()):$request->input('user_info.name'),它支持点号递归取值 - 但
input()也会混入 GET,所以更稳妥的是先$request->post()拿全量,再自己 array_key_exists 或 ?? 取值 - JSON 字段名带中划线(如
user-id)会被转成下划线(user_id),这是框架自动转换,不是 bug
-H "Content-Type: application/json",或者 axios 里 data 写成了字符串而非对象,导致 post() 返回空数组。先打日志看 $request->header('content-type') 和 $request->getContent(),比翻文档快得多。



















