自定义验证规则类必须继承ci_form_validation并置于application/libraries/my_form_validation.php,因form_validation->run()仅识别控制器或该类内部以callback_或_开头的public方法;独立库中定义的回调无法被扫描到,导致run()恒返回false。

自定义验证规则类必须继承 CI_Form_validation 并放在 application/libraries/MY_Form_validation.php,否则回调方法无法被识别,run() 永远返回 FALSE。
为什么不能在普通 Library 里写验证回调
CodeIgniter 的 form_validation->run() 只会扫描当前控制器或 MY_Form_validation 类内部的以 callback_ 或下划线开头(如 _my_rule)的方法。你在 My_validations 这类独立库中定义的 check_email(),即使手动加载了,form_validation 实例也完全看不到它。
- 错误现象:
$this->form_validation->set_rules('email', '邮箱', 'callback_check_email')后,run()直接失败,不报错也不进回调函数 - 根本原因:验证器对象和你的自定义库是两个不同实例,没有引用关系
- 兼容性影响:CI3 所有版本都如此,不是 bug,是设计机制
MY_Form_validation 中回调方法的命名与调用规则
在 MY_Form_validation 类里定义回调时,命名方式直接决定你规则字符串怎么写 —— 二者必须严格匹配,且不能加 callback_ 前缀。
- 方法名以
_开头(如_phone_format()),规则里就写'_phone_format' - 方法名以
callback_开头(如callback_email_unique()),规则里也写'callback_email_unique'(但 CI3 更推荐前者) - 方法必须是
public,且第一个参数接收字段值,后续参数可选(用于传表名、字段等) - 必须显式调用
$this->form_validation->set_message()设置错误提示,否则显示默认英文
示例:
public function _phone_format($value)
{
$this->form_validation->set_message('_phone_format', '{field} 必须为10–13位数字');
return !empty($value) && preg_match('/^\d{10,13}$/', $value);
}
动态规则集如何安全注入到 set_rules()
不要在控制器里拼接规则数组后反复调用 set_rules();应一次性传入完整二维数组,并确保每个子数组含 field、label、rules 三项。
- 常见错误:把
get_rules()返回的数组直接塞给set_rules($rules),但set_rules()接收的是「单条规则数组」或「多条规则组成的二维数组」,类型不匹配会导致静默失败 - 正确做法:确认
$rules是形如[ [ 'field'=>'email', 'label'=>'邮箱', 'rules'=>'required|_email_check' ], [...] ]的结构 - 性能注意:规则生成逻辑应尽量轻量,避免在
get_rules()中查数据库或做 IO
跨模块复用规则时最容易忽略的一点
所有回调方法里要用 $this->CI->db 而不是 $this->db —— 因为 MY_Form_validation 类本身没有自动绑定 CodeIgniter 超级对象,必须通过 get_instance() 显式获取。
漏掉这一步,$this->db->get_where() 会报 Fatal error: Call to a member function get_where() on null,而且错误堆栈不指向验证类,极难定位。











