要确认thinkphp6.1请求参数是否真正经过过滤逻辑,需逐层验证:第一步检查中间件是否修改request参数缓存;第二步对比$raw_get、$raw_post与input()返回值差异;第三步验证filter参数在input()、param()中是否生效,并清除无效的default_filter配置;第四步单独处理json请求体,手动解析并mergeparam。

要确认ThinkPHP6.1中请求参数是否真正经过了你配置的过滤逻辑,不能只看中间件是否注册或配置是否写上,必须通过原始数据流路径逐层验证——因为TP6.1的input()、param()等方法默认绕过中间件清洗结果,且filter参数仅在显式调用时生效。
第一步:确认中间件是否实际修改了Request对象的参数缓存
在全局中间件handle()方法末尾添加临时调试代码:file_put_contents('/tmp/request_param_debug.log', print_r($request->param(), true), FILE_APPEND);。
发起一次POST请求(如curl -X POST -d "name=<script>alert(1)</script>&email=test@example.com" http://localhost/test),检查日志里name字段内容是否已被HTMLPurifier清洗掉script标签——若仍为原始脚本,则说明mergeParam()未成功覆盖,【很可能用了旧版TP6.0或未升级到6.1+,mergeParam()在6.0中不存在】。
注意:不要用dd()或dump(),它们会中断请求生命周期,导致后续控制器无法执行,掩盖真实问题。
第二步:在控制器中对比不同获取方式的返回值
在任意控制器方法内插入以下三行:
$raw_get = $this->request->get();
$raw_post = $this->request->post();
$filtered = input('name'); // 或 param('name')
分别打印这三个变量。如果$raw_post['name']含XSS脚本而$filtered不含,说明中间件清洗有效;如果三者一致含脚本,说明中间件未生效或未正确调用mergeParam()。
这一步操作起来很简单,直接把三行代码粘贴进控制器方法第一行就能看到差异。
第三步:验证filter参数是否被input()函数真正执行
方法一:显式传入过滤器
$name = input('name', '', 'htmlspecialchars'); → 此时$name应为<script>alert(1)</script>,而非原始标签。
方法二:批量过滤param()
$safe_params = $this->request->param([], '', 'htmlspecialchars'); → 检查$safe_params['name']是否已转义。
方法三:验证default_filter配置是否被误用
打开config/app.php,确认'default_filter' => ''为空字符串——该配置**只影响模板输出**,对input()完全无效,若此处写了'htmlspecialchars',是典型误解,需立即清空。
第四步:检查JSON请求体是否被遗漏
前端发送Content-Type: application/json时,TP6.1不会自动解析$_POST,必须手动处理:
① 先读取原始输入流:$json = file_get_contents('php://input');
② 解析为数组:$data = json_decode($json, true) ?: [];
③ 手动清洗并合并:$this->request->mergeParam(HTMLPurifier::instance()->purify($data));
若跳过这三步,直接调用input('name')将始终返回null,【JSON请求不走$_POST自动解析路径,中间件里只调$request->post()会漏掉全部数据】。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











