在Yii1.1的数据验证是由CValidator完成,在CValidator中提供了各种基本的验证规则

<?php
public static $builtInValidators=array(
'required'=>'CRequiredValidator',
'filter'=>'CFilterValidator',
'match'=>'CRegularExpressionValidator',
'email'=>'CEmailValidator',
'url'=>'CUrlValidator',
'unique'=>'CUniqueValidator',
'compare'=>'CCompareValidator',
'length'=>'CStringValidator',
'in'=>'CRangeValidator',
'numerical'=>'CNumberValidator',
'captcha'=>'CCaptchaValidator',
'type'=>'CTypeValidator',
'file'=>'CFileValidator',
'default'=>'CDefaultValueValidator',
'exist'=>'CExistValidator',
'boolean'=>'CBooleanValidator',
'safe'=>'CSafeValidator',
'unsafe'=>'CUnsafeValidator',
'date'=>'CDateValidator',
);
?>

在Model文件中只需要定义rules方法便可以使用验证规则

  public function rules()
{
return array(
array('bianhao, status', 'required','message'=>'{attribute}为必填项目'), //bianhao,status是必须的;message:提供错误信息提示
array('lie, hang, status', 'numerical', 'integerOnly'=>true), //lie,hang,statusbi必须是数字而且必须是整形
array('bianhao', 'length', 'max'=>10), //bianhao的长度最多是10位
);
}

在验证数据有效性的时候,框架提供给我们的验证规则可能满足不了需求,这时候需要自定义验证规则,在ThinkPhp中我们需要新建一个验证规则文件,这显得就比较麻烦了,那Yii是如何解决这个问题的呢?Yii提供了一个CInlineValidator类来处理这个问题

<?php
if(method_exists($object,$name)) //$object当前验证的模型类
{
$validator=new CInlineValidator;
$validator->attributes=$attributes;
$validator->method=$name;
if(isset($params['clientValidate']))
{
$validator->clientValidate=$params['clientValidate'];
unset($params['clientValidate']);
}
$validator->params=$params;
if(isset($params['skipOnError']))
$validator->skipOnError=$params['skipOnError'];
}
?>

只要在当前的验证模型中存在该验证方法那么就绑定到CInlineValidator类中而在CInlineValidator中我们可以看到

<?php
protected function validateAttribute($object,$attribute)
{
$method=$this->method;
$object->$method($attribute,$this->params);
}
?>

可以看出,在Yii1.1中自定义验证只需要在当前Model中创建就可以了

<?php
public function rules()
{
return array(
array('lie,hang',"checkNumber","message"=>"{attribute}的值必须小于10"), //自定义checkNumber方法
);
} /**
* checkNumber方法
* 验证值是否小于10
*/
public function checkNumber($attribute,$params=array()){
if($this->$attribute>10){
$tihuan['{attribute}']=$this->getAttributeLabel($attribute);
$this->addError($attribute,strtr($params["message"],$tihuan));
}
}
?>

注意:在验证函数中不能直接return必须将错误信息addError

在验证数据有效性的时候我们必须还需要考虑场景的问题,不同的场景需要提供不同的验证规则,这点在ThinkPHP5中已经讨论过,Tp5的解决方案是比较繁琐而且不灵活的,那在Yii1.1中是怎么解决的呢?

Yii1.1的CVaildate提供了"on"属性和"except"属性,而在CActiveRecord中初始化中我们可以看到

    public function __construct($scenario='insert')
{
if($scenario===null) // internally used by populateRecord() and model()
return; $this->setScenario($scenario); //我们先看这个这是表示为模型设置一个应用场景
$this->setIsNewRecord(true);
$this->_attributes=$this->getMetaData()->attributeDefaults; $this->init(); $this->attachBehaviors($this->behaviors());
$this->afterConstruct();
}

