Yii表单验证仅在Model调用validate()或save()时触发,覆盖required、string、integer、email、in、exist等内置规则,但需正确配置rules()、调用时机及AJAX响应格式。
Yii 的表单验证不是“全不全”的问题,而是“你有没有用对地方、配对规则、写对上下文”。它本身不校验前端输入的任意字符串,也不自动拦截非法 HTTP 请求体;它的验证能力严格绑定在 Model 实例生命周期中,且只在调用 validate() 或 save() 时触发。
Yii 内置的验证器(Validator 子类)覆盖了绝大多数业务基础需求,但要注意命名和行为差异:
required:字段非空(注意:0、"0"、false 在默认 strict 模式下会被认为“空”,需配合 strict 或 skipOnEmpty 调整)string:长度范围(min/max)、正则匹配(pattern),但不等
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'] → 方法不会被调用['error' => [...]]),前端 JS 无法解析 → 看似“没校验”,其实是响应格式不对真要校验身份证号、手机号归属地、密码强度组合、文件 MIME 类型,就得写自定义验证器。关键点就两个:
Validator 或用匿名函数,但必须在 rules() 中显式声明,例如:['idCard', 'match', 'pattern' => '/^[1-9]\d{17}[\dXx]$/', 'message' => '身份证格式不正确']clientValidate + validate 配合:前端做轻量提示(如格式),后端做最终确认(防绕过),避免把耗时逻辑放 clientValidate 里beforeValidate() 中预处理数据(如 trim、转小写)比在每个 rule 里重复写更干净最常被忽略的是:验证规则的执行顺序影响结果。比如 required 应放在 email 前面,否则空字符串会先被 email 拒绝,而 required 根本没机会报错。
来电咨询