jQuery Validation Plugin

一、默认校验规则

(1)required:true                必输字段 (2)remote:"check.php"      使用ajax方法调用check.php验证输入值 (3)email:true                    必须输入正确格式的电子邮件 (4)url:true                        必须输入正确格式的网址 (5)date:true                      必须输入正确格式的日期 日期校验ie6出错,慎用 (6)dateISO:true                必须输入正确格式的日期(ISO),例如:2009-06-23,1998/01/22 只验证格式,不验证有效性 (7)number:true                 必须输入合法的数字(负数,小数) (8)digits:true                    必须输入整数 (9)creditcard:                   必须输入合法的信用卡号 (10)equalTo:"#field"          输入值必须和#field相同 (11)accept:                       输入拥有合法后缀名的字符串(上传文件的后缀) (12)maxlength:5               输入长度最多是5的字符串(汉字算一个字符) (13)minlength:10              输入长度最小是10的字符串(汉字算一个字符) (14)rangelength:[5,10]      输入长度必须介于 5 和 10 之间的字符串")(汉字算一个字符) (15)range:[5,10]               输入值必须介于 5 和 10 之间 (16)max:5                        输入值不能大于5 (17)min:10                       输入值不能小于10  

二、修改默认的提示

[objc][/objc] view plaincopy
  1. jQuery.extend(jQuery.validator.messages, {
  2.     required: "必选字段",
  3.     remote: "请修正该字段",
  4.     email: "请输入正确格式的电子邮件",
  5.     url: "请输入合法的网址",
  6.     date: "请输入合法的日期",
  7.     dateISO: "请输入合法的日期 (ISO).",
  8.     number: "请输入合法的数字",
  9.     digits: "只能输入整数",
  10.     creditcard: "请输入合法的信用卡号",
  11.     equalTo: "请再次输入相同的值",
  12.     accept: "请输入拥有合法后缀名的字符串",
  13.     maxlength: jQuery.validator.format("请输入一个 长度最多是 {0}的字符串"),
  14.     minlength: jQuery.validator.format("请输入一个 长度最少是 {0}的字符串"),
  15.     rangelength: jQuery.validator.format("请输入 一个长度介于 {0}和 {1}之间的字符串"),
  16.     range: jQuery.validator.format("请输入一个介于 {0}和 {1}之间的值"),
  17.     max: jQuery.validator.format("请输入一个最大为{0}的值"),
  18.     min: jQuery.validator.format("请输入一个最小为{0}的值")
  19. });
上述代码存至message_cn.js中并添加引用即可  

三、常用的方法

1.用其他方式替代默认的SUBMIT
[javascript][/javascript] view plaincopy
  1. $().ready(function(){
  2.     $("#signupForm").validate({
  3.         submitHandler: function(form){
  4.             alert("submitted");
  5.             form.submit();
  6.         }
  7.     });
  8. });
使用ajax方式
[javascript][/javascript] view plaincopy
  1. $(".selector").validate({
  2.     submitHandler: function(form){
  3.         $(form).ajaxSubmit();
  4.     }
  5. })
可以设置validate的默认值,写法如下:
[javascript][/javascript] view plaincopy
  1. $.validator.setDefaults({
  2.     submitHandler: function(form){
  3.         alert("submitted!");
  4.         form.submit();
  5.     }
  6. });
如果想提交表单, 需要使用form.submit()而不要使用$(form).submit()   2.debug,只验证不提交表单 如果这个参数为true,那么表单不会提交,只进行检查,调试时十分方便
[javascript][/javascript] view plaincopy
  1. $().ready(function(){
  2.     $("#signupForm").validate({
  3.         debug: true
  4.     });
  5. });
如果一个页面中有多个表单都想设置成为debug,用
[javascript][/javascript] view plaincopy
  1. $.validator.setDefaults({
  2.     debug: true
  3. })
  3.ignore:忽略某些元素不验证
[javascript][/javascript] view plaincopy
  1. ignore: ".ignore"
4.更改错误信息显示的位置 errorPlacement:Callback Default: 把错误信息放在验证的元素后面 指明错误放置的位置,默认情况是:error.appendTo(element.parent());即把错误信息放在验证的元素后面
[javascript][/javascript] view plaincopy
  1. errorPlacement: function(error, element){
  2.     error.appendTo(element.parent());
  3. }
errorClass:String  Default: "error" 指定错误提示的css类名,可以自定义错误提示的样式 errorElement:String  Default: "label" 用什么标签标记错误,默认的是label你可以改成em errorContainer:Selector 显示或者隐藏验证信息,可以自动实现有错误信息出现时把容器属性变为显示,无错误时隐藏,用处不大 errorContainer: "#messageBox1, #messageBox2" errorLabelContainer:Selector 把错误信息统一放在一个容器里面。 wrapper:String 用什么标签再把上边的errorELement包起来 一般这三个属性同时使用,实现在一个容器内显示所有错误提示的功能,并且没有信息时自动隐藏 errorContainer: "div.error", errorLabelContainer: $("#signupForm div.error"), wrapper: "li"

