eloquent attribute realtime states 是开发者对模型属性变更时立即感知并响应的通俗描述,核心是用 getdirty() 和 getoriginal() 检测真实变化,配合广播事件实现状态变更的实时处理。

什么是 Eloquent Attribute Realtime States?
它不是 Laravel 官方概念,也没有 RealtimeStates 这个内置类或 trait。你在文档或社区里搜不到这个东西——它通常是开发者对「在模型属性变更时立刻感知、响应、触发副作用」的一种口语化描述,比如:用户状态从 pending 变成 active 时,立刻发通知、更新缓存、推送到 WebSocket。别被名字唬住,核心就是「监听属性变化并实时反应」。
用 getDirty() + getOriginal() 捕获真实变更
Laravel 的 $model->isDirty() 或 $model->getDirty() 是最轻量、最可靠的变更检测方式,比监听事件更直接,也比重写 setter 更可控。
-
getDirty()返回本次修改中「新值不同于原始值」的字段数组(如['status' => 'active']) -
getOriginal('status')返回数据库里原来的值(哪怕你没 save,只要是从 DB 加载的,就有原始值) - 注意:
isDirty()在刚 new 一个模型时返回 false;只有从 DBfind()或first()加载后,再改属性,才有效 - 不要依赖
isset($model->status)或!empty()判断是否变了——这些只看当前值,不反映「变没变」
// 在控制器或服务类里
$user = User::find(123);
$originalStatus = $user->getOriginal('status'); // 'pending'
$user->status = 'active';
if ($user->isDirty('status')) {
$old = $originalStatus;
$new = $user->status;
// ? 这里才是「实时状态变更」的入口点
broadcast(new StatusChanged($user, $old, $new));
}
避免在 boot() 里盲目监听 saving/saved
很多人一上来就往 boot() 里塞 static::saving(),结果发现:状态没变也触发、批量更新时重复执行、事务中提前触发导致数据不一致。
-
saving在写入前触发,但此时getDirty()已可用;saved在写入后触发,但原始值可能已被覆盖(尤其多并发时) - 真正需要「实时」响应的场景,往往要区分「是不是真变了」和「变的是哪个字段」——直接在业务逻辑里调用判断,比全局事件更安全
- 如果非要用事件,务必加字段过滤:
if ($model->isDirty('status')) { ... },且避免在事件里做耗时操作(如 HTTP 请求),应 dispatch job - 注意:
updating事件只在 update 操作触发,creating不会触发它——别假设所有变更都走同一套流程
流式处理?别绕远,先用 Queueable + ShouldBroadcast 衔接
所谓「Laravel 流处理」,不是指像 Kafka 那样搞消息队列拓扑,而是把状态变更当作一个事件流,用 Laravel 自带的广播+队列机制串起来。
- 定义一个广播事件类,实现
ShouldBroadcast和Queueable,这样它自动进队列、异步推送到 Pusher/Redis/Soketi - 前端用 Laravel Echo 监听
App.Models.User频道里的StatusChanged事件,拿到old/new就能局部刷新 UI - 不要在模型里直接调用
broadcast()——它会同步执行,阻塞请求;一定要让事件可队列化 - 如果需要更细粒度控制(比如只推给某用户的好友),在
broadcastOn()方法里动态返回私有频道,而不是硬编码公共频道
复杂点在于:状态变更可能嵌套(如订单状态变,连带更新用户积分、库存、物流单),这时候得靠「领域事件」模式解耦,而不是堆砌 if isDirty。但起步阶段,老老实实用 getDirty() + 广播事件,已经能 cover 80% 的实时状态需求。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











