基于laravel的事件监听实例

1,998 阅读2分钟

在分享这篇文章的时候,我假设你已经对laravel有一定的理解。而且已经知道什么是观察者模式。如果你还不能理解什么是观察者模式,那么我建议你在读这篇文章的时候先去看看观察者模式的概念。这样会更好地让你理解代码,和读懂代码。

在现实的开发中,我们经常会碰到这样的需求。产品经理说,要在用户注册的时候发送一条信息给用户进行通知。那么在传统的做法里面我们可能会在注册的方法里面修改逻辑,直接在其原本的方法上面进行修改或者增加更多的逻辑。虽然说这样的写法可以实现功能。但是在代码的简洁度,以及违反了开闭原则。当然我们在一些小项目中为了追求速度,有时候怎么方便怎么写也是无可厚非。不过如果有一天项目的体系大了那么我们终究还是要在合适的地方用合适的模式去解决我们实际业务的问题。

下面我们就直接以来进行实战吧。

首先找到\app\Providers\EventServiceProvider.php文件。在此文件中我们加入我们自己的事件监听

<?php

namespace App\Providers;

use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        // 用户注册后的事件
        'App\Events\Register' => 
            // 发送短信
            'App\Listeners\SendSms',
        ],
    ];
}

接着我们需要运行

php artisan event:generate

上面这一句话运行后,laravel 会为你在系统目录中的 App\Event\目录中生成一个Register的php文件。这个文件就是系统自动帮你生成的事件文件。另外也会生成一个SendSms文件在你的App\Listeners中。细心的你很快就会发现其生成的目录以及文件就是你最初在laravel的事件服务提供的数组中注册的内容。

接下来我们看下我们生成事件注册文件

<?php

namespace App\Events;

use App\User;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;

class Register extends Event
{
    use SerializesModels;

    public $user;

    /**
     * Create a new event instance.
     *
     * @param      User  $user
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

在上面的事件中,我们定义了一个$user去接受新注册的用户信息,并且通过实例化对象的时候把用户信息存放起来。正如你所看到的,该事件类不包含任何特定逻辑,只是一个存放 User 对象的容器

接下来,让我们看看我们的示例事件的监听器,事件监听器在 handle 方法中接收事件实例,event:generate 命令将会自动在 handle 方法中导入合适的事件类和类型提示事件。在 handle 方法内,你可以执行任何需要的逻辑以响应事件:

<?php

namespace App\Listeners;

use App\Events\Register;

class SendSms
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param Register  $event
     * @return void
     */
    public function handle(Register $event)
    {
        // Access the order using $event->user...
          //获取新注册的用户id
          $uid = $event->uid
           //调用发送信息接口
          Sms::send($uid,['register']);
    }
}

最后我们怎么触发事件呢?只需要在对应逻辑位置中通过event函数调用对应的事件方法即可

<?php
namespace App\Htt\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function register(Request $request)
    {
        //获取参数
        //验证参数
        //写入数据库
        //return 注册信息
        //注册完成后调用放信息(其中$user是注册后返回的用户信息)
        event(new Register($user));

    }
}