官方demo

  5.更改错误信息显示的样式 设置错误提示的样式,可以增加图标显示,在该系统中已经建立了一个validation.css专门用于维护校验文件的样式
[css][/css] view plaincopy
  1. input.error {
  2.     border: 1px solid red;
  3. }
  4. label.error {
  5.     background: url("./demo/images/unchecked.gif") no-repeat 0px 0px;
  6.     padding-left: 16px;
  7.     padding-bottom: 2px;
  8.     font-weight: bold;
  9.     color: #EA5200;
  10. }
  11. label.checked {
  12.     background: url("./demo/images/checked.gif") no-repeat 0px 0px;
  13. }
  6.每个字段验证通过执行函数success:String,Callback 要验证的元素通过验证后的动作,如果跟一个字符串,会当做一个css类,也可跟一个函数
[javascript][/javascript] view plaincopy
  1. success: function(label){
  2.     // set   as text for IE
  3.     label.html(" ").addClass("checked");
  4.     //label.addClass("valid").text("Ok!")
  5. }
添加"valid" 到验证元素, 在CSS中定义的样式<style>label.valid {}</style> success: "valid" 7.验证的触发方式修改 下面的虽然是boolean型的,但建议除非要改为false,否则别乱添加。 onsubmit:Boolean  Default: true 提交时验证. 设置唯false就用其他方法去验证 onfocusout:Boolean  Default: true 失去焦点是验证(不包括checkboxes/radio buttons) onkeyup:Boolean  Default: true 在keyup时验证. onclick:Boolean  Default: true 在checkboxes 和 radio 点击时验证 focusInvalid:Boolean  Default: true 提交表单后,未通过验证的表单(第一个或提交之前获得焦点的未通过验证的表单)会获得焦点 focusCleanup:Boolean  Default: false 如果是true那么当未通过验证的元素获得焦点时,移除错误提示。避免和 focusInvalid 一起用
[javascript][/javascript] view plaincopy
  1. // 清除表单的错误验证信息
  2. $().ready(function(){
  3.     var validator = $("#signupForm").validate({
  4.         submitHandler: function(form){
  5.             alert("submitted");
  6.             form.submit();
  7.         }
  8.     });
  9.     $("#reset").click(function(){
  10.         validator.resetForm();
  11.     });
  12. });
  8.异步验证 remote:URL 使用ajax方式进行验证,默认会提交当前验证的值到远程地址,如果需要提交其他的值,可以使用data选项
[javascript][/javascript] view plaincopy
  1. remote: "check-email.php"
  2. //服务器端会默认接受name和value
  3. remote: {
  4.     url: "check-email.php",     //后台处理程序
  5.     type: "post",               //数据发送方式
  6.     dataType: "json",           //接受数据格式
  7.     data: {                     //要传递的数据
  8.         username: function() {
  9.             return $("#username").val();//必须写成函数形式,否则取不到最新的值
  10.         }
  11.     }
  12. }
远程地址只能输出 "true" 或 "false",不能有其它输出   9.添加自定义校验 addMethod:name, method, message 自定义验证方法
[javascript][/javascript] view plaincopy
  1. // 中文字两个字节
  2. jQuery.validator.addMethod("byteRangeLength", function(value, element, param){
  3.     var length = value.length;
  4.     for (var i = 0; i < value.length; i++) {
  5.         if (value.charCodeAt(i) > 127) {
  6.             length++;
  7.         }
  8.     }
  9.     return this.optional(element) || (length >= param[0] && length <= param[1]);
  10. }, $.validator.format("请确保输入的值在{0}-{1}个字节之间(一个中文字算2个字节)"));
  11. // 邮政编码验证
  12. jQuery.validator.addMethod("isZipCode", function(value, element){
  13.     var tel = /^[0-9]{6}$/;
  14.     return this.optional(element) || (tel.test(value));
  15. }, "请正确填写您的邮政编码");
1.要在additional-methods.js文件中添加或者在jquery.validate.js添加建议一般写在additional-methods.js文件中 2.在messages_cn.js文件添加:isZipCode: "只能包括中文字、英文字母、数字和下划线", 调用前要添加对additional-methods.js文件的引用。   10.动态修改验证规则  
[javascript][/javascript] view plaincopy
  1. $("#myinput").rules("add", {
  2.     minlength: 2
  3. });
  4. $("#myinput").rules("add", {
  5.     required: true,
  6.     minlength: 2,
  7.     messages: {
  8.         required: "Required input",
  9.         minlength: jQuery.format("Please, at least {0} characters are necessary")
  10.     }
  11. });
  12. $("#myinput").rules("remove");
  13. $("#myinput").rules("remove", "min max");

四、API文档

名称

返回类型

描述

validate(options)

返回:Validator

验证所选的FORM

valid()

返回:Boolean

检查是否验证通过

rules()

返回:Options

返回元素的验证规则

rules("add",rules)

返回:Options

增加验证规则

rules("remove",rules)

返回:Options

删除验证规则

removeAttrs(attributes)

返回:Options

