ThinkPHP场景验证需手动指定scene()方法,否则不生效;场景名大小写敏感;only为白名单、append为黑名单补丁;编辑推荐append+remove组合;require不自动trim,空格和空数组易漏检;调试用getRule()查看实际规则。
场景验证不是自动生效的,必须手动指定
ThinkPHP 的
不会自己识别当前是新增还是编辑——它完全依赖你传进去的场景名。不调用
方法,哪怕验证器里写了
或
,也只会走默认规则。
常见错误:定义了
,但控制器里只写
,结果字段校验完全没按预期执行。
必须显式调用
或
才会启用对应字段集
场景名大小写敏感,
和
是两个不同场景
如果场景不存在(比如拼错),ThinkPHP 默认回退到全部字段验证,容易误判为“必填没生效”
定义场景时别混淆
和
是白名单:只校验列出的字段,其他全跳过;
是黑名单补丁:在默认规则基础上额外加几个字段。两者逻辑相反,混用容易漏校验。
典型误用:想让「编辑时邮箱非必填、昵称必填」,却在
里写
,结果连
都不校验,导致更新失败。
立即学习
“
PHP免费学习笔记(深入)
”;
新增场景常用
:聚焦核心字段,避免冗余校验
编辑场景推荐
+
组合:先继承默认规则,再删掉不需要的(如
),加上必须改的(如
)
对字段名敏感,
不会移除
字段
控制器里传参前得清理空字段,否则
判定可能失效
ThinkPHP 的
规则只判断值是否为空字符串/NULL/未设置,但不会自动 trim 或过滤空格。用户提交带空格的昵称
,
会通过,后续业务出问题。
更隐蔽的是数组字段:比如
是数组,但前端传了
,验证器默认不展开校验子项,
看起来通过了,实际是空数组。
简单字段建议搭配
和
等过滤规则一起用
数组字段要用
类型声明 +
(需自定义)或在验证后手动检查
不要依赖验证器自动处理数据格式,清理和转换尽量放在
传入前
调试时直接 dump 场景字段列表比看文档更快
验证器行为不透明时,最有效的方式是打印当前生效的字段规则:
,它返回的是最终合并后的规则数组,能一眼看出哪些字段被 include、哪些被 remove。
容易忽略的点:同一个验证器实例不能复用多个场景。比如先
再
,后者会覆盖前者,但
只反映最后一次设置的结果。
每次换场景都要新建验证器实例,或调用
清空再设新场景
返回的键名是字段名,值是规则数组,注意观察
是否在目标字段的规则里
线上环境别留
,临时调试用
记录
结果更稳妥
验证场景的核心不在写得多,而在每次调用前确认三件事:场景名拼对了没、字段规则确实是你要的、传进来的数据已经干净到能被规则准确识别。漏掉任意一个,验证就变成玄学。
validateScenescene()onlyappendscene('edit')$validate->check($data)scene('edit')scene('create')'Edit''edit'onlyappendonlyappendscene('edit')only(['nickname'])idonlyappendremoveremove('password')append(['nickname'])removeremove('user_name')usernamerequirerequire" "requiretags{"tags": [""]}requiretrimalphaNumarrayrequireArray!empty($data['tags'])datadump($validate->getRule())scene('create')scene('edit')getRule()scene('') getRule()requiredumpLog::debug()getRule()