yii2 的AR的refresh可以让模型刷新到最新吧?就是刚刚更新过的
2026-03-05
大方向是对的,但有一个很关键的小细节很多人容易误解。我把 Yii2 里 ActiveRecord::refresh() 的真实行为给你讲清楚。
一、refresh() 的作用是什么
在 Yii2 中:
$model->refresh();
作用是:
从数据库重新读取当前记录的数据,并覆盖当前模型对象的属性。
也就是说:
数据库 → 重新加载 → 覆盖当前AR对象
官方行为可以理解为:
重新执行一次 SELECT
相当于:
SELECT * FROM table WHERE primary_key = ?
二、典型使用场景
例如:
$user = User::findOne(1); $user->name = 'A'; $user->save(); $user->refresh();
执行流程:
save() → 更新数据库 refresh() → 再从数据库读取
这样 $user 里的属性就是 数据库最新状态。
三、refresh() 为什么有用
很多情况下数据库的数据会被 别的逻辑修改。
例如:
1 数据库触发器
update_time 自动更新
2 数据库默认值
created_at = NOW()
3 其他进程修改
例如:
队列 定时任务 其他接口
这时:
$model->refresh();
就能把最新值同步回来。
四、refresh() 会做什么操作
refresh 会做三件事:
1 重新查询数据库
$this->findOne($this->primaryKey)
2 覆盖当前属性
$this->attributes = db_attributes
3 清空 dirtyAttributes
所以 refresh 后:
模型状态 = 干净
五、refresh() 不会做什么
refresh 不会重新创建对象。
还是原来的 $model。
只是:
覆盖属性
六、refresh() 的返回值
if ($model->refresh()) {
}返回:
true 成功 false 记录不存在
例如记录被删了。
七、refresh 的源码逻辑(简化版)
核心逻辑其实很简单:
public function refresh()
{
$record = static::findOne($this->getPrimaryKey());
if ($record === null) {
return false;
}
$this->setAttributes($record->getAttributes(), false);
return true;
}八、一个很多人忽略的坑
如果你这样写:
$model->updateAttributes([ 'status' => 1 ]);
然后:
$model->refresh();
这一步其实 通常没必要。
因为:
$model 本身已经是最新
refresh只是再查一次数据库。
九、refresh 不适用的情况
refresh 不能解决事务未提交的问题。
例如:
事务 A:
$model->status = 1; $model->save();
事务 B:
$model->refresh();
如果 A 没 commit
B 仍然读不到。
十、什么时候必须用 refresh
下面这几种情况推荐用:
数据库触发器
update_time
自增字段
sequence
其他服务修改
例如:
消息队列 websocket 异步任务
十一、实际开发建议
很多 Yii2 项目里常见写法:
$model->save(false); $model->refresh();
作用就是:
确保当前对象状态 = 数据库状态
十二、总结一句话
refresh() 的本质就是:
重新 SELECT 当前记录 并覆盖当前 AR 对象属性
所以你说:
可以让模型刷新到最新吧?
答案是:
对,但前提是数据库里已经是最新数据。
发表评论: