Laravel5.8 使用事件监听器及订阅者完成功能需求

在项目中实现用户签到与积分兑换

用户签到:签到成功后需要给用户增加积分、需要在另一个积分记录表添加一条记录
用户兑换:兑换后需要给用户减少相应积分,同样需要在积分记录表添加一条记录

很明显事件监听用在这很合适,监听签到功能、监听兑换功能

一开始我创建了签到的事件: Sign

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        //签到后要给用户增加财富,财富消费记录表要记录
         'App\Events\Sign' => [
                  'App\Listeners\UserTreasure',
                  'App\Listeners\TreasureLogs',
            ],
    ];

执行命令 php artisan event:generate
在监听器中写相应的逻辑时想到 用户兑换的事件和签到非常类似,于是注册了兑换事件Conver:

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        //签到后要给用户增加财富,财富消费记录表要加条记录
        'App\Events\Sign' => [
            'App\Listeners\UserTreasure',
            'App\Listeners\TreasureLogs',
        ],
        //兑换积分后给用户减少财富,财富消费记录表要加条记录
        'App\Events\Conver' => [
            'App\Listeners\UserTreasure',
            'App\Listeners\TreasureLogs',
        ],
    ];

如上代码我之所以在兑换积分上用了同样的监听器,就是因为其实他们的业务功能极度类似,可是这样写不行啊,
这时候由两种解决方案:

  1. 积分兑换的监听器换个名字,单独写。
  2. 想办法在一个监听器中区分不同事件
    第一个方案不用说也知道,创建一堆业务功能类似的文件不是程序员的风格。

此时事件订阅者出场:

<?php
namespace App\Providers;

use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        //签到后要给用户增加财富,财富消费记录表要记录
//        'App\Events\Sign' => [
//            'App\Listeners\UserTreasure',
//            'App\Listeners\TreasureLogs',
//        ],
        //兑换积分后给用户减少财富,财富消费记录表要加条记录
//        'App\Events\Conver' => [
//            'App\Listeners\UserTreasure',
//            'App\Listeners\TreasureLogs',
//        ],
    ];

    // 订阅者
    protected $subscribe = [
        'App\Listeners\UserTreasure',
        'App\Listeners\TreasureLogs',
    ];

用了订阅者就不需要上面的事件啦,你可能会奇怪一下,貌似没有了事件,我的签到和兑换事件怎么触发呢?
既然把监听器换成了订阅者,就进入一个看看

<?php
namespace App\Listeners;

use App\Events\Conver;
use App\Events\Sign;

class TreasureLogs
{
    public function subscribe($events)
    {
        $events->listen(
            Sign::class,
            'App\Listeners\TreasureLogs@signLogs'
        );

        $events->listen(
            Conver::class,
            'App\Listeners\TreasureLogs@converLogs'
        );
    }

    public function signLogs($events)
    {
         // 触发Sign事件执行
    }

    public function converLogs($events)
    {
       // 触发Conver事件执行
    }

}

这样就好用多了!

个人博客 乘风御上 请多多支持!

聪聆
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 3

这个功能5.8才有吗

4年前 评论
聪聆

@lovecn 呃,不是很早就有了

4年前 评论

没有事件,怎么调用呢?

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!