在CActiveRecord初始化时我们就需要为该模型设置一个应用场景,默认应用场景为"insert"。再来看CModel中是如何获取当前需要验证的Vaildator集合的

     public function getValidators($attribute=null)
{
if($this->_validators===null)
$this->_validators=$this->createValidators();
$validators=array();
$scenario=$this->getScenario();
foreach($this->_validators as $validator)
{
if($validator->applyTo($scenario))
{
if($attribute===null || in_array($attribute,$validator->attributes,true))
$validators[]=$validator;
}
}
return $validators;
}

代码3-4行:获取当前所有验证规则

代码6行:获取当前模型验证规则

代码7-14行:在这个foreach循环里筛选符合当前场景的集合,我们看下$validator->applyTo($scenario) 在CValidator中

     public function applyTo($scenario)
{
if(isset($this->except[$scenario]))
return false;
return empty($this->on) || isset($this->on[$scenario]);
}

代码3-4行:当前场景是否在$this->except中如果在则除掉该验证规则

代码5行:当前验证规则如果没有on属性则保留该验证规则,如果有on属性并且当前场景在$this->on中则保留该规则如果不在则去除

到这,能发现在CValidator中"on"表示该验证规则属于哪个场景(scenario),如果没有"on"属性则该验证规则属于任何场景,如果有"on"属性的话则该验证规则只能属于该on属性下的验证规则;而"except"则恰恰相反,设置了"except"属性就表示该验证规则一定不属于"except"下的场景

看下简单的例子

   public function rules()
{
return array(
array('lie,hang',"checkNumber","message"=>"{attribute}的值必须小于10","on"=>"update,insert"),
array('bianhao, status', 'required',"message"=>'{attribute}为必填项目',"except"=>"insert"),
array('lie, hang, status', 'numerical', 'integerOnly'=>true),
array('bianhao', 'length', 'max'=>10),
);
}

代码4行:该验证规则只能属于update,insert下两个应用场景

代码5行:该验证规则不属于insert应用场景

代码6-7行:该验证规则属于任何应用场景

想要使用不同场景该怎么办?很简单只需要初始化的时候指定场景就好了 $model=new Model($scenario),如果想改变场景怎么办?直接调用$model->setScenario(scenario)就可以了。

总结:对比下与Tp5的验证规则,Yii1.1的显得更加简洁轻便,对不同场景的调用也更加灵活,自定义验证方法也只需要在Model本身添加自定义函数即可。

ps:Yii1.1还提供了前端JS的数据验证方法,但是我表示不太喜欢在PHP中写前端的JS代码,分开一点不是更好么

