应在中间件中调用$request->merge()替换已解析参数以安全过滤,因$request->param()返回只读副本,filter()或手动处理后必须merge才能影响后续使用。

ThinkPHP中间件里怎么安全地过滤请求参数
直接在中间件里修改 $request->param() 是无效的,因为这个方法返回的是只读副本;真正要清理参数,得操作底层的原始数据源。
- GET 参数藏在
$_GET,POST/JSON 数据实际走的是$_POST或php://input,但 ThinkPHP 会提前解析并缓存到$request->getParams()和$request->postParams()内部属性中 - 最稳妥的方式是在中间件中调用
$request->filter()设置全局过滤规则,或对特定字段手动调用filter_var()/htmlspecialchars() - 别碰
Input::clear()—— 这个方法在 TP6+ 已废弃,且不作用于中间件生命周期内已解析的参数
为什么 request->only() + filter 组合容易漏掉脏数据
request->only() 只是白名单取值,它不自动触发任何过滤逻辑;哪怕你设了 default_filter 配置,也只对未显式指定过滤器的字段生效,且仅限于模板输出环节。
- 例如:配置了
'default_filter' => 'htmlspecialchars',但request->only(['name', 'email'])返回的仍是原始字符串 - 真正起效的是
request->param('name', '', 'htmlspecialchars')这种带第三个参数的写法 - 如果参数来自 JSON 请求体(
Content-Type: application/json),request->param()默认不会自动解码再过滤,需先json_decode($request->getContent(), true)再逐个过滤
TP6 自定义中间件中清理参数的实操写法
不要试图重写 Request 对象,而是用 $request->merge() 替换已解析参数,这是唯一能影响后续控制器中 request->param() 返回值的方式。
public function handle($request, \Closure $next)
{
$params = $request->param();
// 清理 name 字段:去首尾空格 + 转义 HTML
$params['name'] = trim(htmlspecialchars($params['name'] ?? ''));
// 移除危险字段(如 callback、_token 等非业务字段)
unset($params['callback'], $params['_token']);
// ⚠️ 关键:用 merge 强制刷新内部参数缓存
$request->merge($params);
return $next($request);
}
-
$request->merge()会覆盖内部的$this->param属性,后续所有request->param()调用都基于新值 - 注意:如果控制器用了依赖注入接收
Request,必须确保中间件执行顺序在路由解析之后(即注册在app/middleware.php的'http'数组里,而非'route') - 对数组型参数(如
tags[])要递归处理,array_map('trim', $params['tags'] ?? [])才安全
过滤时机错位导致 XSS 或 SQL 注入的真实坑点
很多人把过滤逻辑放在控制器里,看似“按需处理”,结果在验证器(Validate)、模型自动写入(save())、日志记录(Log::write())这些环节,原始未过滤参数早已被使用。
- 验证器默认不触发过滤,
rule中的'name|require|alphaNum'不等于自动转义 - 模型
save(['name' => $request->param('name')])直接入库,如果没提前过滤,HTML 标签就进数据库了 - 日志里记的是
$request->param()原始值,攻击载荷可能被完整落盘,形成二次利用入口 - 最佳实践:过滤必须发生在中间件 → 控制器 → 验证器 → 模型 这条链路的最上游,且只做“净化”,不做“转换”(比如把
<script></script>删掉,而不是替换成空格)
参数过滤不是加一层保险,是掐断污染源头。一旦某个环节绕过中间件(比如通过命令行调用控制器、或单元测试直连 Action),原始参数就裸奔了——所以清理动作最好和入口强绑定,而不是靠人肉检查每处 request->param() 调用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











