什么是事件,可以理解为当某个行为执行后发生的事,即为事件:
一个事件,可以拥有多个监听器,一个监听器只能监听一个事件。一个类可以监听多个事件即为事件订阅器。
而观察者则是事件的实现。它存在于事件之上,通俗讲,事件或者事件订阅器是通过观察者模式来实现的。
而监听只也是运用了设计模式中的单一职责则模式: 一个类只做一件事。

事件:

传统的控制器里会把用户注册+发送邮件+发送信息的逻辑给写到一起,这样造成了代码的偶合度,单从代码的维护度来说不利于后期维护。所以事件的产生就是为了把逻辑抽离出来。各司其职。让控制器更干净的做它的事。

监听器:

监听器是负责监听某个事件发生。然后它负责处理某项事物。想象一下,用户注册成功后,会产生一个注册成功的事件,而这个监听器是负责发送邮件的,它就会根据用户的邮箱给用户发送一条注册成功的邮件。
根据上面所描述的。一个监听器只干一件事。你可以为一个事件类注册多个监听器,让这些监听器分别为用户发送邮箱和手机信息。甚至把用户注册信息写入至日志。
laravel事件、监听器、事件订阅器、观察者模式 - 图1

介绍了这么多,你已经迫不及待想写代码了吧。

创建事件与监听器

  1. 现在为我们用户注册成功后,创建一个事件

    1. php artisan make:event UserStoreProcess
  2. 为事件创建属于它自己监听器,这个监听器,我们用来发送邮件给用户

    php artisan make:listener SendSuccessfullyEmail --event=UserStoreProcess
    
  3. 这个监听器我们用来发送信息给用户手机

    php artisan make:listener SendSuccessfullyMessage --event=UserStoreProcess
    

    上面的命令执行完之后,你会发现你的 app 目下生成了两个文件夹 : EventsListeners ,目录里就是刚刚生成的事件类与监听器。

为事件注册监听器

编辑 app/Providers/EventServiceProvider ,加入以下内容

    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],

     //用户注册成功事件
        UserStoreProcess::class=>[
           SendSuccessfullyEmail::class,
            SendSuccessfullyMessage::class
        ]
    ];

这样就成功为事件注册了监听器

编辑事件类

即然我们创建的事件是为了给用户发送邮箱或手机号的。那么,我们应该在事件类里初始化一个User模型的实例。方便我们在监听器里获取模型的邮箱与手机号。
UserStoreProcess类:

use App\Models\User;

class UserStoreProcess {
    use Dispatchable, InteractsWithSockets, SerializesModels;

  public User $user;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user) {

      $this->$user = $user;
    }
}

这样,调用事件时,就可以把当前注册的user实例传给事件类,事件类与监听器协作时,监听器就能拿到事件实例的一个字段属性user.

在编辑监听者之前,我们先来创建一个Mail 类:

php artisan make:mail UserSuccessfully --markdown=emails.users.successfully

运行此命令后,会生成 app/Mail/UserSuccessfully ,同时也会生成一个邮件的渲染模板:resources/views/emails/users/successfully.blade.php

编辑这邮件类

use App\Models\User;
class UserSuccessfully extends Mailable {
    use Queueable, SerializesModels;

    public $user;

    public function __construct(User $user) {
        $this->user = $user;
    }

    public function build() {
        return $this->markdown('emails.users.successfully',[
            'user'=>$this->user,
        ]);
    }
}

上面的User实例,会在监听者里调用此类时传入。方便在模板里调用$user 的属性

编辑监听者

为了方便演示,就只展示发送邮件的过程,编辑 SendSuccessfullyEmail

use Illuminate\Support\Facades\Mail;

class SendSuccessfullyEmail {
//...

      public function handle(UserStoreProcess $event) {

        Mail::to($event->user->email)->send(new UserSuccessfully($event->user));

    }

}

当然,这只是代码示例。真实情况下你得在.env配置文件里配置你的邮箱。这样才能正常发送邮箱给用户。
这个功能无非就是代替了手动发送邮件的功能。同理的。给用户发送手机信息也是同样的方法。这里就不再做演示

如何触发

UserController 创建用户方法中,如下代码

class UserController extends Controller {

            public function store() {
          //验证用户
        //创建用户
        event(new UserStoreProcess($user))

          //返回值
      }

}

这样,在用户创建成功后,将会把创建的用户实例传给事件类,让监听器来发送邮件和信息等操作。

事件订阅者

下面来讲讲事件订阅者,订阅者和事件监听是一个概念,只不过是一个监听器监听多个事件,哪个事件发生后,再处理哪个事件,至于用事件监听还是事件订阅者,根据你的个人习惯来

laravel事件、监听器、事件订阅器、观察者模式 - 图2
和创建事件与监听器方法一样。这里不过多赘述.下面来说下配置方法:

假现在有一个订阅者(监听器),监听登录成功事件,与退出登录事件。要求对对应事件做出监听处理
下面代码是引用自 laravel 中文社区

<?php

namespace App\Listeners;

class UserEventSubscriber
{
    /**
     * 处理用户登录事件。
     */
    public function handleUserLogin($event) {}

    /**
     * 处理用户退出事件。
     */
    public function handleUserLogout($event) {}

    /**
     * 为订阅者注册侦听器。
     *
     * @param  \Illuminate\Events\Dispatcher  $events
     * @return void
     */
    public function subscribe($events)
    {
        $events->listen(
            'Illuminate\Auth\Events\Login',
            [UserEventSubscriber::class, 'handleUserLogin']
        );

        $events->listen(
            'Illuminate\Auth\Events\Logout',
            [UserEventSubscriber::class, 'handleUserLogout']
        );
    }
}

上面的 Login 类与 Logout 类也可以定义为 你自己的事件类

注册事件订阅者

<?php

namespace App\Providers;

use App\Listeners\UserEventSubscriber;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * 应用的事件监听器映射
     *
     * @var array
     */
    protected $listen = [
        //
    ];

    /**
     * 被注册的订阅者类
     *
     * @var array
     */
    protected $subscribe = [
        UserEventSubscriber::class,
    ];
}

观察者

如果你想在模型中监听多个事件。这时就可以用到观察者

创建观察者

php artisan make:observer UserObserver --model=User

这样观察者即与模型关联起来

注册观察者

laravel事件、监听器、事件订阅器、观察者模式 - 图3
编辑 app/Providers/AppSericeProvider.php

<?php

namespace App\Providers;

use App\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 运行所有应用.
     *
     * @return void
     */
    public function boot()
    {

         // 为 User 模型注册观察者
        User::observe(UserObserver::class);
    }

    /**
     * 注册服务提供.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

观察者的使用方法是和事件一个道理。前面说过。事件的实现是在Observer的之下的。怎么用看你自己。