删除特殊属性并且返回他们

Custom selectors

:blank

返回:Validator

没有值的筛选器

:filled

返回:Array <Element >

有值的筛选器

:unchecked

返回:Array <Element >

没选择的元素的筛选器

Utilities

jQuery.format

(template,argument ,argumentN...)

返回:String

用参数代替模板中的 {n}

 

 

Validator:

validate方法返回一个Validator对象,它有很多方法,让你能使用引发校验程序或者改变form的内容. validator对象有很多方法,但下面只是列出常用的

form()

返回:Boolean

验证form返回成功还是失败

element(element)

返回:Boolean

验证单个元素是成功还是失败

resetForm()

返回:undefined

把前面验证的FORM恢复到验证前原来的状态

showErrors(errors)

返回:undefined

显示特定的错误信息

Validator functions:

setDefaults(defaults)

返回:undefined

改变默认的设置

addMethod(name,method,message)

返回:undefined

添加一个新的验证方法.必须包括一个独一无二的名字,一个JAVASCRIPT的方法和一个默认的信息

addClassRules(name,rules)

返回:undefined

增加组合验证类型 在一个类里面用多种验证方法里比较有用

addClassRules(rules)

返回:undefined

增加组合验证类型 在一个类里面用多种验证方法里比较有用,这个是一下子加多个

 

 

内置验证方式:

required()

返回:Boolean

必填验证元素

required(dependency-expression)

返回:Boolean

必填元素依赖于表达式的结果

required(dependency-callback)

返回:Boolean

必填元素依赖于回调函数的结果

remote(url)

返回:Boolean

请求远程校验。url通常是一个远程调用方法

minlength(length)

返回:Boolean

设置最小长度

maxlength(length)

返回:Boolean

设置最大长度

rangelength(range)

返回:Boolean

设置一个长度范围[min,max]

min(value)

返回:Boolean

设置最大值

max(value)

返回:Boolean

设置最小值

email()

返回:Boolean

验证电子邮箱格式

range(range)

返回:Boolean

设置值的范围

url()

返回:Boolean

验证URL格式

date()

返回:Boolean

验证日期格式(类似30/30/2008的格式,不验证日期准确性只验证格式)

dateISO()

返回:Boolean

验证ISO类型的日期格式

dateDE()

返回:Boolean

验证德式的日期格式(29.04.1994 or 1.1.2006)

number()

返回:Boolean

验证十进制数字(包括小数的)

digits()

返回:Boolean

验证整数

creditcard()

返回:Boolean

验证信用卡号

accept(extension)

返回:Boolean

验证相同后缀名的字符串

equalTo(other)

返回:Boolean

验证两个输入框的内容是否相同

phoneUS()

返回:Boolean

验证美式的电话号码

 

 

validate ()的可选项:

debug:进行调试模式(表单不提交):

$(".selector").validate

({

  debug:true

})

把调试设置为默认:

$.validator.setDefaults({

  debug:true

})

submitHandler:

通过验证后运行的函数,里面要加上表单提交的函数,否则表单不会提交

$(".selector").validate({

  submitHandler:function(form) {

$(form).ajaxSubmit();

  }

})

ignore:

对某些元素不进行验证

$("#myform").validate({

  ignore:".ignore"

})

rules:

自定义规则,key:value的形式,key是要验证的元素,value可以是字符串或对象

$(".selector").validate({

  rules:{

    name:"required",

    email:{

      required:true,

      email:true

    }

  }

})

messages:

自定义的提示信息key:value的形式key是要验证的元素,值是字符串或函数

$(".selector").validate({

  rules:{

    name:"required",

    email:{

      required:true,

      email:true

    }

  },

  messages:{

    name:"Name不能为空",

    email:{

      required:"E-mail不能为空",

      email:"E-mail地址不正确"

    }

  }

})

groups:

对一组元素的验证,用一个错误提示,用error Placement控制把出错信息放在哪里

$("#myform").validate({

 groups:{

   username:"fname lname"

 },

 errorPlacement:function(error,element) {

    if (element.attr("name") == "fname" || element.attr("name") == "lname")

      error.insertAfter("#lastname");

    else

      error.insertAfter(element);

  },

  debug:true

})

Onubmit Boolean默认:true

是否提交时验证

$(".selector").validate({

  onsubmit:false

})

onfocusout Boolean默认:true

是否在获取焦点时验证

$(".selector").validate({

  onfocusout:false

})

onkeyup Boolean默认:true

是否在敲击键盘时验证

$(".selector").validate({

  onkeyup:false

})

onclick Boolean默认:true

是否在鼠标点击时验证(一般验证checkbox,radiobox)

$(".selector").validate({

  onclick:false

})

focusInvalid Boolean默认:true

提交表单后,未通过验证的表单(第一个或提交之前获得焦点的未通过验证的表单)会获得焦点

$(".selector").validate({

  focusInvalid:false

})

focusCleanup Boolean默认:false

当未通过验证的元素获得焦点时,并移除错误提示(避免和 focusInvalid.一起使用)

$(".selector").validate({

  focusCleanup:true

})

