事件就是在特意時間、特定地點、發生的特定行爲。例如:刪除某個用戶帖子這個行爲後,要經過站短髮送信息給帖子所屬的用戶。這裏就有刪除帖子事件,發站短是事件後處理。php
事件機制是一種很好的應用解耦方式,一個事件能夠擁有多個互補依賴的監聽器。如用戶對某個帖子進行回帖操做後,就能夠觸發給用戶發積分、加金幣、清除帖子詳情頁對varnish緩存、給樓主發送push提醒、同步數據到一uid取模分表對業務上... 。回帖後須要處理對這些業務互補干擾,分屬在不一樣模塊,一些服務對業務邏輯還能夠進行異步處理,如給樓主發送push提醒。因此事件機制能夠解藕,讓類承擔單一職責,代碼變的更清晰、易於維護。laravel
laravel事件機制主要有註冊事件、事件、監聽器、事件分發等部分組成。數組
在模塊目錄下等providers目錄下類EventServiceProvider.php的$listen數組包含全部事件(鍵)和事件所對應監聽器(值)來註冊事件的監聽器,例如咱們添加一個添加課程是給用戶發送站短緩存
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ LessonJoined::class => [NotifyUserForLessonJoined::class] ];
將事件和監聽器放在服務提供者EventServiceProvider.php以後,可使用命令event:generate在模塊下的events、listens目錄下生成相對於的事件和監聽器app
在模塊的events目錄中新增事件類less
<?php namespace Education\LiveLesson\Events; use Meijiabang\Events\Event; class LessonJoined extends Event { }
在模塊的listeners目錄中新增監聽類異步
<?php namespace Education\LiveLesson\Listeners; use Meijiabang\Support\Exception\ExceptionCode; use Education\LiveLesson\Events\LessonJoined; use Education\LiveLesson\Services\LessonService; use Illuminate\Support\Facades\Log; use Meijiabang\Events\Listener; use User\Notice\Services\NoticeService; class NotifyUserForLessonJoined extends Listener { /** * @var string */ protected $content = '參加《[name]》課程成功,記得按時參加課程>'; /** * @param LessonJoined $event * @return bool */ public function handle(LessonJoined $event) { $model = $event->getModel(); if (!is_null($model)) { $noticeService = new NoticeService($model->uid, NoticeService::LIVELESSON_JOIN); $lessonName = app(LessonService::class)->find($model->relation_id)->title; $serviceResult = $noticeService->send([ 'lesson_id' => $model->relation_id, 'uid' => $model->uid, 'content' => str_replace('[name]', $lessonName, $this->content), ]); if (ExceptionCode::SUCCESS != $serviceResult->getCode()) { Log::info(date("Y-m-d H:i:s") . ' Failed to send live-lesson-join message to ' . $model->uid); return true; } } return true; } }
若是要分發事件,你能夠將事件實例傳遞給輔助函數 event。這個函數將會把事件分發到全部已經註冊的監聽器上。由於輔助函數 event 是全局可訪問的,因此你能夠在應用中的任何地方調用它:ide
event(new LessonJoined($privilege));