YII验证规则自定义教程

jerry Yii 2015年08月12日 收藏

1.setFlash(), getFlash()可以完成验证成功后提示
2.errorSummary验证不通过的错误提示
如果我们使用一个validator(验证器)类,则这个类必须继承CValidator。其实有三种方法可以指定validator(验证器),包括前面提到的一种格式:
1.第一种是在模型类中定义验证方法
2.第二种是指定一个单独的验证器类(这个类继承validators/CValidator )。
3.第三种是你可以使用Yii框架中现有的验证器,指定预定义的验证器别名即可。
Yii为你提供了很多预定义的验证器类,同时也指定了别名,用在定义规则时。Yii1.1版本,预定义的验证器别名的完整列表如下:

* boolean:它是CBooleanValidator类的别名,验证属性的值是布尔值(true或false)。
* captcha:它是CCaptchaValidator类的别名,验证属性的值等于一个显示的CAPTCHA(验证码)的值。
* compare:它是CCompareValidator类的别名,验证属性的值与另一个属性的值相等。
* email:它是CEmailValidator类的别名,验证属性的值为有一个有效的Email地址。
* default:它是CDefaultValidator类的别名,验证属性的值为分配的默认值。
* exist:它是CExistValidator类的别名,验证属性的值在表中的对应列中存在。
* file:它是CFileValidator类的别名,验证属性的值包含上传的文件。
* filter:它是CFilterValidator类的别名,用过滤器转换属性的值。
* in:它是CRangeValidator类的别名,验证属性值在一个预定义列表中。
* length:它是CStringValidator类的别名,验证属性值的长度在一个范围内。
* match:它是CRegularExpressionValidator类的别名,验证属性值匹配一个正则表达式。
* numerical:它是CNumberValidator类的别名,验证属性值是数字。
* required:它是CRequiredValidator类的别名,验证属性值必需有值,不能为空。
* type:它是CTypedValidator类的别名,验证属性值是一个指定的数据类型。
* unique:它是CUniquedValidator类的别名,验证属性值在表中的对应列中是唯一的。
* url:它是CUrlValidator类的别名,验证属性值是一个有效的URL。


1.自定义规则验证
然后在模型(model)的:

const WEAK = 0;
const STRONG = 1;
public function rules()
{
return array(
array(‘password’, ‘passwordStrength’, ‘strength’=>self::STRONG),
);
}
public function passwordStrength($attribute,$params)//(参数是固定格式)
{
if ($params['strength'] === self::WEAK)
$pattern = ‘/^(?=.*[a-zA-Z0-9]).{5,}$/’;
elseif ($params['strength'] === self::STRONG)
$pattern = ‘/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/’;
if(!preg_match($pattern, $this->$attribute))
$this->addError($attribute, ‘your password is not strong enough!’);
}


刚才创建的方法需要两个参数:

* $attribute 需要验证的属性
* $params 在规则中自定义的参数


在模型的 rules 方法中我们验证的是 password 属性,所以在验证规则中需要验证的属性值应该是 password.
在 rules 方法中我们还设置了自定义的参数 strength,它的值将会放到 $params 数组中.
你会发现在方法中我们使用了 CModel::addError().
添加错误接受两个参数:第一个参数是在表单中显示错误的属性名,第二个参数时显示的错误信息 。
2.单独的验证器类
首先要做的是创建类文件.最好的方法时类的文件名和类名相同,可以使用 yii 的延迟加载(lazy loading)功能。
让我们在应用(application)的扩展(extensiions)目录(在 protected 文件夹下)下新建一个文件夹.
将目录命名为: MyValidators然后创建文件: passwordStrength.php

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)的:

public function rules()
{
return array(
array(‘password’, ‘ext.MyValidators.passwordStrength’, ‘strength’=>self::STRONG),
);
}


由于我们直接在User AR类中添加了$repassword属性,并且它与底层数据库表之间没有对应关系,我们需要告诉模型类允许这个属性在setAttributes()被 调用时被设置。 我们的做法是将其添加到User模型类的安全属性列表中。向User::rules()数组添加下列代码:

array(‘repassword’, ‘safe’),


我们新建的$repassword不存在对应的tbl_user表中的列,需要将其直接添加到安全属性列表。
setAttributes:

$model->attributes=$_POST['User'];
//$model->vpnip =$_POST['User']['vpnip'];


添加了$repassword属性

class User extends CActiveRecord
{
public $repassword; //不能是private会报错
以注册验证为例.controller
public function actionRegister()
{
$model=new User;
if(isset($_POST['User']))
{
$model->attributes=$_POST['User'];
if($model->validate()){
….
$model->save();
Yii::app()->user->setFlash(‘register’,'Thank you for your register.’);//验证通过提示
$this->redirect(array(‘register’));
}
}
$this->render(‘register’,array(
‘model’=>$model,
));
}