Yii2框架数据验证操作实例详解

2018-09-07 12:58

阅读:468

  本文实例讲述了Yii2框架数据验证操作。分享给大家供大家参考,具体如下:

  一、场景

  什么情况下需要使用场景呢?当一个模型需要在不同情境中使用时,若不同情境下需要的数据表字段和数据验证规则有所不同,则需要定义多个场景来区分不同使用情境。例如,用户注册的时候需要填写email,登录的时候则不需要,这时就需要定义两个不同场景加以区分。

  默认情况下模型的场景是由rules()方法申明的验证规则中使用到的场景决定的,也可以通过覆盖scenarios()方法来更具体地定义模型的所有场景,例如:

   public function scenarios() { return [ signup => [username, email, password, conpassword, verifyCode, reg_time, log_time], login => [username, password, verifyCode, rememberMe, log_time] ]; }

  其中键为场景名称,值为该场景下使用的模型属性(称为活动属性)。

  指定模型场景有以下两种方法:

  方法一:

   $model = new User(); $model->scenario = signup;

  方法二:

   $model = new User([scenario => signup]);

  可以通过指定验证规则中的on属性来申明一条验证规则适用的场景:

   [email, required, on => signup]

  场景主要用于模型属性块赋值和数据验证。调用模型类的load()方法进行块赋值的时候,只有当前场景对应使用的属性会被赋值,调用模型类的validate()方法进行数据验证的时候,只有当前场景属性相关的且适用于当前场景的验证规则会被执行。

  二、验证规则

  Yii模型类通过实现rules()方法申明使用的所有验证规则,示例:

   public function rules() { return [ [[username, password], required], [email, email, on => signup] ]; }

  一条规则可适用于一个或多个场景,一条规则可用来验证一个或多个属性,一个属性可对应一条或多条验证规则。如果没有指定on属性,验证规则会在所有场景下使用。

  所有的验证规则都可以通过设置message属性来自定义错误信息,而且在错误信息内容中可以通过{attribute}来引用当前属性标签名称(属性标签名称需要在模型的attributeLabels()方法设置),通过{value}来引用当前属性的输入值,例如:

  [username, unique, on => register, message => {attribute}{value}已被占用!, on => signup]//注册时用户名唯一

  yii验证的使用方式有以下三种:

  1. 客户端验证:

  Yii默认开启客户端验证,可以通过设置enableClientValidation参数为true开启,开启之后ActiveForm会读取模型中申明的验证规则生成相应的Javascript验证代码。enableClientValidation参数设置的方式有三种:

  (1)在视图文件ActiveForm中对整个form进行设置:

   <?php $form = ActiveForm::begin([ enableClientValidation =>true ]); ?>

  (2)在视图文件ActiveField中对单个field进行设置:
复制代码 代码如下:<?= $form->field($model, username, [enableClientValidation=>false])->label(用户名) ?>

  (3)在AR类的rules()函数中设置:
[username, yii\validators\StringValidator, min => 3, max => 30, enableClientValidation => true, on => register]

  优先级:(2)>(1)>(3)

  2. 服务器端验证:

  (1)validate()

  模型validate()方法会根据rules()方法中定义的验证规则对所有数据进行验证,验证通过返回true,否则将错误保存在yii\base\Model::errors属性中并返回false。

  (2)save()

  模型save()方法中默认调用validate()方法进行数据验证,验证通过则直接进行数据库操作,返回true,否则不进行数据库操作,返回false,将错误信息存储在yii\base\Model::errors属性中。若已显式调用过validate(),可以通过传参避免在save()方法中重复验证数据:save(false)。

  3. Ajax验证:

  Yii默认关闭ajax验证,可以通过配置enableAjaxValidation参数为true开启。

  客户端设置(两种方式):

  (1)在视图文件ActiveForm中对整个form进行设置:

   <?php $form = ActiveForm::begin([ enableAjaxValidation =>true ]); ?>

  (2)在视图文件ActiveField中对单个field进行设置:
