前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Yii2验证器(Validator)用法分析

Yii2验证器(Validator)用法分析

作者头像
botkenni
发布2019-09-03 15:41:50
2.6K0
发布2019-09-03 15:41:50
举报
文章被收录于专栏:IT码农IT码农IT码农

先看一下验证器的使用。

public function rules()

{

return [

[['email', 'password'], 'required'],

['password', 'string', 'min'=>6],

];

}

如上所示,验证器主要使用在rules里面,对当前model里面的属性值进行验证以检查是否满足某种要求。

验证器使用格式:

书写格式为:[需要验证的属性,验证器名称,验证器参数]。

如果需要验证的属性为多个可用数组,如果为一个属性可用字符串也可用数组来表示。

每个属性都可以有多个验证器,如上面的password使用了 required和string两个验证器。

常用验证器:

Yii2已经内置了一些常用的验证器。所有的验证器都从基类yii\validators\Validator继承实现。我大概总结下有这么几类。

数字相关:

integer——整数 用来检测属性值是否为整数,以及最大、最小值检测等。(yii\validators\NumberValidator)

double——浮点 用来检测属性值是否为浮点数,即小数。(yii\validators\NumberValidator)

number——数字 这个和上面的double完全相同,只是用了2个名称。(yii\validators\NumberValidator)

格式相关:

date——日期 检验属性值是否为正确的日期格式。(yii\validators\DateValidator)

email——邮件 检测属性值是否是正确的电子邮件格式。(yii\validators\EmailValidator)

url——URL 用来判断属性值是否是正确的url地址。(yii\validators\UrlValidator)

对值进行函数处理:

filter——过滤器 这个是对属性值进行加工处理的。如对属性值加前缀、替换特定的字符串等等。(yii\validators\FilterValidator)

trim——裁边 这个是对属性值进行加工处理的。只是去掉字符串两侧的空格、或指定的字符串。(yii\validators\FilterValidator)

上传文件验证:

file——文件 这个主要是对上传的文件进行验证,如格式、大小等。(yii\validators\FileValidator)

image——图片 这个和上面的file验证器差不多,不过是专门用来验证图片的。(yii\validators\ImageValidator)

判断比较:

compare——比较 用来对两个属性值进行比较,如相等、大于、小于比较等。(yii\validators\CompareValidator)

in——包含(范围) 用来检测属性值是否包含在指定的数组中。(yii\validators\RangeValidator)

exist——存在 用来检测在数据表中是否已经存在此属性值。(yii\validators\ExistValidator)

unique——唯一性 这个和exist差不多,用来检测值是否是唯一。(yii\validators\UniqueValidator)

string——字符串 对属性值进行长度判断,如最大长度、最短长度等。(yii\validators\StringValidator)

boolean——布尔型 用来检查属性的值是否为布尔值。(yii\validators\BooleanValidator)

default——默认值 这个是用来给属性设置默认值的。如当属性值为null的时候,给它设置为 空的默认值。(yii\validators\DefaultValueValidator)

required——必填 这个用来检查属性值是否为空。(yii\validators\RequiredValidator)

captcha——验证码 这个主要是在界面使用验证码的时候对验证码进行验证的。(yii\captcha\CaptchaValidator)

match——正则表达式 这个就比较强大了,用来检测属性值是否匹配给出的正则。上面所列出的基本都可以用这个实现。(yii\validators\RegularExpressionValidator)

其它:

safe——安全 这个不进行验证,仅仅用来指定属性值是安全的。(yii\validators\SafeValidator)

--------------------------

ii2的Validator是非常好用的一类方法,它辅助Model层,完成对数据的校验。现在核心的验证器有这么几类:

BooleanValidator - 要求属性必须为Bool类型
CompareValidator - 完成两个属性的比较
DateValidator - 要求属性必须为日期类型
EachValidator - 要求数组的每个元素必须满足某个条件
EmailValidator - 要求属性必须为邮件格式
ExistValidator - 要求该属性必须存在于此模型或者别的模型个某个属性当中
StringValidator - 要求该属性必须为字符串
RangeValidator - 要求属性必须在某个范围之内取值
.....

使用起来,它们都有一样的面孔,那就是,在复写的model::rules方法里面增加一条规则:

['country', 'in', 'range' => ['china', 'usa'], 'message' => 'the country is wrong']

