param() 会按 get→post 顺序合并并覆盖同名参数,如 ?id=1 且 post id=2 时返回 2;它不解析 put/delete 请求体或 application/json,需用 input('json') 或 rawinput();get() 和 post() 严格对应 http 方法,互不干扰,适合需明确来源或安全审计的场景。

param() 会自动合并 GET 和 POST,但有覆盖规则
param() 看起来最省事,但它不是“智能合并”,而是按固定顺序取值:先取 GET 参数,再取 POST 参数,同名时后者覆盖前者。比如 URL 带 ?id=1,同时 POST 提交 id=2,$request->param('id') 返回的是 2。
这个行为在调试时容易误判——你以为参数来自 URL,其实被表单提交悄悄替换了。尤其在前后端联调中,如果前端用 AJAX 同时带 query string 和 body,param() 就会掩盖真实来源。
- 适合场景:快速原型、无需区分来源的简单接口
- 不适用场景:需要审计参数来源(如日志记录)、做幂等校验、或依赖 URL 参数做路由判断
- 注意:
param()不读取PUT/DELETE请求体,也不解析application/json,除非你手动配置input类型
get() 和 post() 严格对应 HTTP 方法,不互通
get() 只从 $_GET 超全局数组取值,post() 只从 $_POST 取值。它们互不干扰,也不会 fallback —— 这和原生 PHP 一致,不是 ThinkPHP 的 bug,而是设计选择。
常见错误是:表单 method="get" 却写 $request->post('name'),结果返回空或触发 Notice;或者用 curl 发 POST 请求但忘了加 -H "Content-Type: application/x-www-form-urlencoded",导致 $_POST 为空,post() 拿不到任何东西。
- 必须匹配:HTML 表单
method="get"→ 用get();method="post"→ 用post() - API 调用时注意:
application/json请求不会自动填充$_POST,所以post()返回空,得改用input('json')或rawInput() - 安全提示:不要因为
get()看似“只读”就忽略过滤,URL 参数一样可能被恶意构造
为什么 param() 有时拿不到 PUT/DELETE 参数
ThinkPHP5.1 默认只对 POST 方法解析请求体为 $_POST,而 PUT、DELETE 等方法的原始 body 不会自动解析进 $_POST,因此 param() 和 post() 都无法获取。
典型现象:用 axios 发 DELETE /user/123?id=456,param('id') 拿到的是 URL 中的 456,但如果你本意是传 JSON body {"id": 456},它根本不会被解析。
- 解决办法:手动读取原始输入
$request->input('json', [], 'json'),或用$request->rawInput()获取原始字符串再 json_decode - 前提:确保前端发送时设置了正确的
Content-Type: application/json - 注意:Nginx/Apache 可能拦截非标准方法,需确认服务器允许
PUT/DELETE
实际开发中该选哪个
没有“最好”,只有“最合适”。关键看你要解决什么问题:
- 管理后台的搜索表单(method="get")→ 用
get(),方便用户复制链接、刷新重试 - 登录/提交订单(method="post")→ 用
post(),避免敏感数据暴露在 URL - 快速验证接口逻辑(比如 Postman 测试)→
param()省事,但上线前务必切回明确方法 - RESTful API(JSON 通信)→ 别碰
param()和post(),直接用input('json')或body()
最容易被忽略的是:param() 对空值、0、false 的处理和原生 $_REQUEST 一样,不会帮你做类型转换或默认值兜底,所有业务校验仍需自己写。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











