param()默认合并GET与POST参数且POST优先覆盖,不包含$_FILES、$_COOKIE、$_SERVER;支持点号取嵌套数组;自动应用htmlspecialchars和trim过滤;无法直接获取PUT/PATCH的JSON数据。

param() 不等于 $_REQUEST,它默认只取 GET + POST
ThinkPHP 的 param() 方法返回的是经过框架统一过滤、合并后的请求参数,但**不包含 $_FILES、$_COOKIE、$_SERVER**。它默认行为是先取 $_GET,再用 $_POST 覆盖同名键(POST 优先),所以像 ?id=1&name=a 加上 POST body: id=2&status=ok,param('id') 返回 2,param('name') 返回 'a',param('status') 返回 'ok'。
常见误判是以为 param() 等价于原始请求全量数据,结果在调试接口时发现上传字段或 header 传的 token 总拿不到——因为它们根本不在 param() 范围内。
- 要取上传文件,必须用
file()或file('xxx') - 要取 Cookie,用
cookie('key')或cookie() - 要取 Header(如 Authorization),用
header('authorization') - 想强制只从某一种方式取值,可传第二个参数:例如
param('id', '', 'get')强制读 GET,param('id', '', 'post')强制读 POST
param() 的默认过滤机制会自动 trim + strip_tags
ThinkPHP 在调用 param() 时,底层默认应用了 htmlspecialchars 和 trim(取决于配置中的 default_filter,默认为 'htmlspecialchars,trim')。这意味着即使你 POST 一个带空格或 HTML 标签的字符串,拿到的已经是处理过的值。
比如前端传 content=%20%3Cscript%3Ealert(1)%3C/script%3E%20,param('content') 直接返回 <script>alert(1)</script>(注意已转义)且首尾空格被去掉。
立即学习“PHP免费学习笔记(深入)”;
- 若需原始未过滤值,改用
input('param.', '', '')—— 第三个参数传空字符串可绕过默认过滤 - 若只想关掉某一项(比如保留空格但过滤标签),需在
app.php中修改'default_filter' => 'htmlspecialchars' - 注意:关闭过滤后,所有
param()调用都会受影响,不是局部生效
param() 获取嵌套数组时容易忽略点号路径语法
当表单提交含层级结构(如 user[name]、user[profile][age]),ThinkPHP 会自动解析成多维数组,但 param() 取值时**不支持方括号语法**,必须用点号。
例如 HTML 中有:<input name="user[info][email]">,对应 POST 数据是 ['user'=>['info'=>['email'=>'a@b.com']],此时:
-
param('user.info.email')✅ 正确,返回'a@b.com' -
param('user[info][email]')❌ 错误,返回null或默认值 -
param('user')返回完整子数组['info'=>['email'=>'a@b.com']] - 深层嵌套超过 3 层(如
a.b.c.d)仍可用,无硬性限制
RESTful 场景下 param() 拿不到 PUT/PATCH 的 JSON body
ThinkPHP 默认只从 $_GET 和 $_POST 合并参数,而 PUT/PATCH 请求体如果是 JSON(Content-Type: application/json),PHP 不会自动解析到 $_POST,因此 param() 拿不到任何东西。
典型现象:前端用 fetch('/api/user/1', {method:'PUT', body:JSON.stringify({name:'test'})}),后端 param() 返回空数组。
- 解决方案一:改用
input('param.')并手动解析 raw input:json_decode(file_get_contents('php://input'), true) - 解决方案二:在中间件中提前将 JSON body 解析并 merge 到 Request 对象(推荐封装成公共中间件)
- 解决方案三:前端换用
application/x-www-form-urlencoded,让数据进$_POST(但破坏 REST 语义) - 注意:
input('put.')和input('patch.')是 ThinkPHP 提供的快捷方式,但前提是已启用对应方法的参数解析(需检查Request配置或中间件是否支持)
param() 当万能入口去接所有输入,却没意识到它的作用域和过滤策略都是有边界的。尤其在前后端分离、多端共用接口时,上传、JSON、Header 几类数据必须分渠道取,混用就会丢数据。



















