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’]
最后要注意,验证规则申明的先后顺序对验证结果也是有影响的!
yii2之数据验证的更多相关文章
- 我这么玩Web Api(二):数据验证,全局数据验证与单元测试
目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试 一.模型状态 - ModelState 我理解 ...
- MVC 数据验证
MVC 数据验证 前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解.System.ComponentModel.DataAnnotations 一.基础特性 一.Required 必填 ...
- kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件
小菜利用工作之余编写了一款Java小插件,主要是用来验证Web请求的数据,是在服务器端进行验证,不是简单的浏览器端验证. 小菜编写的仅仅是一款非常初级的组件而已,但小菜为它写了详细的说明文档. 简单介 ...
- MVC3 数据验证用法之密码验证设计思路
描述:MVC数据验证使用小结 内容:display,Required,stringLength,Remote,compare,RegularExpression 本人最近在公司用mvc做了一个修改密码 ...
- jQuery MiniUI开发系列之:数据验证
在开发应用系统界面时,往往需要进行很多.复杂的数据验证,当填写的数据符合规定,才能提交保存. jQuery MiniUI提供了比较完美的表单数据验证和错误显示的方式. 常见的表单控件,都有一个验证事件 ...
- AngularJS快速入门指南14:数据验证
thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table ...
- atitit.数据验证--db数据库数据验证约束
atitit.数据验证--db数据库数据验证约束 1. 为了加强账户数据金额的安全性,需要增加验证字段..1 2. 创建帐户1 3. 更改账户2 4. ---code3 5. --fini4 1. 为 ...
- MVC数据验证原理及自定义ModelValidatorProvider实现无编译修改验证规则和错误信息
Asp.net MVC中的提供非常简单易用的数据验证解决方案. 通过System.ComponentModel.DataAnnotations提供的很多的验证规则(Required, StringLe ...
- MVC 数据验证[转]
前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解. 一.基础特性 一.Required 必填选项,当提交的表单缺少该值就引发验证错误. 二.StringLength 指定允许的长度 指 ...
随机推荐
- Mysql免安装版配置【图文版和文字版】
图文版 配置环境变量 新建一个my.ini文件,添加下面内容 [mysqld] basedir=C:\\software\Mysql\mysql-5.7.14-winx64 datadir=C:\\s ...
- Hibernate第八篇【懒加载】
前言 前面在使用Hibernate的时候就提及过了懒加载,但没有好好地说明具体的说明究竟是怎么回事-本博文主要讲解懒加载 什么是拦截器以及为什么要使用懒加载? 懒加载就是当使用数据的时候才去获取数据. ...
- python装饰器练习题
练习题1. 请使用python, 对下面的函数进行处理, def hello(name): print "hello, %s" % name 在函数被调用时打印耗时详情 <f ...
- [python学习笔记] 开篇
今天开始学习markdown,立贴为证. 平均一天一小时.两个月先学完基础. 所有的帖子只为了学习记录,有不对的请提出,轻吐槽
- 如何用Python脚本从文件读取数据?
最近自学Python的进度比较慢,工作之余断断续续的看着效率比较低,看来还是要狠下心来每天进步一点点. 还记得前段时间陈大猫提了一口"先实现用python读取本地文件",碰巧今天看 ...
- Hive 存储类型 StoreType
file_format: : SEQUENCEFILE | TEXTFILE -- (Default, depending on hive.default.fileformat configurati ...
- hdu1512 Monkey King(左偏树 + 并查集)
Once in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its o ...
- JQ判断浏览器以及版本
JQuery 使用jQuery.browser 来判断浏览器,返回值可以为: safari(safari) opera(Opera) msie(IE) mozilla(Firefox). if($.b ...
- JavaWeb(三)JSP概述
一.JSP概述 1.1.JSP简介 一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%>结束.JSP是一种Java servlet,主要用于实现 ...
- Jmeter脚本录制方法(一)——分别使用Badboy录制和Jmeter自带的代理服务器录制
Jmeter录制方式分三种,分别是:使用Badboy录制.Jmeter自带的代理服务器录制和手工录制,今天先介绍前两种录制方法. Badboy录制 Badboy是用C++开发的动态应用测试工具, 其拥 ...