ThinkPHP 8.0请求参数过滤需分三层设防:中间件校验键名白名单、验证器限定字段及内容规则、模型层strict()配合allowField()控制入库字段,缺一不可。

ThinkPHP 8.0 的请求参数过滤不能靠“全局开关”或自动转义,必须按字段、按场景、分层设防。核心是三道防线:**中间件统一拦截键名 → 验证器校验字段存在性与内容规则 → 模型层限定入库字段**,缺一不可。
用中间件校验参数键名合法性
所有接口入口前,先检查请求中出现的参数名是否在白名单内。推荐新建 ParamWhitelistMiddleware:
- 从 config/api.php 读取预设白名单,如
'allowed_params' => ['page', 'limit', 'keyword', 'sort', 'status'] - 调用
$request->param()获取全部参数,遍历键名,不在白名单中则抛出HttpException(400) - 注意大小写敏感,数据库字段通常是小写,需统一转换后比对
- 注册时放在中间件队列靠前位置(如优先级 5),确保早于控制器执行
验证器定义字段存在性与内容规则
验证器不是只做“格式检查”,更是第二层字段白名单:
- 在
$scene中显式列出该接口允许接收的字段,例如:protected $scene = ['search' => ['keyword', 'category_id', 'sort']];没写进来的字段,验证器直接忽略,也不参与后续处理 - 每个字段绑定安全过滤,如
'keyword' => 'require|htmlspecialchars|strip_tags',防止输出时XSS - 注意:验证通过 ≠ 允许入库,仍需配合模型层
allowField()控制写入范围
模型层用 allowField() + strict() 控制入库字段
这是最后一道数据落库防线,防止绕过验证器直接操作模型:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 调用
$model->strict(true)启用严格模式,否则allowField()对where()等查询无效 -
allowField(['username', 'email', 'mobile'])必须传入明确数组,不能拼接用户输入 - 白名单建议从配置或数据库 Schema 动态加载,避免硬编码遗漏:用
(new User())->getSchema()->getFields()获取真实字段列表再过滤 - 错误示范:
$user->where(['username' => $v, 'is_admin' => 1])—— 若未开启 strict 或未在 allowField 中声明is_admin,该条件会被静默丢弃或报错(取决于配置)
分页与搜索类参数要单独处理
像 page、limit、sort 这类通用参数,不建议混入业务验证器:
- 分页时用
input('only', ['keyword', 'status'])显式提取业务字段,避免把page也塞进验证逻辑 - 排序字段(如
sort=username_desc)需额外提取主字段名,并校验是否在合法字段列表中:$field = preg_replace('/_(asc|desc)$/i', '', $input),再查in_array($field, $allowedFields) - 模糊搜索关键词要手动转义
%和_:addcslashes($keyword, '%_'),防止 SQL 通配符注入
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










