request()->except()用于排除指定键并返回新数组,不修改原请求;支持字符串、数组、通配符(如'user.*');需在验证前调用以剔除敏感字段,且对JSON请求生效前提是已自动解析。

thinkphp6 的 request()->except() 怎么用
直接调用 except() 就能排除指定参数,它返回一个不含指定键的新数组,原请求数据不受影响。注意这不是“过滤后继续用原 request 对象”,而是拿结果做后续处理。
常见错误是以为调用后 request()->param() 会自动变,其实不会——except() 是纯函数式操作,只返回副本。
-
request()->except('token')排除单个参数 -
request()->except(['token', 'sign'])排除多个参数(支持字符串数组) -
request()->except('user.*')支持通配符,排除所有以user.开头的键(如user.name、user.email) - 传空数组或不存在的键,会原样返回全部参数,不会报错
想在验证前剔除敏感字段,该在哪调用 except()
不能在 validate() 里直接改 $this->request,验证器默认读的是原始 param()。稳妥做法是先取干净数据,再喂给验证器:
$data = $this->request->except(['token', 'timestamp']); $result = $this->validate($data, 'rule.name');
如果你用的是场景验证(比如 scene('edit')),也要确保 except() 在 validate() 调用之前完成,否则剔除无效。
立即学习“PHP免费学习笔记(深入)”;
- 别在验证规则里写
token => 'require|alphaNum'然后指望except()后验证不报错——验证器仍会查原始数据 - 如果控制器方法接收了
Request $request注入,直接对它调用except()即可,无需额外input()或param() -
except()对get()、post()、param()都适用,但必须明确调用来源,例如$request->post()->except(...)才只剔除 POST 数据
except() 和 only() 的行为差异与陷阱
only() 是白名单,except() 是黑名单,表面互为反向,但实际行为不对称:当指定键不存在时,only() 返回空数组,except() 返回全量数据。
这容易导致误判——比如你写 $data = $request->except('page'),但前端根本没传 page,结果 $data 还是全部参数,可能意外带入不该存库的字段。
- 若目标是“只留安全字段”,优先用
only(['id', 'title', 'content']),更可控 -
except()适合临时剔除干扰项(如签名、时间戳、调试参数),不适合做数据准入控制 - 两者都不处理嵌套数组的深层排除,例如
except('user.profile')对['user' => ['profile' => [...]]]无效,只能靠手动递归或改用filter_var_array等方式
TP6.1+ 中 except() 对 JSON 请求体是否生效
生效,但要注意前提:JSON 请求必须已由框架自动解析(即 Content-Type 是 application/json,且未禁用 json_input 配置)。此时 request()->param() 已合并 JSON body,except() 对其操作完全正常。
容易踩的坑是前端发 JSON 但没设 header,或后端配置了 'json_input' => false,这时 param() 拿不到 JSON 字段,except() 自然也剔不掉。
- 调试时可用
var_dump($request->param())确认 JSON 是否已解析成功 - 若需区分来源(比如只剔除 query 中的
debug,保留 body 里的同名字段),得分别调用$request->except(...)->get()和$request->except(...)->post() - TP6.2 起支持
except()的第三个参数$type(如'get'、'post'),但需显式指定,不传则默认作用于param()合并结果
except() 不递归,也不支持正则,遇到 items[0][price] 这类命名,得自己写循环过滤。



