Yii1.1的验证规则的更多相关文章

  1. YII 表单验证规则

    官方文档:http://www.yiichina.com/guide/form.model 类参考手册:http://www.yiichina.com/api/CValidatorhttp://www ...

  2. ThinkPhp5.0模型验证规则

    Tp5提供了模型数据规则的验证功能,用于在数据save或者update前验证数据的有效性.Tp5提供校验规则的类为\Think\Validate,默认提供的校验规则可以查看该文件. 在Model文件中 ...

  3. EF里如何定制实体的验证规则和实现IObjectWithState接口进行验证以及多个实体的同时验证

    之前的Code First系列文章已经演示了如何使用Fluent API和Data Annotation的方式配置实体的属性,比如配置Destination类的Name属性长度不大于50等.本文介绍E ...

  4. TP5验证规则

    系统内置的验证规则如下: 格式验证类 require 验证某个字段必须,例如:'name'=>'require' number 或者 integer 验证某个字段的值是否为数字(采用filter ...

  5. [Asp.net MVC]Asp.net MVC5系列——在模型中添加验证规则

    目录 概述 在模型中添加验证规则 自定义验证规则 伙伴类的使用 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列——第一个项目 [Asp.net MVC]Asp.net MVC5 ...

  6. Thinkphp 1.验证规则 2.静态定义 3.动态验证

    一.验证规则 数据验证可以对表单中的字段进行非法的验证操作.一般提供了两种验证方式: 静态定 义($_validate 属性)和动态验证(validate()方法). //验证规则 array( ar ...

  7. oracle ebs应用产品安全性-交叉验证规则

    转自: http://blog.itpub.net/298600/viewspace-625138/ 定义: Oracle键弹性域可以根据自定义键弹性域时所定义的规则,执行段值组合的自动交叉验证.使用 ...

  8. Struts2 验证框架 validation.xml 常用的验证规则

    validation.xml 的命名规则和放置路径: 文件名:<ActionClassName>-validation.xml <ActionClassName>就是要验证的A ...

  9. 爱上MVC3~为下拉列表框添加一个自定义验证规则

    回到目录 开发它的原因: 之前的同事,也是我的哥们,问我下拉列表框是否可以支持验证,这个问题看似简单,但确实MVC里有为我们提供,所以,只能自己写个扩展了,即自己写一个attribute特性,让它继承 ...

随机推荐

  1. Xamarin+Prism开发详解六:DependencyService与IPlatformInitializer的关系

    祝各位2017年事业辉煌!开年第一篇博客,继续探索Xamarin.Forms… 为什么我做Xamarin开发的时候中意于Prism.Forms框架?本章为你揭晓. 实例代码地址:https://git ...

  2. .NET跨平台之旅:将示例站点升级至 ASP.NET Core 1.1

    微软今天在 Connect(); // 2016 上发布了 .NET Core 1.1 ,ASP.NET Core 1.1 以及 Entity Framework Core 1.1.紧跟这次发布,我们 ...

  3. “四核”驱动的“三维”导航 -- 淘宝新UI(需求分析篇)

    前言 孔子说:"软件是对客观世界的抽象". 首先声明,这里的"三维导航"和地图没一毛钱关系,"四核驱动"和硬件也没关系,而是为了复杂的应用而 ...

  4. JavaScript 开发规范

    本篇主要介绍JS的命名规范.注释规范以及框架开发的一些问题. 目录 1. 命名规范:介绍变量.函数.常量.构造函数.类的成员等等的命名规范 2. 注释规范:介绍单行注释.多行注释以及函数注释 3. 框 ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(73)-微信公众平台开发-消息管理

    系列目录 前言 回顾上一节,我们熟悉的了解了消息的请求和响应,这一节我们来建立数据库的表,表的设计蛮复杂 你也可以按自己所分析的情形结构来建表 必须非常熟悉表的结果才能运用这张表,这表表的情形涵盖比较 ...

  6. 13、零配置Struts2开发

    Convention 插件 从 Struts 2.1 开始, Struts 可以使用 Convention 插件来支持零配置: Convention 插件完全抛弃配置信息, 不仅不需要使用 strut ...

  7. MAVEN学习-第一个Maven项目的构建

    MAVEN安装成功之后就可以进行项目的构建和管理了: 为什么要用maven进行项目的构建和管理? 对于初学者来说一个最直接的也是最容易里的优点在于JAR包的管理,相对于以前开发一个项目的时候我们需要用 ...

  8. C++随笔:.NET CoreCLR之corleCLR核心探索之coreconsole(1)

    一看这个标题,是不去取名有点绕呢?或者是,还有些问题?报告LZ...你的标题取得有问题,是个病句!↖(^ω^)↗!!!先不要急,其实我今天带给大家的就是CoreCLR中的coreclr.其中它是在名字 ...

  9. Android中AlarmManager使用示例(持续更新,已经更改)

    现在普遍的手机都会有一个闹钟的功能,如果使用Android来实现一个闹钟可以使用AtarmManager来实现.AtarmManager提供了一种系统级的提示服务,允许你安排在将来的某个时间执行一个服 ...

  10. MongoDB学习笔记五—查询上

    数据准备 { , "goods_name" : "KD876", "createTime" : ISODate("2016-12- ...