当使用Massive Assignment时,如果form内的数据没有在rules验证规则中明确的指定,对这个字段的赋值将不会生效, 对于那些没有特殊要求的字段至少也好设置safe规则。 ?phppublic function actionCreate(){$model=new Post;if(isset($_POST['Post'])){$model-
当使用Massive Assignment时,如果form内的数据没有在rules验证规则中明确的指定,对这个字段的赋值将不会生效,
对于那些没有特殊要求的字段至少也好设置safe规则。
<?php
public function actionCreate()
{
$model=new Post;
if(isset($_POST['Post']))
{
$model->attributes=$_POST['Post'];//tag A
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
看tag A部分,它执行了一下的流程:
The key is $model->attributes = $_POST['Comment'];, which is deceptively simple.In reality this is calling
$model->setAttributes( $_POST['Comment'] ); // this is an array!
CModel的setAttributes详细代码如下:
<?php
public function setAttributes($values,$safeOnly=true)
{
if(!is_array($values))
return;
$attributes=array_flip($safeOnly ? $this->getSafeAttributeNames() : $this->attributeNames());// tag B
foreach($values as $name=>$value)?//tag E
{
if(isset($attributes[$name]))
$this->$name=$value;//tag F
else if($safeOnly)//tag G
$this->onUnsafeAttribute($name,$value);
}
}
看tag B 部分,因为$safeOnly默认是true,所以这里首先开始执行$this->getSafeAttributeNames();
CModel的getSafeAttributeNames详细代码如下:
<?php
public function getSafeAttributeNames()
{
$attributes=array();
$unsafe=array();
foreach($this->getValidators() as $validator)?//tag C
{
if(!$validator->safe)
{
foreach($validator->attributes as $name)
$unsafe[]=$name;
}
else
{
foreach($validator->attributes as $name)
$attributes[$name]=true;
}
}
foreach($unsafe as $name)
unset($attributes[$name]);
return array_keys($attributes);
}看tag C部分,此处开始执行$this->getValidators();
CModel的getValidators详细代码如下:
<?php
public function getValidators($attribute=null)
{
if($this->_validators===null)
$this->_validators=$this->createValidators();//tag D
$validators=array();
$scenario=$this->getScenario();
foreach($this->_validators as $validator)
{
if($validator->applyTo($scenario))
{
if($attribute===null || in_array($attribute,$validator->attributes,true))
$validators[]=$validator;
}
}
return $validators;
}
看tag D部分,代码如下:
<?php
public function createValidators()
{
$validators=new CList;
foreach($this->rules() as $rule)
{
if(isset($rule[0],$rule[1])) // attributes, validator name
$validators->add(CValidator::createValidator($rule[1],$this,$rule[0],array_slice($rule,2)));
else
throw new CException(Yii::t('yii','{class} has an invalid validation rule. The rule must specify attributes to be validated and the validator name.',
array('{class}'=>get_class($this))));
}
return $validators;
}可以看到在这个方法中开始使用验证规则,如果$this->rules()是个空数组则foreach内的消息体都不会被执行,直接执行下面的return $validators;
最终返回了空的CList的实例。现在回到getValidators()方法,$this->_validators就是一个空的CList实例,$validators初始化为空数组,getValidators直接返回$validators到getSafeAttributeNames的tag C处,同理getSafeAttributeNames也返回了空的数组给setAttributes的tag B处。
最终$attributes为空数组。在执行tag E处循环时一直执行tag G而不是执行tag F部分,而tag F部分才是真正的绑定值。
参考地址:http://www.yiiframework.com/wiki/161/understanding-safe-validation-rules/
原文地址:yii ar中的rules()规则在收集表单中的一些作用, 感谢原作者分享。
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号