yii 场景scenario在模型验证规则的使用

  

用户指南原文:

  1.1 中的安全特性

  在版本 1.1 中,特性如果出现在相应场景的一个验证规则中,即被认为是安全的。 例如:

array('username, password', 'required', 'on'=>'login, register'),
array('email', 'required', 'on'=>'register'),

 

如上所示, username 和 password 特性在 login 场景中是必填项。而 usernamepassword 和 email 特性在register 场景中是必填项。 于是,如果我们在 login 场景中执行块赋值,就只有 username 和 password 会被块赋值。 因为只有它们出现在 login 的验证规则中。 另一方面,如果场景是 register ,这三个特性就都可以被块赋值。

 // 在登录场景中
 $model=new User('login');
 if(isset($_POST['User']))
     $model->attributes=$_POST['User'];
  
 // 在注册场景中
 $model=new User('register');
 if(isset($_POST['User']))
     $model->attributes=$_POST['User'];

 

 

那么为什么我们使用这样一种策略来检测特性是否安全呢? 背后的基本原理就是:如果一个特性已经有了一个或多个可检测有效性的验证规则,那我们还担心什么呢?

请记住,验证规则是用于检查用户输入的数据,而不是检查我们在代码中生成的数据(例如时间戳,自动产生的主键)。 因此,不要 为那些不接受最终用户输入的特性添加验证规则。

有时候,我们想声明一个特性是安全的,即使我们没有为它指定任何规则。 例如,一篇文章的内容可以接受用户的任何输入。我们可以使用特殊的 safe 规则实现此目的:

array('content', 'safe')

 

为了完成起见,还有一个用于声明一个属性为不安全的 unsafe 规则:

array('permission', 'unsafe')

 

unsafe 规则并不常用,它是我们之前定义的安全特性的一个例外。

1.0 中的安全特性

在版本1.0中,决定一个数据项是否是安全的,基于一个名为 safeAttributes 方法的返回值和数据项被指定的场景. 默认的,这个方法返回所有公共成员变量作为 CFormModel 的安全特性,而它也返回了除了主键外, 表中所有字段名作为 CActiveRecord的安全特性.我们可以根据场景重写这个方法来限制安全特性 .例如, 一个用户模型可以包含很多特性,但是在 login 场景.里,我们只能使用 username 和 password 特性.我们可以按照如下来指定这一限制 :

public function safeAttributes()
{
    return array(
        parent::safeAttributes(),
        'login' => 'username, password',
    );
}

 

safeAttributes 方法更准确的返回值应该是如下结构的 :

array(
   // these attributes can be massively assigned in any scenario
   // that is not explicitly specified below
   'attr1, attr2, ...',
     *
   // these attributes can be massively assigned only in scenario 1
   'scenario1' => 'attr2, attr3, ...',
     *
   // these attributes can be massively assigned only in scenario 2
   'scenario2' => 'attr1, attr3, ...',
)

 

如果模型不是场景敏感的(比如,它只在一个场景中使用,或者所有场景共享了一套同样的安全特性),返 回值可以是如下那样简单的字符串.

'attr1, attr2, ...'

 

而那些不安全的数据项,我们需要使用独立的赋值语句来分配它们到相应的特性.如下所示:

$model->permission='admin';
$model->id=1;
 
 

 

 

而在更新数据时,官方并没有说明该如何设置scenario,当用于数据更新时,博主亲测报错

$model = user::model('passwd');  //场景:passwd

 

正确方式是

$model=user::model();
$model->setScenario('passwd');

 

posted @ 2015-03-21 13:49  sanerror  阅读(1019)  评论(0)    收藏  举报