话不多说,直奔主题!
直接上源码分析:
public function load($data, $formName = null)
{
// 调用load 一般我是 $test = new test()
// $test->load('参数1','参数2')
// 参数1 一般是post get 传过来的参数 第二个参数 是一个空字符串 '';
// $this->formName() 返回的额是 你实例化的类的名字 new test() 最后返回的是test
$scope = $formName === null ? $this->formName() : $formName;
if ($scope === '' && !empty($data)) {
$this->setAttributes($data); //进入
return true;
} elseif (isset($data[$scope])) {
$this->setAttributes($data[$scope]);
return true;
} else {
return false;
}
}
接下来看 setAttributes() :
public function setAttributes($values, $safeOnly = true)
{
if (is_array($values)) {
$attributes = array_flip($safeOnly ? $this->safeAttributes() : $this->attributes());
//这里执行的是$this->safeAttributes()方法,该方法返回的是当前场景下需要验证的字段。最后$attributes打印下来看下图
foreach ($values as $name => $value) {
if (isset($attributes[$name])) {
$this->$name = $value;
} elseif ($safeOnly) {
$this->onUnsafeAttribute($name, $value);
}
}
}
}
这里就会返回当前场景下需要验证的字段,涉及场景和规则,打印一下,其实就是返回的对应的就是表字段或者自定义属性字段。
array(2) {
["id"]=>
int(0)
["name"]=>
int(1)
}
在之后 执行的是 foreache循环 这里的$this 是那个$test 这个对象对象去调用 :
// 例如post 提交过来的数据是这样
$post=[
'id'=>123456,
'name'=>'lily'
] ;
$test->id=123456;
$test->name='lily';
所以这个load()方法只是分配post 或者get 发过来的数据,不做验证。
接下来看save(); 直接查看save方法源码 。
public function save($runValidation = true, $attributeNames = null)
{
if ($this->getIsNewRecord()) {//判断是否是新纪录
return $this->insert($runValidation, $attributeNames);//执行这里 之后$this代表的是test 这个模型表。
//test 继承的是\yii\db\ActiveRecord 查看insert() 方法 。
} else {
return $this->update($runValidation, $attributeNames) !== false;
}
}
继续跟踪 insert() 方法中:
public function insert($runValidation = true, $attributes = null)
{
if ($runValidation && !$this->validate($attributes)) {//下面的代码分析validate方法 验证rules
return false;
}
$result = $this->insertInternal($attributes);//保存数据
return $result;
}
或者跟踪update()方法:
public function update($runValidation = true, $attributeNames = null)
{
if ($runValidation && !$this->validate($attributeNames)) {//下面的代码分析validate方法 验证rules
return false;
}
return $this->updateInternal($attributeNames);//保存数据
}
然后跟踪任意的 validate()方法:
public function validate($attributeNames = null, $clearErrors = true)
{
if ($clearErrors) {
$this->clearErrors();
}
if (!$this->beforeValidate()) { //在验证之前首先执行的是 beforValidata
return false;
}
$scenarios = $this->scenarios();
$scenario = $this->getScenario();//检查是否调用场景
if (!isset($scenarios[$scenario])) {
throw new InvalidArgumentException("Unknown scenario: $scenario");
}
if ($attributeNames === null) {
$attributeNames = $this->activeAttributes();//返回数组(值为属性的名称)
}
$attributeNames = (array)$attributeNames;
// $this->getActiveValidators() 验证数据。
// 读取rules 方法 getActiveValidators() ->getValidators()->createValidators()
// 这里验证rules等信息->createValidator()
foreach ($this->getActiveValidators() as $validator) {
$validator->validateAttributes($this, $attributeNames);
}
$this->afterValidate();//获取交集 检查是否有错误 hasError()
return !$this->hasErrors();
}
由此可知,调用save方法时,会自动调用validate方法,执行数据校验。随着数据验证完毕,之后就保存数据 。
全篇完。