基於laravel的事件監聽例項

逍遙俠發表於2018-12-27

在分享這篇文章的時候,我假設你已經對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));

    }
}複製程式碼


相關文章