复制代码 代码如下:<?= $form->field($model, username, [enableAjaxValidation=>false])->label(用户名) ?>

  优先级:(2)>(1)

  服务器端处理:

   if(Yii::$app->request->isAjax) { $res = \yii\bootstrap\ActiveForm::validate($model); Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; return $res; }

  注:有些验证规则无法使用客户端验证,如:unique、exist等。

  三、yii核心验证器

  Yii提供了一些核心验证器,可以直接使用,申明格式如下:

  [属性名, 验证器名称/类名, ...(一些额外参数设置)]

  了解并使用yii的核心验证器会让开发变得简单许多。下面简单对yii核心验证器进行分类介绍。

  1. 不进行数据验证的验证器

  (1)safe:而是把一个属性标记为安全属性。

  [desc, safe]

  (2)default:给值为空的属性设置默认值。

  [add_time, default, value => time()]

  (3)trim:去除输入值首尾两侧多余空格。

  [username, trim]

  (4)filter:滤镜,对数据进行格式化或一些其他处理后返回。

  [phone, filter, filter => function($value) {
....return $value;
}]

  filter: 用于定义滤镜的php回调函数,可以为全局函数名,匿名函数或其他。
skipOnArray:是否在输入为数组时跳过滤镜,默认为false。如果滤镜不能处理数组输入,应该设置为true。

  2. 数据类型验证器

  (1)boolean:布尔型。

  [del, boolean, trueValue => true, falseValue => false, strict => true]

  trueValue:代表真的值,默认为1。
falseValue:代表假的值,默认为0。
strict:是否要求输入数据必须严格匹配trueValue或falseValue。默认为false。

  (2)number:数字。

  [salary, number]

  (3)double:双精度浮点型,等效于number验证器。

  [salary,double, max => 99.99, min => 0]

  (4)integer:整数。

  [age, integer]

  注:number、double、integer验证器都可以设置min、max参数来限制数字的最大、最小值(含界点)。

  (5)string:字符串。

  [username, string, length => [3, 30]]

  length:指定输入字符串的长度限制。
min:字符串最小长度。
max:字符串最大长度。
encoding:字符串的编码方式,不设置则使用应用自身的charset属性值。默认为utf-8。

  3. 数据格式验证器

  (1)date:日期。

  [time, date, format => php:Y:m:d, timestampAttribute => startTime]

  format:时间格式,默认为“y-m-d”。
timestampAttribute:将时间转化为时间戳并赋值给某个属性。

  (2)email:验证是否符合邮箱地址格式。

  [emailAddr, email]

  (3)ip:验证是否为有效IP地址。

  [ip_address, ip]

  (4)url:网址。

  [website, url, defaultScheme => http]

  validSchemes:用于指定哪些URI方案会被视为有效,默认为[http, https]。
defaultScheme:若输入值没有对应的方案前缀,会使用的默认URI方案前缀。

  (5)match:输入值是否满足某个正则表达式。

  [username, match, pattern => /^[a-z]\w*$/i]

  pattern:正则表达式。
not:是否对验证结果取反。

  4. 数据值验证器

  (1)required:必填。

  [[username, password], required]

  requiredValue:所期望的值,若没设置则输入不能为空。
strict:检查输入值时是否检查类型。

  (2)captcha:验证码。

  [verifyCode, captcha, caseSensitive => true, captchaAction => site/captcha, skipOnEmpty => false]

  caseSensitive:是否大小写敏感,默认为false。
captchaAction:指向用于渲染验证码图片的captcha方法的路由,默认为site/captcha。
skipOnEmpty:输入为空时是否跳过验证,默认为false。

  (3)compare:比较。

  [password, compare, compareAttribute => conpassword, operator => ==]

  compareAttribute:与指定属性值比较的属性名称。
compareValue:与某个常量值比较。
operator:比较操作符。

  其中compareAttribute默认在验证属性后面加后缀“_repeat”作为另一个比较属性的名称,operator默认为“==”,即:[password, compare]规则表示验证password与password_repeat的值是否相等。

  (4)each:验证数组。

  [ids, each, rule => [integer]]

  (验证数组ids中的每个元素是否都是int类型数据)