这条规则就可以保证country这个属性必须在china和usa之间二选一,否则就会报'the country is wrong'错误。是不是非常的简单? 这个家族的验证器在活动记录ActiveRecord的使用时非常有用,能保证你插入数据库的数据是正确无误的。 已有的校验类虽然很丰富,但是毕竟不能满足我们全部的对数据校验需求,我们希望能扩展已有的验证器。有没有这样一个方法,既能能以这样简单的方式使用,又能方便我们自己定义校验规则?这就是今天要跟大家分享的内容。 直接上代码:

class RegexValidator extends Validator
{
    /**
     * @var string|array 所要采用的验证方法,可以为string,也可以为如果个方法组成的array
     * 所有的方法必须属于RegexValidator
     */
    public $method = null;
    /**
     * @var array 验证的方法列表
     * 方法必须属于RegexValidator
     */
    private $_methodArray = [];

    /**
     * @inheritdoc
     */
    public function init()
    {
        parent::init();
        $this->_methodArray = (array)$this->method;
        if(empty($this->_methodArray)){
            throw new InvalidConfigException("Configuration error:no validating method are found!");
        }
        foreach($this->_methodArray  as $method){
            if(!$this->hasMethod($method)){
                throw new InvalidConfigException("Validating method:\"{$method}\" does not exits!");
            }
        }
    }

    /**
     * @inheritdoc
     */
    public function validateAttribute($model, $attribute)
    {
        $value = $model->$attribute;
        //将错误信息转化为数组,数组元素对应[_methodArray]的验证方法
        $this->message = (array)$this->message;
        foreach($this->_methodArray  as $k => $method){
            $ret = call_user_func([$this, $method], $value);
            if($ret === false){
                $error = isset($this->message[$k]) ? $this->message[$k] : Yii::t('yii', '{attribute} is invalid.');
                $this->addError($model, $attribute, $error);
            }
        }
    }

    /**
     * @inheritdoc
     */
    protected function validateValue($value)
    {
        $this->message = (array)$this->message;
        foreach($this->_methodArray as $k => $method){
            $ret = call_user_func([$this, $method], $value);
            if($ret === false){
                $error = isset($this->message[$k]) ? $this->message[$k] : Yii::t('yii', "\"{$value}\" is invalid specified by the validator:". static::className() ."::$method");
                return [$error, []];
            }
        }
        return null;
    }

    /**
     * @inheritdoc
     */
    public function clientValidateAttribute($model, $attribute, $view)
    {

    }   

   //...这里是你的逻辑…… 
   
    /**
     * 由26个大写英文字母组成的字符串
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function uperchars($data = null)
    {
        $_pattern = "/^[A-Z]+$/";
        return self::_regex($_pattern, $data);
    }

    /**
     * 由26个小写写英文字母组成的字符串
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function lowerchars($data = null)
    {
        $_pattern = "/^[a-z]+$/";
        return self::_regex($_pattern, $data);
    }

    /**
     * 由数字和26个英文字母组成的字符串
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function numschars($data = null)
    {
        $_pattern = "/^[A-Za-z0-9]+$/";
        return self::_regex($_pattern, $data);
    }

    /**
     * 手机号码
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function mobile($data = null)
    {
        $_pattern = "/^(0|86|17951)?(13[0-9]|15[012356789]|1[78][0-9]|14[57])[0-9]{8}$/";
        return self::_regex($_pattern, $data);
    }

    /**
     * Email
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function email($data = null)
    {
        $_res = filter_var($data, FILTER_VALIDATE_EMAIL);
        return empty($_res) ? false : true;
    }

    /**
     * 邮编
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function postcode($data = null)
    {
        $_pattern = "/^[1-9]\d{5}(?!\d)$/";
        return self::_regex($_pattern, $data);
    }

    /**
     * 中文
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function zh($data = null)
    {
        $_pattern = "/^[\x{4e00}-\x{9fa5}]+$/u";
        return self::_regex($_pattern, $data);
    }

    /**
     * URL地址
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function url($data = null)
    {
        $_res = filter_var($data, FILTER_VALIDATE_URL);
        return empty($_res) ? false : true;
    }

    /**
     * 身份证
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function identity($data = null)
    {
        $_pattern = "/^(^\d{15}$)|(^\d{17}([0-9]|X)$)$/";
        return self::_regex($_pattern, $data);
    }

    /**
     * IPv4
     * @param $data mixed 数字或者字符串
     * @return bool
     **/
    public static function ip($data = null)
    {
        $_res = filter_var($data, FILTER_VALIDATE_IP);
        return empty($_res) ? false : true;
    }

