yii2中用match验证器做正则校验需三步:一在rules()中配置pattern及message;二正则必须用/u修饰符支持中文;三用not=>true实现反向校验,动态正则需用内联验证器。

Yii2中用match验证器做正则校验
在Yii2模型中对字段内容做格式限制,比如手机号、身份证号、用户名规则、密码强度等,必须通过正则表达式精准控制输入合法性,避免后端被非法数据穿透。
第一步:在模型的rules()方法中添加match规则,语法为['字段名', 'match', 'pattern' => '你的正则', 'message' => '提示语']。
第二步:注意正则字符串需用分隔符包裹,Yii2内部使用preg_match(),推荐统一用/.../u格式(【u修饰符必须加,否则中文字符匹配会失败】)。
第三步:若要校验“非某格式”,使用'not' => true参数,例如禁止输入特殊符号:['content', 'match', 'pattern' => '/^[a-zA-Z0-9_\x{4e00}-\x{9fa5}]+$/u', 'not' => true, 'message' => '不能包含特殊字符']。
常见正则写法与坑点避让
密码至少8位、含大小写字母和数字:['password', 'match', 'pattern' => '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/u']。这个正则用到了前瞻断言,PHP 7.3+ 支持良好,但低版本可能报错——【若部署环境PHP 。
中文姓名(2–4个汉字):['realname', 'match', 'pattern' => '/^[\x{4e00}-\x{9fa5}]{2,4}$/u']。别漏掉u,否则\x{4e00}会被当普通字符串处理,永远不匹配。
邮箱基础校验(非RFC全规范,够用):['email', 'match', 'pattern' => '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/u']。注意这不是替代'email'内置验证器,而是补充;如果已用'email'规则,此处match可删减为仅校验域名后缀长度等细粒度逻辑。
用内联验证器动态拼接正则
当正则需要根据模型其他字段动态生成时(例如:手机号前缀决定号段范围),不能硬编码pattern,得用内联验证器。
方法一:匿名函数写法
['mobile', function ($model, $attribute, $params) { $prefix = substr($model->$attribute, 0, 3); $patterns = ['135' => '/^135\d{8}$/', '186' => '/^186\d{8}$/', '177' => '/^177\d{8}$/']; if (isset($patterns[$prefix]) && !preg_match($patterns[$prefix], $model->$attribute)) { $model->addError($attribute, '该号段格式不合法'); }}]
方法二:提取为模型方法再引用
在模型类里定义public function validateMobileByPrefix($attribute, $params),然后rules中写['mobile', [$this, 'validateMobileByPrefix']] 。这样便于单元测试和复用,也避免匿名函数闭包过大影响性能。