rule:定义验证每一个数组元素的验证规则。
allowMessageFromRule:是否使用rule中指定的多个验证规则报错信息,默认为true,若设置为false,则使用“message”参数值作为错误信息。

  注:若输入值不是数组则会报错。

  (5)exist:存在性。

  [cid, exist, targetClass => app\models\Category, targetAttribute => id]

  (cid的值是否在AR类对应的id属性中存在,使用场景:当前AR模型关联的数据表的cid字段和Category模型关联的数据表的id字段相关联,所以使用该验证规则验证cid字段的值能否在关联的另一个数据表中找到对应记录)
targetClass:用于查找输入值的目标AR类。
targetAttribute:用于查找输入值的目标属性名称。
filter:检查属性值存在性需要进行数据库查询,该参数设置查询的过滤条件。可以设置为查询条件的字符串或数组,或者function($query)匿名函数。
allowArray:是否允许输入值为数组,默认为false。若设置为true,则数组的每个元素都必须在目标字段中存在。若把targetAttribute设置为多元素数组来验证被测值在多字段中的存在性时,该属性不能设置为true。

  (6)unique:唯一性。

  [email, unique, targetClass => app\models\User, message => {attribute}{value}已被注册!, on => signup]
除了没有allowArray属性,其他属性都和exist验证器一样。

  (7)in:范围。

  [sex, in, range => [0, 1, 2]]

  range:范围值列表。
strict:是否使用严格模式(类型与值都要相同)。
not:是否对验证的结果取反,默认为false。
allowArray:是否接受输入数组,默认为false。

  5. 文件验证器

  (1)file:文件。

  [pcImg, file, extensions => [png, jpg, gif], maxSize => 1024*1024]

  extensions:可接受上传的文件扩展名列表。
mimeTypes:可接受上传的MIME类型列表。
minSize:文件大小下限。
maxSize:文件大小上限。
maxFiles:上传文件个数上限,默认为1。设置为大于1时输入值必须为数组。
checkExtensionByMimeType:是否通过文件的MIME类型来判断文件扩展,默认为true。

  (2)image:图片。

  [mbImg, image extensions => png, ipg, minWidth => 100, minHeight => 100]

  该验证器继承自file验证器,并支持额外属性minWidth、maxWidth、minHeight、maxHeight来设置图片的最小、最大宽度和最小、最大高度。

  四、其他验证器

  1. 条件式验证:

   [state, required, when => function($model) {//只在country属性值为USA的时候state属性值才不能为空 return $model->country==USA; }]

  注:若需要支持客户端验证,则要配置whenClient属性。

  1. 自定义验证器:

  (1)行内验证器:一种以模型方法或匿名函数的形式定义的验证器。

  示例:

   [conpassword, function($attribute, $params) { if($this->$attribute != $this->newpassword) { $this->addError($attribute, 确认密码和新密码不一致!); } }]。

  (当然这里也可以使用yii核心验证器compare来实现)

  注:行内验证器不支持客户端验证。

  (2)独立验证器:

  独立验证器是继承自yii\validators\Validator或其子类的类,可以通过重写validateAttribute()方法来实现验证规则,若验证失败,可以调用yii\base\Model::addError()方法来保存错误信息到模型内。

  独立验证器示例:

   namespace app\components; use yii\validators\Validator; class ConpasswordValidator extends Validator { public function init() { parent::init(); $this->message = 确认密码和密码不一致!; } //服务器端验证 public function validateAttribute($model, $attribute) { if($model->conpassword !== $model->password) { $model->addError($attribute, $this->message); } } //客户端验证 public function clientValidateAttribute($model, $attribute, $view) { $conpassword = json_encode($model->conpassword); $message = json_encode($this->message, JSON_UNESCAPED_SLASHES JSON_UNESCAPED_UNICODE); return <<<JS if(value != $conpassword) { message.push($message); } JS; return false; } }

  模型中使用示例:

  [conpassword, app\components\ConpasswordValidator]

  最后要注意,验证规则申明的先后顺序对验证结果也是有影响的!

  更多关于Yii相关内容感兴趣的读者可查看本站专题:《Yii框架入门及常用技巧总结》、《php优秀开发框架总结》、《smarty模板入门基础教程》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

  希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。


评论


亲,登录后才可以留言!