    /**
     * 匹配正则公共方法
     * @param $pattern string 匹配模式
     * @param $subject string 对象
     * @return bool
     */
    private static function _regex($pattern, $subject = null)
    {
        if ($subject === null)
        {
            return false;
        }
        if (preg_match($pattern, $subject))
        {
            return true;
        }
        return false;
    }

}

首先,必须继承yii\validators\Validator,并且复写validateAttributevalidateValue方法。validateAttribute是验证属性用的,调用$module->validate()时会对其隐式的调用;validateValue则可以不依赖Model独立使用。clientValidateAttribute则是在客户端实现数据校验的部分(这部分等待聪明的你去DIY)。init实现初始化的功能。 复写了基础的几个Validator方法,然后就是我们自己的校验数据的逻辑:

zh - 校验数据是否为中文
postcode - 校验数据是否为邮编
mobile - 校验数据是否为手机号码
……

接下来,当然是最精彩的部分——如何使用?有三种方式可以方便您调用:

1.用在数据模型model的rules方法里面:

['name', RegexValidator::className(), 'method' => 'lowerchars', 'message' => '名字必须全为小写字母']
[
    ['mobile', 'status'],
    RegexValidator::className(),
    'method' => ['mobile', 'zh'],
    'message' => ['手机格式不正确', '必须为中文']
]

这里需要在Model里引入RegexValidator类,并用RegexValidator::className()代替核心验证器'in','string','exsit'等; 规则里的'method'是你自己定义的(静态)方法,你的校验逻辑之所在。可以单个引用,也可以为数组,当为数组时对应的错误信息'message'也得为数组,而且错误信息与之对应。 当调用$model->validate(),如果不满足以上的条件这个方法就会返回false,而且在$model->getErrors()里面会返回具体的错误信息:

[
    'name' => [
        '名字必须全为小写字母',
    ],
    'mobile' => [
        '手机格式不正确',
    ],
    'zh' => [
        '必须为中文',
    ],  
]

返回的错误信息和核心验证器格式是完全一样的。

2.脱离model独立使用,必须要配置[method]参数:

$valid = new RegexValidator([
    'method' => ['zh', 'negative'],
    'message' => ['必须为中文', '必须为负数'],
)];
$valid->validate($value, $error);
if($error){
    echo $error;
}

同样的和核心验证器的使用方法相同;

3.直接调用RegexValidator里的各个静态方法进行验证

$value = 'Abc';
$ret = RegexValidator::mobile($value);
if(!$ret){
	echo ...;
}

这是最简单调用方法,此时无法使用错误提示。 这个类是可以扩展的,您可以将自己的逻辑在number以降继续添加。

G

M

T

Detect languageAfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBengaliBosnianBulgarianCatalanCebuanoChichewaChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEsperantoEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekGujaratiHaitian CreoleHausaHebrewHindiHmongHungarianIcelandicIgboIndonesianIrishItalianJapaneseJavaneseKannadaKazakhKhmerKoreanLaoLatinLatvianLithuanianMacedonianMalagasyMalayMalayalamMalteseMaoriMarathiMongolianMyanmar (Burmese)NepaliNorwegianPersianPolishPortuguesePunjabiRomanianRussianSerbianSesothoSinhalaSlovakSlovenianSomaliSpanishSundaneseSwahiliSwedishTajikTamilTeluguThaiTurkishUkrainianUrduUzbekVietnameseWelshYiddishYorubaZulu

AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBelarusianBengaliBosnianBulgarianCatalanCebuanoChichewaChinese (Simplified)Chinese (Traditional)CroatianCzechDanishDutchEnglishEsperantoEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekGujaratiHaitian CreoleHausaHebrewHindiHmongHungarianIcelandicIgboIndonesianIrishItalianJapaneseJavaneseKannadaKazakhKhmerKoreanLaoLatinLatvianLithuanianMacedonianMalagasyMalayMalayalamMalteseMaoriMarathiMongolianMyanmar (Burmese)NepaliNorwegianPersianPolishPortuguesePunjabiRomanianRussianSerbianSesothoSinhalaSlovakSlovenianSomaliSpanishSundaneseSwahiliSwedishTajikTamilTeluguThaiTurkishUkrainianUrduUzbekVietnameseWelshYiddishYorubaZulu

Text-to-speech function is limited to 200 characters

Options : History : Feedback : Donate

Close

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档