接下来我将为大家演示AR类的增删改查操作
首先我们创建一个UserController,并且创建一个actionCreate方法
public function actionCreate(){
$now = time();
//实例化User的对象
$user = new User();
//给它的属性赋值
$user->username = '鑫仔';
$user->city_id = 2;
$user->create_time = $now;
$user->update_time = $now;
//保存
if($user->save()){
echo '插入成功,id为'.$user->id;
}else{
//保存失败则打印错误
dump($user->getErrors());
}
}
输出“插入成功,id为13”
再去看数据库,多了一行数据
那么AR内部是如何实现这一系列的动作的咧
new User()实例化User模型,调用了父类CActiveRecord的构造方法
public function __construct($scenario='insert')
{
if($scenario===null) // internally used by populateRecord() and model()
return;
//设置场景,场景的主要作用是对对象的约束,比如说你自己是一个对象,那么家是你的一个场景 公司又是你的另外一个场景,不同的场景对你约束是不一样的
$this->setScenario($scenario);
//设置用来判断是插入还是更新的一个标记
$this->setIsNewRecord(true);
//获取数据库中有默认值的字段并赋值到_attributes属性中
$this->_attributes=$this->getMetaData()->attributeDefaults;
//初始化
$this->init();
//绑定行为
$this->attachBehaviors($this->behaviors());
//调用构造方法后钩子 并触发事件onaferconstruct
$this->afterConstruct();
}
那么至此实例化的一个user的模型对象拥有了 场景属性 是否是新纪录属性 默认值属性数组 绑定了一些行为 触发了一些事件
$user
-
>username
=
'鑫仔'; 接下来我们调用了赋值操作
我们看到其实user类中并没有username这个属性,那么他肯定是调用了魔术方法__set()
public function __set($name,$value)
{
//见方法setAttribute
if($this->setAttribute($name,$value)===false)
{
if(isset($this->getMetaData()->relations[$name]))
$this->_related[$name]=$value;
else
parent::__set($name,$value);
}
}
public function setAttribute($name,$value)
{
//先判断是否存在该属性,有则赋值给该属性,再判断表中是否有这个字段,有则将这个字段以及赋值存放在_attributes属性中,所以attributes属性中存放的是所有的字段及值
if(property_exists($this,$name))
$this->$name=$value;
elseif(isset($this->getMetaData()->columns[$name]))
$this->_attributes[$name]=$value;
else
return false;
return true;
}
$user->save()最后一步 保存
public function save($runValidation=true,$attributes=null)
{
//第一个参数 是否在保存时执行验证 第二个参数 需要验证的字段数组 默认为所有
//验证完后 判断是新记录还是旧记录 新记录则调用插入方法 旧记录则调用更新方法
if(!$runValidation || $this->validate($attributes))
return $this->getIsNewRecord() ? $this->insert($attributes) : $this->update($attributes);
else
return false;
}