有关场景应用时的“非安全属性”,safe验证器,大家觉得有啥用呢? [ 技术分享 ]
近几天看了看yii2的模型场景机制和验证的部分,收获颇多,想来发一个话题跟大家好讨论下。
我觉得这个“非安全属性”没啥用,理由如下:
“安全属性”是对应场景下的属性,可以在load方法里完成赋值。如果不想被当前场景赋值,可以对某个字段加"!"前缀。使之成为“非安全属性”
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios[self::SCENARIO_CREATE] = ['contact_name','contact_tel','contact_addr'];
$scenarios[self::SCENARIO_UPDATE] = ['!contact_name','contact_tel','contact_addr'];
return $scenarios;
}
在SCENARIO_CREATE场景的时候,可以在load里完成['contact_name','contact_tel','contact_addr']的赋值;
在SCENARIO_UPDATE场景里,load()时只会对['contact_tel','contact_addr']完成赋值,不会对contact_name完成赋值。
可是我觉得,直接不写'!contact_name'也一样可以实现不对contact_name赋值。这样岂不是更好!
而至于contact_tel会不会被验证,和这里是不是安全属性没有关系!
第二个,就是safe验证器,按照文档所说https://www.yiichina.com/doc/guide/2.0/structure-models#safe-attributes safe验证器指明里不需要被验证的属性,比如:
public function rules()
{
return [
[['title', 'description'], 'safe'],
];
}
我觉得safe验证器也没啥用,safe仅仅是一个傀儡验证器,因为safeValidator只有两个空方法。
如果是这样的话,还不如不把safe写在rules方法里呢,这样['title', 'description']这些属性们当然不会被验证,更不会走safe验证器,还提高效率呢!
话说回来,如果要是有点用的话,那就是【提示,提醒】作用而已,而已。
它会告诉你"!contact_name"不会被load赋值;告诉你['title', 'description']不会被验证。
共 1 条回复
-
看了楼主的文章也是深感共鸣,感觉有所收获。
但是仔细看了下文档结合自己的代码输出,觉得这个里面的内容还是有出入的。首先,引用非安全属性的部分原话
你可能想验证一个属性但不想让他是安全的, 可在scenarios()方法中属性名加一个惊叹号 !
是想【验证】属性,但是不想让他安全。他想说的是验证,也就是说这个属性可能被自己直接赋值了
$model->contact_name = 'xxx'; // 为前提,才能让你此次的load通过,没有想到具体场景,假设场景就是你必须验证你的姓名是否为真(假设验证之后你的contact_name 才能赋值),然后load才能通过
其次,safe验证
safe验证器和不写还是大有区别的,不写在前台load的时候就不会被load上,而safe验证器是指的前台可以load随意任何值都可以,但是感觉很不安全是的。
不知道理解是否正确,帖子也有段时间了,挖出来也是想着更多的讨论。
敬礼。共 1 条回复首先这个话题我以为石沉大海了,其实应该有好多人看了但是并没有提出问题。互相学习下还是好的,尤其遇到了理解不一致的东西。
我还是拆成两个部分来理解:
第一,首先理解“安全属性”和load的关系。
“安全属性”这个概念的意思,就是说可以在对应场景下被load赋值的属性。这个在文档第一句话就说了:块赋值只应用在模型当前scenario 场景yii\base\Model::scenarios()方法 列出的称之为 安全属性 的属性上
块赋值就是指load()方法赋值。被赋值的属性就是安全属性。
你说的那个“想验证一个属性而又不想它是安全的”。我觉得你说得是对的。没有问题。对某些安全属性前缀加上"!"号后它就不会在load时被赋值了,它就是“非安全属性”了。当然你应该在这之前或之后用其它方法赋值。第二个:对于safe验证器的理解来说,我还是坚持我的看法,
safe验证器写与不写都不影响load()过程。safe紧紧是声明了不验证的属性而已。这些属性可以是load赋值的,或者直接赋值的都无所谓。
文档上有一段话是这么翻译的,但是我觉得有理解歧义:
为此,提供一个特别的别名为 safe 的验证器来申明 哪些属性是安全的不需要被验证, 如下示例的规则申明 title 和 description 都为安全属性。
上面说
“哪些属性是安全的不需要被验证”
我觉得“不需要被验证”说对了,因为safe验证器就是一个傀儡验证器,没有验证过程。
但是“哪些属性是安全的”
这部分。这里的“安全”,我觉得应该不是前面所说的“安全属性”里的“安全”。这里的“安全”就是我们所说的,主观上认为这些属性没有问题,没有漏洞,可以不走,也不需要走验证过程,“很安全”。所以这里和load()没有关系。
再回到第一句文章的原话:
你可能想验证一个属性但不想让他是安全的, 可在scenarios()方法中属性名加一个惊叹号 !
我觉得把这句话包含了load()和验证两个过程,把它俩加一块理解就可以了:
“想验证一个属性”,说的是后面的rules里的规则验证过程;
“不想让他是安全的”是说不希望被load()赋值。
就这样理解。你觉得咋样?我觉得很有意思。
刘师傅 河北省邯郸市永年区
最后登录:2024-07-04
在线时长:81小时48分
- 粉丝9
- 金钱20897
- 威望220
- 积分23907