yii 场景scenario在模型验证规则的使用
用户指南原文:
1.1 中的安全特性
在版本 1.1 中,特性如果出现在相应场景的一个验证规则中,即被认为是安全的。 例如:
array('username, password', 'required', 'on'=>'login, register'), array('email', 'required', 'on'=>'register'),
如上所示, username
和 password
特性在 login
场景中是必填项。而 username
, password
和 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');