Request::only() 不能防参数污染,因它仅截取字段而不校验路径合法性、不递归过滤嵌套结构、不阻止非法字段静默存在,需配合 input() 提取、validate 场景校验及 allowField() 入库三重防护。

Request::only() 为什么不能直接防参数污染
它只做字段截取,不校验路径合法性。比如你传 user[name] 和 user[password],request()->only(['user.name']) 确实只取到 name,但前提是 user 是个数组——如果攻击者传 user 是字符串 "abc",再加个 user_password=123,only() 就完全没用,因为字段名压根对不上。
常见错误现象:request()->only(['id', 'status']) 返回空数组,但数据库里却写入了 delete_flag=1;这是因为前端传的是 id=1&status=0&delete_flag=1,而 only() 只从当前层级取键,不处理未声明字段的“静默存在”问题。
-
only()不递归过滤嵌套结构,['user.name']不等于['user']['name']的路径白名单 - 它不阻止非法字段进入后续流程,比如被日志、缓存或模型自动填充误用
- TP 5.1 不支持点号路径写法(如
user.name),必须用input(['user'])+ 手动递归提取
TP6 的 only(['a.b.c']) 要配合 validate 场景才真正闭环
TP6 支持点号路径,但仅靠 only() 仍不够:它提取后返回扁平数组,而验证器默认按原始结构校验。比如 request()->only(['user.name', 'status']) 返回 ['user.name' => 'x', 'status' => 1],但验证规则里写的是 'user.name' => 'require|alpha',这能过;可一旦你漏写 user.email 规则,攻击者只要在原始请求里塞个 user[email]=x@x,它就不会进 only() 结果,也不会被验证器扫到——除非你用 scene() 显式绑定字段集。
- 必须在验证器中定义
scene('submit')并调用$this->only(['user.name', 'status']),否则验证器不感知白名单边界 -
only()提取结果要原样传给validate($data, $rule, '', 'submit'),不能混用input('')全量数据 - TP6 的
Validate::make()默认不启用场景,得手动传['scene' => 'xxx']或显式调用scene('xxx')
容易被忽略的 key 大小写与空值陷阱
only() 匹配键名是严格区分大小写的,且对 null 值敏感。比如前端传 ID=1,你写 only(['id']) 就拿不到;又或者传 status=(空字符串),only() 会照常返回该键,但后续 number 规则可能放行它——这不是 bug,是设计如此。
- 别依赖
only()过滤空值,要用filter参数或验证规则(如require)二次约束 - 字段名来自 URL 或表单时,注意浏览器默认转小写(如
Content-Type→content-type),但 PHP 的$_GET键名保留原始大小写 - TP6 中
request()->only(['User.Name'])和request()->only(['user.name'])是两个不同键,不会自动 normalize
替代方案:比 only() 更稳的白名单入口是 input(['k1','k2'])
在控制器里优先用 input(['id', 'name', 'status']),而不是 request()->only()。前者从 $_GET/$_POST 混合源提取,且天然规避了路由变量注入(如 :id 绑定值不会混进来);后者基于 Request 对象,可能包含路由层注入的参数,导致白名单失效。
-
input(['id'])返回['id' => 123],类型自动转换(可加第三个参数强制如intval) - 它不递归,但胜在语义明确、来源可控,适合绝大多数接口参数清洗
- 若需嵌套字段,用
input('user/a')+input('user/b')分开取,比only(['user.a','user.b'])更易调试、更少歧义
真正起效的白名单从来不是单点函数,而是 input() 提取 → validate 校验 → allowField() 入库 三道关卡的协同。其中任意一环漏掉路径级控制(比如没关 param_merge、没在验证器里 only()、模型 save 时没设 allowField),整条链就断了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











