記錄下學習筆記(Laravel 中的事件監聽)

NaturalGao發表於2019-05-11

從字面上就可以看出來,無非就是監聽一個事件。

例句一個物流發貨的場景:我有個小程式商城,使用者下單後需要在後臺發貨,發完貨後我想在微信傳送個模組通知提示使用者,我想了想使用者不登入微信或者把訊息提示關閉了,那豈不是不能實時通知使用者已經發貨了,我決定再加個簡訊通知使用者。有了模組通知,簡訊通知後我還嫌不夠...然後我繼續加.... 通常我們會這麼寫:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class OrderController extends Controller
{
    public function sendGoods()
    {
        //@todo:發貨邏輯
        //@todo:模組通知邏輯
        //@todo:簡訊通知邏輯
        //@todo:等等....
    }
}

這樣寫不是不可以,但是邏輯功能越來越多,控制器只會變得臃腫起來,後期不便於維護。這時候可能會有人說,那我可以封裝起來啊,是的,你可以封裝起來,然後就可以用簡短的程式碼來實現。但是實際專案中,會涉及多人開發,這樣就不方便了。所以推薦使用laravel自帶的“事件監聽“...

3.1 開啟終端->切換到專案根目錄->使用artisan命令建立事件監聽檔案

php artisan make:event OrderEvent

執行完命令,發現 app/Events 目錄下多了個 OrderEvent.php 檔案

記錄下學習筆記(Laravel 中的事件監聽)

我們可以開啟看看...

<?php

namespace App\Events;

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

class OrderEvent
{
    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 App\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class OrderEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

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

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

3.2 繫結事件

開啟 app/Providers/EventServiceProvider.php 檔案,找到 成員屬性 listen下:

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

把事件關聯起來,修改為:

    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        'App\Events\OrderEvent' => [
            'App\Listeners\sendModel',
            'App\Listeners\sendPhone',
        ]
    ];

接著開啟終端,執行 artisan 命令 生成 監聽檔案

php artisan event:generate

然後我們可以在 app/Listeners 檔案下發現多了兩個檔案

記錄下學習筆記(Laravel 中的事件監聽)

開啟這兩個檔案,依次修改為:

sendModel.php:

<?php

namespace App\Listeners;

use App\Events\OrderEvent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

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

    /**
     * Handle the event.
     *
     * @param  OrderEvent  $event
     * @return void
     */
    public function handle(OrderEvent $event)
    {
        $user = $event->user; // @todo: 當前使用者
        //@todo:傳送訊息模板邏輯
        dump('傳送訊息模板成功');
    }
}

sendPhone.php:

<?php

namespace App\Listeners;

use App\Events\OrderEvent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

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

    /**
     * Handle the event.
     *
     * @param  OrderEvent  $event
     * @return void
     */
    public function handle(OrderEvent $event)
    {
        $user = $event->user; // @todo: 當前使用者
        //@todo:傳送簡訊訊息
        dump('傳送簡訊訊息成功');
    }
}

3.3 最後我們再開啟 OrderController.php 修改為:

<?php
namespace App\Http\Controllers;
use App\Events\OrderEvent;
use App\User;
use Illuminate\Http\Request;
class OrderController extends Controller
{
    public function sendGoods()
    {
        $user = User::find(1);
        //@todo:發貨邏輯
        dump('發貨成功!!');
        event(new OrderEvent($user));
    }
}

3.4 繫結路由

Route::get('/sendGoods','OrderController@sendGoods');

3.5 訪問路由結果:

記錄下學習筆記(Laravel 中的事件監聽)

這樣是不是簡單,便於維護了許多呢... 還不會的小夥伴趕緊去試試吧!如果對你有幫助,請給個贊,謝謝!

相關文章