在 Eloquent 模型类上进行查询、插入、更新、删除操作时,会触发相应的模型事件,不管你有没有监听它们。
这些事件包括:
retrieved:获取到模型实例后触发 creating:插入到数据库前触发 created:插入到数据库后触发
updating:更新到数据库前触发 updated:更新到数据库后触发
saving:保存到数据库前触发(插入/更新之前,无论插入还是更新都会触发)
saved:保存到数据库后触发(插入/更新之后,无论插入还是更新都会触发)
deleting:从数据库删除记录前触发
deleted:从数据库删除记录后触发
restoring:恢复软删除记录前触发
restored:恢复软删除记录后触发注:批量更新时不会触发相应事件,因为是直接走查询构建器完成的,绕过了模型方法。
通过静态方法监听模型事件
在模型类上调用要监听事件对应的静态方法
// app/Providers/EventServiceProvider.php
public function boot()
{
parent::boot();
// 监听模型获取事件,闭包函数传入参数-模型实例
User::retrieved(function ($user) {
Log::info('从模型中获取用户[' . $user->id . ']:' . $user->name);
});
}
通过订阅者监听模型事件
操作:
1.创建对应的事件类
php artisan make:event UserDeleted
2.将 Eloquent 支持的模型事件与自定义的事件类建立映射关系
# app/Models/User.php
protected $dispatchesEvents = [
'deleting' => UserDeleting::class,
'deleted' => UserDeleted::class
];
3.将事件类注册到监听器类中
第1种方式:
listen属性中为每个事件,绑定对应监听器 (有event, 有listener)
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'App\Events\Event' => [
'App\Listeners\EventListener',
'App\Listeners\UserDeletingListener',
'App\Listeners\UserDeletedListener',
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
Sheet::observe(SheetObserver::class);
}
}
第2种方式:
为某个模型类创建一个事件订阅者类来统一处理该模型中的所有事件
<?php
namespace App\Listeners;
use App\Events\UserDeleted;
use App\Events\UserDeleting;
use Illuminate\Support\Facades\Log;
// 订阅者类
class UserEventSubscriber
{
/**
* 处理用户删除前事件
*/
public function onUserDeleting($event) {
Log::info('用户即将删除[' . $event->user->id . ']:' . $event->user->name);
}
/**
* 处理用户删除后事件
*/
public function onUserDeleted($event) {
Log::info('用户已经删除[' . $event->user->id . ']:' . $event->user->name);
}
/**
* 为订阅者注册监听器
*
* @param Illuminate\Events\Dispatcher $events
*/
public function subscribe($events)
{
$events->listen(
UserDeleting::class,
UserEventSubscriber::class . '@onUserDeleting'
);
$events->listen(
UserDeleted::class,
UserEventSubscriber::class . '@onUserDeleted'
);
}
}
// app/Providers/EventServiceProvider.php
protected $subscribe = [
UserEventSubscriber::class
];
触发代码:
$user = User::findOrFail(10);
$user->delete();
[2018-12-05 02:14:50] local.INFO: 从模型中获取用户[10]:Dr. Kory Abshire IV
[2018-12-05 02:14:50] local.INFO: 用户即将删除[10]:Dr. Kory Abshire IV
[2018-12-05 02:14:50] local.INFO: 用户已经删除[10]:Dr. Kory Abshire IV
通过观察者监听模型事件
观察者/订阅者区别:
订阅者处理模型事件的简化版本
不需要自定义事件类
不需要建立映射关系
只需要在观察者类中将需要监听的事件定义为同名方法,处理业务逻辑即可
创建User模型的观察者
php artisan make:observer UserObserver --model=User
默认生成的 UserObserver 会为 created、 updated、deleted、restored、forceDeleted(强制删除) 事件定义一个空方法
对于监听的事件方法,可以根据需要自行增删
<?php
namespace App\Observers;
use App\User;
use Illuminate\Support\Facades\Log;
class UserObserver
{
public function saving(User $user)
{
Log::info('即将保存用户到数据库[' . $user->id . ']' . $user->name);
}
public function creating(User $user)
{
Log::info('即将插入用户到数据库[' . $user->id . ']' . $user->name);
}
public function updating(User $user)
{
Log::info('即将更新用户到数据库[' . $user->id . ']' . $user->name);
}
public function updated(User $user)
{
Log::info('已经更新用户到数据库[' . $user->id . ']' . $user->name);
}
public function created(User $user)
{
Log::info('已经插入用户到数据库[' . $user->id . ']' . $user->name);
}
public function saved(User $user)
{
Log::info('已经保存用户到数据库[' . $user->id . ']' . $user->name);
}
}
观察者注册到User模型,才能生效:
// EventServiceProvider.php
public function boot()
{
parent::boot();
User::observe(UserObserver::class);
...
}
触发事件
$user = new User();
$user->name = '学院君测试号01';
$user->email = 'test01@laravelacademy.org';
$user->password = bcrypt('secret');
$user->save();
[2018-12-05 02:50:00] local.INFO: 即将保存用户到数据库[]学院君测试号01
[2018-12-05 02:50:00] local.INFO: 即将插入用户到数据库[]学院君测试号01
[2018-12-05 02:50:00] local.INFO: 已经插入用户到数据库[19]学院君测试号01
[2018-12-05 02:50:00] local.INFO: 已经保存用户到数据库[19]学院君测试号01