errorClass String默认:"error"

指定错误提示的css类名,可以自定义错误提示的样式

$(".selector").validate({

  errorClass:"invalid"

})

errorElement String默认:"label"

使用什么标签标记错误

$(".selector").validate

  errorElement:"em"

})

wrapper String

使用什么标签再把上边的errorELement包起来

$(".selector").validate({

  wrapper:"li"

})

errorLabelContainer Selector

把错误信息统一放在一个容器里面

$("#myform").validate({

  errorLabelContainer:"#messageBox",

  wrapper:"li",

  submitHandler:function() { alert("Submitted!") }

})

showErrors:

跟一个函数,可以显示总共有多少个未通过验证的元素

$(".selector").validate({

  showErrors:function(errorMap,errorList) {

       $("#summary").html("Your form contains " + this.numberOfInvalids() + " errors,see details below.");

       this.defaultShowErrors();

  }

})

errorPlacement:

跟一个函数,可以自定义错误放到哪里

$("#myform").validate({

 rrorPlacement:function(error,element) { error.appendTo(element.parent("td").next("td"));

  },

  debug:true

})

success:

要验证的元素通过验证后的动作,如果跟一个字符串,会当做一个css类,也可跟一个函数

$("#myform").validate({

       success:"valid",

       submitHandler:function() { alert("Submitted!") }

})

highlight:

可以给未通过验证的元素加效果,闪烁等

 

 

addMethod(name,method,message)方法:

参数name是添加的方法的名字

参数method是一个函数,接收三个参数(value,element,param) value是元素的值,element是元素本身 param是参数,我们可以用addMethod来添加除built-in Validation methods之外的验证方法 比如有一个字段,只能输一个字母,范围是a-f,写法如下:

$.validator.addMethod("af",function(value,element,params){

  if(value.length>1){

   return false;

  }

  if(value>=params[0] && value<=params[1]){

   return true;

  }else{

   return false;

  }

},"必须是一个字母,且a-f");

用的时候,比如有个表单字段的id="username",则在rules中写

username:{

  af:["a","f"]

}

addMethod的第一个参数,就是添加的验证方法的名子,这时是af

addMethod的第三个参数,就是自定义的错误提示,这里的提示为:"必须是一个字母,且a-f"

addMethod的第二个参数,是一个函数,这个比较重要,决定了用这个验证方法时的写法

如果只有一个参数,直接写,如果af:"a",那么a就是这个唯一的参数,如果多个参数,用在[]里,用逗号分开

 

meta String方式:

$("#myform").validate({

  meta:"validate",

  submitHandler:function() { alert("Submitted!") }

})

<script type="text/javascript" src="js/jquery.metadata.js"></script>

<script type="text/javascript" src="js/jquery.validate.js"></script>

<form id="myform">

 <input type="text" name="email" />

 <input type="submit" value="Submit" />

</form>

Yii简单的基于角色的访问控制

public function filters()
{
 return array(
 'accessControl', // perform access control for CRUD operations
 );
}
     
public function accessRules()
{
 return array(
 array('allow',
 'action'=>array('admin'),
 'roles'=>array('staff', 'devel'),
 ),
 array('deny'// deny all users
 'users'=>array('*'),
 ),
 );
}

用户模型

在用户表中新增一列,列名 roles。建立相应的模型。在这里它将被命名为 “User”。 当添加用户可以给他们分配角色 “管理员”,“用户”,“员工”等等。

验证

