Yii表单验证仅在Model调用validate()或save()时触发,覆盖required、string、integer、email、in、exist等内置规则,但需正确配置rules()、调用时机及AJAX响应格式。

Yii 表单验证到底覆盖哪些场景?
Yii 的表单验证不是“全不全”的问题,而是“你有没有用对地方、配对规则、写对上下文”。它本身不校验前端输入的任意字符串,也不自动拦截非法 HTTP 请求体;它的验证能力严格绑定在 Model 实例生命周期中,且只在调用 validate() 或 save() 时触发。
哪些校验规则是开箱即用且高频实用的?
Yii 内置的验证器(Validator 子类)覆盖了绝大多数业务基础需求,但要注意命名和行为差异:
-
required:字段非空(注意:0、"0"、false在默认 strict 模式下会被认为“空”,需配合strict或skipOnEmpty调整) -
string:长度范围(min/max)、正则匹配(pattern),但不等价于 PHP 的is_string() -
integer/number:会尝试类型转换,"123"可过,"12.3"过不了integer,但可过number -
email:基于简单正则,不查 MX 记录,也不发验证邮件 -
in:值必须在给定数组中(range参数),注意类型松散比较("1" == 1默认成立) -
exist:检查数据库是否存在某值(如用户名已注册),需指定targetClass和targetAttribute -
safe:仅标记字段可批量赋值,**不校验**——常被误当成“跳过校验”,其实只是绕过massive assignment保护
为什么有些“明显该校验”的情况没生效?
常见失效原因不是 Yii 验证器能力不足,而是模型使用方式出错:
- 没调用
$model->validate()就直接取$model->getErrors()→ 返回空数组 - 字段未在
rules()中声明,却期望它被校验 → Yii 默认忽略未声明字段 - 使用
load()时传入错误的$formName(如表单没设name属性,却用'User'去 load)→ 数据根本没进模型 - 自定义验证方法(如
public function validatePassword())没在rules()里注册['password', 'validatePassword']→ 方法不会被调用 - AJAX 提交时后端没返回 JSON 错误结构(
['error' => [...]]),前端 JS 无法解析 → 看似“没校验”,其实是响应格式不对
复杂校验必须手写?怎么写才不踩坑?
真要校验身份证号、手机号归属地、密码强度组合、文件 MIME 类型,就得写自定义验证器。关键点就两个:
- 继承
Validator或用匿名函数,但必须在rules()中显式声明,例如:['idCard', 'match', 'pattern' => '/^[1-9]\d{17}[\dXx]$/', 'message' => '身份证格式不正确'] - 若需 DB 查询或外部 API,务必用
clientValidate+validate配合:前端做轻量提示(如格式),后端做最终确认(防绕过),避免把耗时逻辑放 clientValidate 里 - 注意验证时机:在
beforeValidate()中预处理数据(如 trim、转小写)比在每个 rule 里重复写更干净
最常被忽略的是:验证规则的执行顺序影响结果。比如 required 应放在 email 前面,否则空字符串会先被 email 拒绝,而 required 根本没机会报错。










