\_validate 是 ThinkPHP 3.2 模型层的 protected 数组属性,须定义在继承 Model 的模型类中,控制器中声明无效;调用 create() 或 add() 时触发,规则为四至六元素索引数组,字段名须与表单 name 一致,验证失败时 create() 返回 false,需手动判断并用 getError() 获取提示。

ThinkPHP 3.2 的 _validate 不是控制器方法,别往里写
它根本不会被自动调用——这是最常踩的坑。ThinkPHP 3.2 中的 _validate 是模型(Model)层的属性,不是控制器(Controller)里的钩子函数。你把它写在控制器方法开头,框架完全无视。
正确位置只有一处:在继承自 Model 的模型类里,作为 protected $_validate 数组声明。
- 验证规则必须定义在模型类中,例如
UserModel.class.php - 控制器里调用
$User->create()或$User->add()时,才会触发该模型的_validate - 如果模型没定义
_validate,或控制器直接 new Model() 但没调用create(),验证压根不执行
验证数组写法要对,字段名和规则顺序不能错
_validate 是二维数组,每条规则是四个元素的索引数组:array(字段名, 验证规则, 错误提示, 验证条件, 附加规则, 验证时间)。漏掉第 4 位(验证条件)却写了第 5 位,就会导致规则静默失效。
常见错误现象:required 规则不报错、email 格式始终通过、空字符串绕过验证。
- 字段名必须和表单提交的
name值完全一致(区分大小写),比如表单是user_email,就不能写成email - 验证条件常用值:1 表示新增时验证,2 表示更新时验证,3 表示全部验证;不填默认为 1,容易漏掉编辑场景
- 附加规则如
regex要配正则字符串,in要配逗号分隔的字符串(不是数组),写成array('1','2')会直接报错
示例(正确):
protected $_validate = array(
array('username', 'require', '用户名不能为空', 1),
array('email', 'email', '邮箱格式不正确', 1),
array('status', array('0','1'), '状态值非法', 2, 'in')
);
验证失败后,create() 返回 false,别直接拿数据入库
很多人写完验证,发现 $data = $Model->create() 后没检查返回值,直接 $Model->add($data),结果验证失败时 $data 是 false,最终插入全 NULL 或报 SQL 错误。
更隐蔽的问题:create() 失败时,$Model->getError() 才有提示内容,但这个内容不会自动抛出异常,得手动取。
- 必须判断
$data !== false,否则后续操作无意义 -
getError()返回的是字符串,不是数组,且只保留最后一条错误(除非你用getErrors(),但 3.2 默认不支持多错误收集) - 若需返回多个字段错误,得自己遍历
_validate+ 手动校验,框架原生不支持批量错误聚合
验证规则中的 callback 和 function 容易引发作用域问题
用 callback 类型时,指定的方法名默认在当前模型类中查找;但如果写成 array('checkMobile', 'callback'),而 checkMobile 是私有方法或不在该模型里,就会报 Fatal error: Call to undefined method。
用 function 类型时,传入的是函数名字符串,不是闭包,PHP 5.3+ 也不支持直接传匿名函数进 _validate 数组。
-
callback方法必须是public,且参数固定为单个值(即当前字段值) - 若需访问其他字段或模型实例,只能通过
$this在回调方法内获取,但要注意此时$this->data可能尚未完整赋值 - 更稳妥的做法:把复杂逻辑提到控制器里做预处理,模型层只做基础格式验证
验证逻辑天然耦合在模型定义里,改一个字段规则可能影响所有使用该模型的操作。线上环境别临时注释 _validate 调试——它一旦失效,就是静默放行。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











