Laravel使用event事件

tomlibao發表於2021-06-02

在常見的業務中,比如我們要記錄一個介面的最終處理結果記錄到日誌裡,使用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 協議》,轉載必須註明作者和本文連結

相關文章