事件類通常被保存在 app/Events 目錄下,而它們的處理程序則被保存在 app/Handlers/Events 目錄下。
事件的創建
下面我們用artisan來創建一個事件,比如叫CqhTestEvent
php artisan make:event CqhTestEvent
生成的事件如下
<?php namespace App\Events; use App\Events\Event; use Illuminate\Queue\SerializesModels; class CqhTestEvent extends Event { use SerializesModels; /** * Create a new event instance. * * @return void */ public function __construct() { } }
事件的觸發
- 方法一:可以直接用event()函數來觸發事件,如下
event(new CqhTestEvent());
- 方法二:也可以用Event facade來觸發,如下
$response = Event::fire(new CqhTestEvent());
fire 方法返回一個響應的數組,讓你可以用來控制你的應用程序接下來要有什么反應。
事件的處理
事件處理的方法可以分別兩種,分別是類和閉包。
這里我的處理類中叫CqhTestEventHandler,下面我們來用artisan來創建這個處理類
php artisan handler:event CqhTestEventHandler --event=CqhTestEvent
然后在app/Handlers/Events文件下會生成CqhTestEventHandler.php,結構如下
<?php namespace App\Handlers\Events; use App\Events\CqhTestEvent; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldBeQueued; class CqhTestEventHandler { /** * Create the event handler. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param CqhTestEvent $event * @return void */ public function handle(CqhTestEvent $event) { // } }
然后我們在handle方法里加上一句
public function handle(CqhTestEvent $event) { // echo 'chenqionghe的事件被處理了'; }
這樣,我們的簡單的對應事件的處理就完成了
然后, 要指定相應事件的處理類也有兩種方式,事件服務中指定和Event::listen()方法指定
方法一:指定要處理的類
- 在EventServiceProvider的boot方法中指定要處理
然后,我們需要把這個事件注冊到系統服務里邊,在app/Providers文件夾里有個EventServiceProvider.php我們,打開他,找到相應的listen屬性,加上
如下
<?php namespace App\Providers; use Illuminate\Contracts\Events\Dispatcher as DispatcherContract; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { /** * The event handler mappings for the application. * * @var array */ protected $listen = [ 'event.name' => [ 'EventListener', ], //在這里加上 'App\Events\CqhTestEvent' => [ 'App\Handlers\Events\CqhTestEventHandler', ], ]; ... }
在這里把事件給添加上,並定義相應處理事件的類(注意,這里是可以針對事件使用多個處理類的,只需要在數組里加上就行了)
- 在Event::listen()方法中指定
Event::listen('App\Events\CqhTestEvent', 'App\Handlers\Events\CqhTestEventHandler');
注意:指定類的時候和路由是一個原理,事件處理默認會調用CqhTestEventHandler的handle方法,如果要指定相應方法,可以加上@方法名,如CqhTestEventHandler@doEvent
只需要在調用事件之前指定即可
方法二:用閉包來處理事件
我們不可以直接用閉包來處理某個事件,只要在觸發事件前定義就可以了,如在EventServiceProvider的boot方法里
Event::listen('App\Events\CqhTestEvent', function($event) { // 處理事件... });
如果定義了多個這樣的事件處理,在觸發事件后他們都會一並被執行,就相當於jquery里邊的bind方法如,
public function getTest() { Event::listen('App\Events\CqhTestEvent', function($event) { echo '觸發事件1'; }); Event::listen('App\Events\CqhTestEvent', function($event) { echo '觸發事件2'; }); Event::listen('App\Events\CqhTestEvent', function($event) { echo '觸發事件3'; }); event(new CqhTestEvent()); }
上面注冊了CqhTestEvent事件的三個處理,運行結果如下
觸發事件1觸發事件2觸發事件3
同樣,和jquery一樣,有時候你會希望停止繼續傳遞事件到其他監聽器。你可以通過從處理程序return false 來做到這件事
public function getTest() { Event::listen('App\Events\CqhTestEvent', function($event) { echo '觸發事件1'; }); Event::listen('App\Events\CqhTestEvent', function($event) { echo '觸發事件2'; return false; }); Event::listen('App\Events\CqhTestEvent', function($event) { echo '觸發事件3'; }); event(new CqhTestEvent()); }
運行結果如下
觸發事件1觸發事件2