在文件 protected/components/UserIdentity.php 添加如下内容: class UserIdentity extends CUserIdentity
{
    private $id;
     
    public function authenticate()
    {
        $record=User::model()->findByAttributes(array('email'=>$this->username));
        if($record===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if($record->password!==md5($this->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->id=$record->id;
            $this->setState('roles', $record->roles);           
            $this->errorCode=self::ERROR_NONE;
        }
        return !$this->errorCode;
    }
     
    public function getId(){
        return $this->id;
    }
}
重要的一行是 $this->setState('roles', $record->roles);他给会话增加了用户角色。你可以使用 Yii:app()->user->getState("roles") 或 Yii::app()->user->roles 获取用户角色。

检查权限:结构

在 protected/components 文件夹下修改并创建文件 WebUser.php ,然后重写 checkAccess() 方法。 <?php
class WebUser extends CWebUser
{
 /**
 * Overrides a Yii method that is used for roles in controllers (accessRules).
 *
 * @param string $operation Name of the operation required (here, a role).
 * @param mixed $params (opt) Parameters for this operation, usually the object to access.
 * @return bool Permission granted?
 */
 public function checkAccess($operation, $params=array())
 {
 if (empty($this->id)) {
 // Not identified => no rights
 return false;
 }
 $role = $this->getState("roles");
 if ($role === 'admin') {
 return true; // admin role has access to everything
 }
 // allow access if the operation request is the current user's role
 return ($operation === $role);
 }
}
在 checkAccess() 方法中你可以定义自己的逻辑。 确保类可以被yii使用配置文件 "protected/config/main.php" 必须包含以下内容: 'components' => array(
 // ...
 'user' => array(
 'class' => 'WebUser',
 ),
旁注: [CWebUser::checkAccess()] 通常连接yii的验证系统。这里我们使用一个简单的处理角色的系统来替换[CAuthManager] 定义的分级系统。详细教程参加 Role-Based Access Control

检查权限: 使用

  • 在你的 PHP 代码中使用 Yii::app()->user->checkAccess('admin') 来检查当前用户是否有 ‘admin’ 角色。当用户拥有 "staff" 或 "admin" 角色时,调用 Yii::app()->user->checkAccess("staff") 将会返回 true。
  • 在控制器中你可以使用 accessRules() 中的 "roles" 属性进行过滤。
见下面的例子。

怎样过滤动作

控制器必须包含以下代码: public function filters()
{
 return array(
 'accessControl', // perform access control for CRUD operations
 );
}
     
public function accessRules()
{
 return array(
 array('allow',
 'action'=>array('admin'),
 'roles'=>array('staff', 'devel'),
 ),
 array('deny'// deny all users
 'users'=>array('*'),
 ),
 );
}
这里对控制器中的 "admin" 动作进行了限制访问: 只有拥有 "staff" 或 “devel” 角色才可以访问。 想API文档中描述的那样 CAccessRule, “roles” 属性实际上调用的是 Yii::app()->user->checkAccess() 方法。

怎样根据角色显示不同菜单

你只需使用一个基于用户角色的菜单。例如 <?php
$user = Yii::app()->user; // just a convenience to shorten expressions
$this->widget('zii.widgets.CMenu',array(
 'items'=>array(
 array('label'=>'Users', 'url'=>array('/manageUser/admin'), 'visible'=>$user->checkAcces('staff')),
 array('label'=>'Your Ideas', 'url'=>array('/userarea/ideaList'), 'visible'=>$user->checkAcces('normal')),
 array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>$user->isGuest),
 array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!$user->isGuest)
 ),
));
?>

更进一步: 访问上下文

一个通常的需求,用户只能够修改自己的数据。在这种情况下,用户的角色是没有任何意义的:将要修改的数据。 这就是为什么 [CWebUser::checkAccess()] 有一个可选的参数 "$param" 。现在假设我们要检查的是一个用户是否有权更新Post记录的权限。我们可以这样写: if (Yii::app()->user->checkAccess('normal', $post)) {
.....
}
当然 WebUser::checkAccess() 必须被扩展来使用 "$params" 参数。这将取决于你的应用程序的逻辑。比如, 这可能是非常简单的 $post->userId == $this->id

Yii CModel.rules()方法 、validate预定义完整列表[转载]

public array rules () {return} array 要调用 validate() 时应用的有效性规则。 返回属性的有效性规则。 声明验证规则,应重写此方法。 每个规则是数组具有以下结构: array(‘attribute list’, ‘validator name’, ‘on’=>’scenario name’, …validation parameters…) 注: * attribute list: 指定属性 (以逗号分隔) 进行验证 ; * validator name: 指定要使用的验证程序。 它可以是方法的一个模型类的一个内置的验证器或验证程序类 (或其路径的别名) 名称的名称。 一种验证方法必须具有以下签名: // $params refers to validation parameters given in the rule function validatorName($attribute,$params) 内置的验证程序是指在 CValidator::builtInValidators 中声明的验证程序之一。 验证程序的类是扩展 CValidator 的类。 * on: 应执行有效性规则时,此选项指定的情形。 用逗号分开不同的方案。 如果未设置此选项,将在任何情况下应用规则。 请 方案 中有关此选项的更多详细信息,参阅。 * 附加参数用于初始化相应的验证程序属性。 请参阅 individal 验证器类 API 可能的属性。 以下是一些例子: array( array(‘username’, ‘required’), array(‘username’, ‘length’, ‘min’=>3, ‘max’=>12), array(‘password’, ‘compare’, ‘compareAttribute’=>’password2′, ‘on’=>’register’), array(‘password’, ‘authenticate’, ‘on’=>’login’), array(‘Price’,'numerical’, ‘integerOnly’=>true), ); 预定义完整列表: * boolean : CBooleanValidator 的别名, 确保属性的值是CBooleanValidator::trueValue 或 CBooleanValidator::falseValue . * captcha : CCaptchaValidator 的别名,确保了特性的值等于 CAPTCHA 显示出来的验证码. * compare : CCompareValidator 的别名, 确保了特性的值等于另一个特性或常量. * email : CEmailValidator 的别名,确保了特性的值是一个有效的电邮地址. * default : CDefaultValueValidator 的别名, 为特性指派了一个默认值. * exist : CExistValidator 的别名, 确保属性值存在于指定的数据表字段中. * file : CFileValidator 的别名, 确保了特性包含了一个上传文件的名称. * filter : CFilterValidator 的别名, 使用一个filter转换属性. * in : CRangeValidator 的别名, 确保了特性出现在一个预订的值列表里. * length : CStringValidator 的别名, 确保了特性的长度在指定的范围内. * match : CRegularExpressionValidator 的别名, 确保了特性匹配一个正则表达式. * numerical : CNumberValidator 的别名, 确保了特性是一个有效的数字. * required : CRequiredValidator 的别名, 确保了特性不为空. * type : CTypeValidator 的别名, 确保了特性为指定的数据类型. * unique : CUniqueValidator 的别名, 确保了特性在数据表字段中是唯一的. * url : CUrlValidator 的别名, 确保了特性是一个有效的路径. 验证的实现: 事实上CModel.rules()+CActiveForm.validate的结合就实现验证功能了。 例子: 【view】 beginWidget(‘CActiveForm’); ?> errorSummary($model); ?> //注1:这里显示出错时,报错的地方 …… endWidget(); ?> 【control】 $model=new user; if(isset($_POST['user'])) { $model->attributes=$_POST['user']; if($model->validate() && $model->save()) //注2:$model->validate()就是在调用model.rules进行验证 $this->redirect(array(‘view’,'id’=>$model->id)); } 【model】 class user extends CActiveRecord …… public function rules() { // NOTE: you should only define rules for those attributes that // will receive user inputs. return array( array(‘username, password, email’, ‘required’), array(‘username, password, email’, ‘length’, ‘max’=>128), array(‘id, username, password, email’, ‘safe’, ‘on’=>’search’), ); } …… 要实现更强大复杂的验证功能也就在rules()里做文章了。 有关用Ajax验证,会在Ajax专题中具体介绍。当然有必要时,也会再加的。         ================================================== 遇到个很囧的model rules问题(测试create与update的username) 1.array('username', 'required') 测试结果:create 生效(正常), update 生效(正常) 2.array('username', 'required', 'on' => 'create, update') 测试结果:create不生效(不正常), update 生效(正常) 3.array('username', 'required', 'on' => 'create') 测试结果:create不生效(不正常), update 不生效(正常) 4.array('username', 'required', 'on' => 'update') 测试结果:create不生效(正常), update 生效(正常)   ----=====-------=======----------=======---------========------ 缺省 new 出来的 model 实例的 scenario 是 insert 而不是 create ,你应该用 $model = new ModelClass('create'); 去试试。 ------------------------- 怪不得我以前写 create时候失败 后来new XXXXX('create')才可以 原来缺省 insert.           =========================================== 1.场景(scenario)多了怎么办? 项目中的user model,场景有10几个:注册,登录,修改用户基本资料,修改用户附属资料,修改用户密码,修改头像,修改用户隐私策略,修改用户tag,修改用户兴趣,爱好等等. 这么多场景(scenario)和验证(validation)交织在一起,觉得很混乱,CModel::rules函数很难写 2.验证(validation)不能用全局函数么??这样的话有很多验证要重复去写 ------------------------------------------------------------------------ 比如User Model中,有对user_name的validation_rule 在其他model中,比如用户好友,博客作者用户名等Model中,还要重复的去写相应的验证规则 比如我要在项目中的很多model中写上规则 array('user_name','match','pattern'=>'/^[a-zA-Z0-9_]{4,16}$/u','message'=>'账号只能由4-16个字母,数字,下划线组成'), 这样的话比如以后验证策略变了,要求用户名只能是10个字符以内,就比较麻烦,要把项目中所有model中验证user_name的规则进行修改 --------------====================---------------------------==================
  • 尽量不要用Model里面的rules,应该用Form里面的rules
  • 可以写自定义的validation,然后直接 array('user_name','ext.your_validation');-------------------------------- 1. 据你所说的意思应该是你在每一个功能点上者应用了一个场景吧?我想应该没这个必要,设置场景一般为了区别于一般情况的验证,比如注册需要验证确认密码字段 而其它情况下不需要验证这个字段,像这种情况就可以把“确认密码”这个字段的验证指定一个场景而其它的字段默认应用于所有的场景,不需要每一个能点上应用 一个场景。 2.多个模型都要用到的验证规则可以自己写成一个验证类,然后在各个model的rule中去运用这个类 ------------------------------- Form 是 Form,model 是 model,不同的。 当然,gii 生成的代码,是省略了 Form,直接拿 model 当 form 用,自然是 model 的 rules 判断了。
  原文地址:http://blog.csdn.net/hy840429/article/details/6725660

YII 验证和消息

setFlash(), getFlash()可以完成验证成功后提示 Java代码 <?php # 成功信息提示 Yii::app()->user->setFlash('success', "Thinks saved success!"); # 错误信息提示 Yii::app()->user->setFlash('error', "here has an Error, Please check that!"); # 一般消息信息提示 Yii::app()->user->setFlash('notice', "messge here"); ?> 2.errorSummary验证不通过的错误提示 rules()方法中定义的规则会在模型实例调用其 validate() 或 save() 方法时逐一执行。normalizeTags验证器是一个基于方法的验证器,Models/xx.php中的rules()的验证规则是对数据库表进行的,Models/xxForm.php中的rules()的验证规则是对表单进行的,和数据库表没有关系,类名和文件名要相同 。 如果我们使用一个validator(验证器)类,则这个类必须继承CValidator。其实有三种方法可以指定validator(验证器),包括前面提到的一种格式: 1.第一种是在模型类中定义验证方法 2.第二种是指定一个单独的验证器类(这个类继承validators/CValidator )。 3.第三种是你可以使用Yii框架中现有的验证器,指定预定义的验证器别名即可。 Yii为你提供了很多预定义的验证器类,同时也指定了别名,用在定义规则时。Yii1.1版本,预定义的验证器别名的完整列表如下: * captcha:它是CCaptchaValidator类的别名,验证属性的值等于一个显示的CAPTCHA(验证码)的值。 * compare:它是CCompareValidator类的别名'=','==','!=','>','>='。 * default:它是CDefaultValidator类的别名,验证属性的值为分配的默认值。 * exist:它是CExistValidator类的别名,验证属性的值在表中的对应列中存在。 * filter:它是CFilterValidator类的别名,用过滤器转换属性的值。 * in:它是CRangeValidator类的别名,验证属性值在一个预定义列表中。 * length:它是CStringValidator类的别名,验证属性值的长度在一个范围内。 * match:它是CRegularExpressionValidator类的别名,验证属性值匹配一个正则表达式。 * numerical:它是CNumberValidator类的别名,验证属性值是数字。 * type:它是CTypedValidator类的别名,验证属性值是一个指定的数据类型。 * unique:它是CUniquedValidator类的别名,验证属性值在表中的对应列中是唯一的。 * url:它是CUrlValidator类的别名,验证属性值是一个有效的URL。 2.单独的验证器类 方便重用 首先要做的是创建类文件.最好的方法时类的文件名和类名相同,可以使用yii的延迟加载(lazy loading)功能。 让我们在应用(application)的扩展(extensiions)目录(在 protected 文件夹下)下新建一个文件夹. 将目录命名为: MyValidators然后创建文件: passwordStrength.php Java代码 class passwordStrength extends CValidator{ public $strength; private $weak_pattern = '/^(?=.*[a-zA-Z0-9]).{5,}$/'; private $strong_pattern = '/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/'; protected function validateAttribute($object,$attribute) { // check the strength parameter used in the validation rule of our model if ($this->strength == 'weak') $pattern = $this->weak_pattern; elseif ($this->strength == 'strong') $pattern = $this->strong_pattern; // extract the attribute value from it's model object $value=$object->$attribute; if(!preg_match($pattern, $value)) { $this->addError($object,$attribute,'your password is too weak!'); } } 然后在模型(model)的: Java代码 /** * @return array validation rules for model attributes. */ public function rules() { return array( array('password', 'ext.MyValidators.passwordStrength', 'strength'=>self::STRONG), ); } 由于我们直接在User AR类中添加了$repassword属性,并且它与底层数据库表之间没有对应关系,我们需要告诉模型类允许这个属性在setAttributes()被调用时被设置。 保存时不能入库需要添加rules验证验证器 。我们的做法是将其添加到User模型类的安全属性列表中。向User::rules()数组添加下列代码: Java代码 array('repassword', 'safe'), 我们新建的$repassword不存在对应的tbl_user表中的列,需要将其直接添加到安全属性列表。 setAttributes: Java代码 $model->attributes=$_POST['User']; 添加了$repassword属性 Java代码 class User extends CActiveRecord { public $repassword; //不能是private会报错 以注册验证为例.controller Java代码 public function actionRegister() { $model=new User; if(isset($_POST['User'])) { $model->attributes=$_POST['User']; if($model->save()){ Yii::app()->user->setFlash('register','Thank you for your register.');//验证通过提示 $this->refresh(); } } $this->render('register',array( 'model'=>$model, )); } register.php Java代码 <h1>注册用户</h1> <?php if(Yii::app()->user->hasFlash('register')): ?> <div> <?php echo Yii::app()->user->getFlash('register'); ?> </div> <?php else: ?> <div> <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'user-form', 'enableAjaxValidation'=>false, )); ?> <p>Fields with <span>*</span> are required.</p> <?php echo $form->errorSummary($model); ?> <div> <?php echo $form->labelEx($model,'password'); ?> <?php echo $form->passwordField($model,'password',array('size'=>60,'maxlength'=>128, 'autocomplete'=>'off','value'=>'')); ?> <?php echo $form->error($model,'password'); ?> </div> <div> <?php echo $form->labelEx($model,'repassword'); ?> <?php echo $form->passwordField($model,'repassword',array('size'=>60,'maxlength'=>128, 'autocomplete'=>'off','value'=>'')); ?> <?php echo $form->error($model,'repassword'); ?> </div> <div> <?php echo CHtml::submitButton('注册'); ?> </div> <?php $this->endWidget(); ?> </div> <?php endif; ?> ajax动态验证 第一步:在_form中最上面改成 Java代码 $form=$this->beginWidget('CActiveForm', array( 'id'=>'user-form', 'enableAjaxValidation'=>true, ) 第二步:controller中添加,对应 'id'=>'user-form' Java代码 $this->performAjaxValidation($model); protected function performAjaxValidation($model) { if(isset($_POST['ajax']) && $_POST['ajax']==='user-form') { echo CActiveForm::validate($model); Yii::app()->end(); } } 第三步:在models层中加入checkemai方法 Java代码 public function rules() { // NOTE: 可以用exist验证器替换 return array( array('email', 'checkUser','message'=>'Test message for email validation'), array('user_id', 'checkUser','message'=>'Test message for {attribute} validation'), ); } public function checkUser($attribute,$params) //attribute用法 { switch($attribute){ case "email": //rules email $models = ServiceReviews::model()->findAllByAttributes(array('email' =>$this->email,'service_id'=>$this->service_id)); if(count($models)>0){ $this->addError($attribute, $params['message']); } break; case "user_id": if(Yii::app()->user->isGuest){ $models = ServiceReviews::model()->findAllByAttributes(array('user_id' =>Yii::app()->user->id,'service_id'=>$this->service_id)); if(count($models)>0){ $this->addError($attribute, $params['message']); } } break; } } 最后在models层的验证规则中(rules)加入以下验证规则{attribute} Java代码 array('email', 'checkUser','message'=>'已经存在{attribute}'), 刚才创建的方法需要两个参数: * $attribute 需要验证的属性 * $params 在规则中自定义的参数 在模型的 rules 方法中我们验证的是email属性,所以在验证规则中需要验证的属性值应该是 email. 在 rules 方法中我们还设置了自定义的参数 message,它的值将会放到 $params 数组中. 三.非表单验证错误处理 : 你会发现在方法中我们使用了 CModel::addError().添加错误接受两个参数:第一个参数是在表单中显示错误的属性名,第二个参数时显示的错误信息 。 用户提交表单时,可能除表单验证之外还有与表单各输入项无关的其他错误产生,例如后台数据库出错、接口调用失败等。 这种情况下可以在Model中相应的位置使用如下代码记录错误: Java代码 $this->addError('info', '发送不明错误,请重试'); // info 只是一个自定义的名字,不需要真正有这个字段或属性。 然后在视图文件中这样输出错误: Java代码 echo $form->error($model, 'info'); //$form 是 CActiveForm 的实例。$form->getErrors(); 当我们调用 CModel::validate() 方法, 我们可以指定一个场景参数. 只有在特定的场景下校验规则才会生效.校验规则会在那些 on 选项没有被设置或者包含了指定的场景名称的场景中生效.如果我们没有指定场景,而调用了 CModel::validate() 方法,只有那些 on 选项没有设置的规则才会被执行 . Java代码 $model = new model('register'); // or $model=new User; // $model->scenario='register'; 例如,在注册一个用户时,我们运行以下脚本来执行校验 : Java代码 array('password', 'compare', 'compareAttribute'=>'repassword', 'on'=>'register,edit'), Email验证器 Java代码 array('email','email'), //验证email这个字段必须符合email格式 Compare验证器 Java代码 array('password2','compare','compareAttribute'=>'password1'),//验证password1和password2必须一致 array('end_date','compare', 'compareAttribute' => 'start_date', 'operator' => '>', 'message' => '错误的开始结束日期'), Unique验证器 Java代码 array('username,email','unique','className'=>'User'),//User为Model,username,email在user中不允许重复 如果被验证属性为空,就认为完全合法,立刻返回,但是如果allowEmpty为false的话,就要通过函数后续的所有验证条件 。那么对于一个传入的空值来说,allowEmpty无论是true还是false,极有可能都不会报错,上面节选的验证器是StringValidator,如果我没有设定min的值,那么一个空串在allowEmpty为false的情况下,还是不会报任何错误的。 如果希望一个属性值不能为空,最好还是用RequiredValidator来验证,allowEmpty是不靠谱的,建议一般就采取allowEmpty的默认值true,可以节省几次判断。 Java代码 array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()), 布尔验证器 Java代码 array('rememberMe', 'boolean'), 数字验证器 Java代码 array('id', 'numerical', 'min'=>1, 'max'=>10, 'integerOnly'=>true), default验证器 datetime格式 Java代码 array('created','default','value'=>new CDbExpression('NOW()'),'setOnEmpty'=>false) fiter验证器 Java代码 array('moduleID', 'filter', 'filter'=>'trim'), 正则验证器 Java代码 array('name','match','pattern'=>'/^[a-z0-9\-_]+$/'), in验证器 Java代码 array('superuser', 'in', 'range' => array(0, 1)), length验证器 Java代码 array('password','length','min'=>'6','max'=>'16','message'=>'{attribute}长度必须在{min}到{max}之间'), 类型验证 integer,float,string,array,date,time,datetime Java代码 array('created', 'type', 'datetime'), 日期格式验证 Java代码 array('created', 'date', 'format'=>'yyyy/MM/dd/ HH:mm:ss'), 文件验证 Java代码 array('filename', 'file', 'allowEmpty'=>true, 'types'=>'zip, rar, xls, pdf, ppt'),