将一个模型传递一个到事件监听器里,为什么模型的getChanges、isDirty、isClean 、 wasChanged都为空?
1. 运行环境
1). 当前使用的 Laravel 版本?
Laravel Framework 10.31.0
2). 当前使用的 php/php-fpm 版本?
PHP 版本:PHP 8.1.21
php-fpm 版本:PHP 8.1.21
3). 当前系统
Ubuntu 22.04
4). 业务环境
开发环境
2. 问题描述?
下面是代码片段,运行php artisan debug
<?php
// 第一次dump
namespace App\Console\Commands;
use App\Models\Device\AlmDevice;
use Illuminate\Console\Command;
class Debug extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'debug';
public function handle()
{
$almDevice = AlmDevice::find(1);
$almDevice->update(['memo' => '12345021q6070']);
dump($almDevice->getChanges());
event(new \App\Events\Device\Alm\UpdatedEvent($almDevice));
}
}
<?php
// 第二次dump
namespace App\Events\Device\Alm;
use App\Events\BaseEvent;
use App\Models\Device\AlmDevice;
class UpdatedEvent extends BaseEvent
{
public AlmDevice $almDevice;
/**
* Create a new event instance.
*/
public function __construct(AlmDevice $almDevice)
{
parent::__construct();
$this->almDevice = $almDevice;
dump($almDevice->getChanges());
}
}
<?php
namespace App\Providers;
use App\Listeners\Device\AlmSyncSubscribe;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event to listener mappings for the application.
*
* @var array<class-string, array<int, class-string>>
*/
protected $listen = [
\App\Events\Device\Alm\UpdatedEvent::class => [
[AlmSyncSubscribe::class, 'onDeviceUpdated'],
]
];
/**
* Register any events for your application.
*/
public function boot(): void
{
//
}
/**
* Determine if events and listeners should be automatically discovered.
*/
public function shouldDiscoverEvents(): bool
{
return false;
}
}
<?php
// 第三次dump
namespace App\Listeners\Device;
use App\Events\Device\Alm\UpdatedEvent;
class AlmSyncSubscribe extends ShouldQueue
{
public function onDeviceUpdated(UpdatedEvent $event)
{
$almDevice = $event->almDevice;
dump($almDevice->getChanges());
}
}
3. 您期望得到的结果?
我期望是在第三次dump可以输出模型变更的属性
4. 您实际得到的结果?
array:2 [
"update_time" => "2023-11-20 17:24:22"
"memo" => "123450213q61070"
] // app/Console/Commands/Debug.php:26
array:2 [
"update_time" => "2023-11-20 17:24:22"
"memo" => "123450213q61070"
] // app/Events/Device/Alm/UpdatedEvent.php:19
[] // app/Listeners/Device/AlmSyncSubscribe.php:12
因为你的模型在派发任务时会因为
SerializesModels
这个 Trait 进行序列化,最后在消费的时候,再重新获取模型所以,其实你后面 AlmSyncSubscribe 里面其实是新查询到的一个模型,自然不存在这些变化。如果你需要这些变化,那你就要在派发的时候,单独取出来组装进去。
另外这也有一个值得思考的就是,在队列处理到这一行数据的时候,很可能它已经发生过变化了。