Laravel使用event事件

一、需求场景

在常见的业务中,比如我们要记录一个接口的最终处理结果记录到日志里,使用event就可以把记录日志的业务逻辑放在一个处理方法中,使得代码中的业务逻辑更明确。

二、配置监听

监听配置文件:app\EventServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use App\Events\TestEvent;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
//        Registered::class => [
//            SendEmailVerificationNotification::class,
//        ],
        'App\Events\SendEvent' => [
//            'App\Listeners\PayEventListener',
            'App\Listeners\SendEventListener',
        ],
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        //
    }
}

其中,$listen属性中:

  • App\Events\ArticleEvent:是在App\Events目录下新建一个事件(ArticleEvent.php),控制器等的业务逻辑中实例化的是该文件。

  • App\Listeners\PayEventListener:是在App\Listeners目录下新建一个监听器(PayEventListener.php)

注意:单个事件可以配置多个监听器(处理业务逻辑,如发送邮件,发送短信)。

配置多个监听器的写法:

    protected $listen = [
        'App\Events\SendEvent' => [
            'App\Listeners\SendEventListener',
            'App\Listeners\PayEventListener',
        ],
    ];

表明一个调用ArticleEvent事件,会执行两个监听器。如果有多个监听器,会按照上方代码快中的数组下标依次进行处理。

三、生成事件及监听文件

执行命令:php artisan event:generate

会在Events目录下生成SendEvent.php,在Listenters目录下生成SendEventListener.php两个文件。

SendEvent.php(事件)中,用来接收调用端传过来的参数。

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class SendEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;


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

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

可以定义一个属性:

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class SendEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $name;

    /**
     * Create a new event instance.
     *
     * @param $username
     */
    public function __construct($username)
    {
        $this->name = $username; 
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

SendEventListener.php(监听器)中,可以通过$event->name来接收参数,从而进行相应的业务逻辑处理:

<?php

namespace App\Listeners;

use App\Events\SendEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;

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

    /**
     * Handle the event.
     *
     * @param  SendEvent  $event
     * @return void
     */
    public function handle(SendEvent $event)
    {
        echo $event->name; 
        Log::info('事件1监听测试'.date('Y-m-d H:i:s'));
    }
}

四、调用事件

在控制器中,直接实例化事件类就行,也可以传相应的参数。:

public function testEvent(){
//        Log::info(date('Y-m-d H:i:s').'我进来了');
        $username = '写代码的光头强';
        event(new SendEvent());
//        Log::info(date('Y-m-d H:i:s').'我结束了');
    }

至此,简单的event事件调用就实现了。以上都是带代码同步进行的。

同步执行顺序:控制器——事件——监听器1——监听器2——控制器结束

在这里插入图片描述
如果使用异步,可以配合着队列来用。

end~

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 2

试试 github.com/ctfang/laravel-watch

2年前 评论

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