模型触发事件

允许你在模型生命周期中的多个时间点调用如下这些方法: retrieved, creating, created, updating, updated, saving, saved, deleting, deleted, restoring,restored。

事件允许你在一个指定模型类每次保存或更新的时候执行代码

事件 描述
retrieved 获取到模型实例后发
creating 插入到数据库前发
created 插入到数据库后发
updating 更新到数据库前发
updated 更新到数据库后发
savmg 保存到数据库前发(适入/更新之前,无论插入还是更新都会触发)
saved 保存到数据库后发(插入/更新之后,无论插入还是更新都会触发)
deleting 从数据库删除记录前发
deleted 从数据库删除记录后发
restoring 恢复软删除讠己录前发
restored 恢复软删除讠己录后发

注:批量更新时不会触发相应事件,因为是直接走查询构建器完成的,绕过了模型方法

通过静态方法监听模型事件

//app\Providers\EventServiceProvider.php
	//插入到数据库后的操作
	public function boot() {
		parent::boot();
		//闭包函数传入参数是模型实例
		User::created(function ($user){
			Log::info('插入到数据库后实现的方法',$user->toArray());
		});
	}

	//插入到数据库前的操作,可以更改插入的值
	public function boot() {
		parent::boot();
		User::creating(function ($user) {
			$user->password = 'shuxiaoyuan';
			Log::info('插入到数据库前实现的方法', $user->toArray());
		});
	}

通过订阅者监听模型事件

  • 创建对应的事件类

php artisan make:event UserCreated

在事件类中加入如下代码

	use App\Models\User;

	public $users;

	public function __construct(User $user)
    {
        $this->users = $user;
    }
  • 建立模型事件与自定义事件类的映射
	//在model中加入如下代码
	use App\Events\UserCreated;
	
	//建立模型事件与自定义事件类的映射
	protected $dispatchesEvents = [
		'created'=> UserCreated::class,
	];
  • 创建订阅者监听事件类 可以直接在 app\Providers\EventServiceProvider.php 文件的listen属性中为每个事件绑定对应的监听器类,这里我们直接搞一个专门的目录来管理。 在App目录下创建文件夹 Listeners 在文件夹中新建文件 UserEventSubscriber.php 在文件中添加如下代码
<?php

namespace App\Listeners;

use App\Events\UserCreated;
use App\Events\UserDeleted;
use App\Events\UserDeleting;
use Illuminate\Support\Facades\Log;

class UserEventSubscriber {
	
	/**
	 * 处理用户登录事件.
	 *
	 * @translator laravelacademy.org
	 */
	public function onUserLogin($event) {
	
	}
	
	/**
	 * 处理用户退出事件.
	 */
	public function onUserLogout($event) {
	
	}
	
	/**
	 * 处理User模型插入后事件
	 */
	public function onUserCreated($event){
		dd($event);
	}
	
	/**
	 * 处理删除前事件
	 */
	public function onUserDeleting($event) {
		Log::info('删除用户前:' . $event->id);
	}
	
	/**
	 * 处理删除后事件
	 */
	public function onUserDeleted($event) {
		Log::info('删除用户后:' . $event->id);
	}
	
	/**
	 * 为订阅者注册监听器
	 *
	 * @param  Illuminate\Events\Dispatcher $events
	 */
	public function subscribe($events) {
		$events->listen(UserCreated::class, UserEventSubscriber::class . '@onUserCreated');
		$events->listen(UserDeleting::class, UserEventSubscriber::class . '@onUserDeleting');
		$events->listen(UserDeleted::class, UserEventSubscriber::class . '@onUserDeleted');
	}
}

  • 注册订阅者
//app\Providers\EventServiceProvider.php

	/**
	 * 要注册的订阅者类
	 *
	 * @var array
	 */
	protected $subscribe = [
		'App\Listeners\UserEventSubscriber',
	];

Ok,好了,现在通过模型插入一条数据,打印数据如下 订阅者模式

通过观察者监听模型事件

  • 创建观察者 在 App 下新建目录 Observers,在该目录下新建观察者类 UserObserver 输入如下代码,都差不多,看一下就知道了,我就只写一个算了,懒
/**
 * Created by PhpStorm.
 * User: xiaoyuan.shu
 * Date: 2019/7/15
 * Time: 16:23
 */

namespace App\Observers;

use App\Models\User;
use Illuminate\Support\Facades\Log;

class UserObserver {
	/**
	 * Handle the user "created" event.
	 *
	 * @param  \App\User $user
	 * @return void
	 */
	public function created(User $user) {
		Log::info('插入到数据库后', $user->toArray());
	}

	/**
	 * Handle the user "updated" event.
	 *
	 * @param  \App\User $user
	 * @return void
	 */
	public function updated(User $user) {
		//
	}

	/**
	 * Handle the user "deleted" event.
	 *
	 * @param  \App\User $user
	 * @return void
	 */
	public function deleted(User $user) {
		//
	}

	/**
	 * Handle the user "restored" event.
	 *
	 * @param  \App\User $user
	 * @return void
	 */
	public function restored(User $user) {
		//
	}

	/**
	 * Handle the user "force deleted" event.
	 *
	 * @param  \App\User $user
	 * @return void
	 */
	public function forceDeleted(User $user) {
		//
	}
}
  • 注册相应的观察者

App\Providers\AppServiceProvider

public function boot()
{
    parent::boot();

    //注册User模型的观察者
    User::observe(UserObserver::class);
}
  • OK了,开始用起来吧。每次对数据库的操作都会走一下这个

总结 : 如果只是监听一两个模型事件,通过静态方法监听方式比较合适;如果仅仅监听系统支持的模型事件,并且要监听多个模型的多个事件,观察者是最佳选择;如果还要在模型类上监听更多系统模型事件之外的自定义事件,则使用订阅者来监听比较合适。