国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

事件系統(tǒng)

事件系統(tǒng)


事件系統(tǒng)

事件系統(tǒng)介紹

Laravel 的事件提供了一個簡單的觀察者實現(xiàn),能夠訂閱和監(jiān)聽應用中發(fā)生的各種事件。事件類通常存放在 app/Events 目錄下,而這些事件類的監(jiān)聽器則存放在 app/Listeners 目錄下。如果在你的應用中你沒有看到這些目錄,不用擔心,它們會在你使用 Artisan 控制臺命令生成事件與監(jiān)聽器的時候自動創(chuàng)建。

事件系統(tǒng)為應用各個方面的解耦提供了非常棒的方法,因為單個事件可以擁有多個互不依賴的監(jiān)聽器。舉個例子,你可能希望每次訂單發(fā)貨時向用戶推送一個 Slack 通知。你可以簡單地發(fā)起一個可以被監(jiān)聽器接收并轉化為 Slack 通知的 OrderShipped 事件,而不是將訂單處理代碼和 Slack 通知代碼耦合在一起。

注冊事件和監(jiān)聽器

Laravel 應用中的 EventServiceProvider 為注冊所有的事件監(jiān)聽器提供了一個便利的場所。其中, listen 屬性包含了所有事件 (鍵) 以及事件對應的監(jiān)聽器 (值) 的數(shù)組。當然,你可以根據應用的需要,添加多個事件到 listen 屬性包含的數(shù)組中。舉個例子,我們來添加一個 OrderShipped 事件:

/**
 * 應用程序的事件監(jiān)聽器映射
 *
 * @var array
 */
 protected $listen = [ 
    'App\Events\OrderShipped' => [    
        'App\Listeners\SendShipmentNotification',  
        ],
    ];

生成事件 & 監(jiān)聽器

當然,手動創(chuàng)建事件和監(jiān)聽器的文件是件麻煩事。而在這里,你只需要將監(jiān)聽器和事件添加到 EventServiceProvider 中,而后使用 event:generate 命令。這個命令會生成在 EventServiceProvider 中列出的所有事件和監(jiān)聽器。當然,已經存在的事件和監(jiān)聽器將保持不變:

php artisan event:generate

手動注冊事件

通常,事件是在 EventServiceProvider$listen 數(shù)組中注冊;然而,你也可以在 EventServiceProviderboot 方法中手動注冊基于閉包的這些事件:

/**
 * 注冊應用中的其它事件
 *
 * @return void
 */
 public function boot(){ 
    parent::boot();    
    Event::listen('event.name', function ($foo, $bar) {  
          //   
       });
  }

通配符事件監(jiān)聽器

你可以在注冊監(jiān)聽器時使用 * 作為通配符參數(shù),這樣可以在同一個監(jiān)聽器上捕獲多個事件。通配符監(jiān)聽器接收事件名作為其第一個參數(shù),并將整個事件數(shù)據數(shù)組作為其第二個參數(shù):

Event::listen('event.*', function ($eventName, array $data) { 
   //
});

定義事件

事件類是一個保存與事件相關信息的容器。例如,假設我們生成的 OrderShipped 事件接收一個 Eloquent ORM 對象:

<?php
    namespace App\Events;
    use App\Order;
    use Illuminate\Queue\SerializesModels;
    class OrderShipped{ 
       use SerializesModels;    
       public $order;    
     /**
     * 創(chuàng)建一個事件實例。
     *
     * @param  \App\Order  $order
     * @return void
     */   
    public function __construct(Order $order) 
       {    
           $this->order = $order;  
        }
    }

如你所見,這個事件類中沒有包含其它邏輯。它只是一個購買的 Order 的實例的容器。如果使用 PHP 的 serialize 函數(shù)序列化事件對象,事件使用的 SerializesModels trait 將會優(yōu)雅地序列化任何 Eloquent 模型。

定義監(jiān)聽器

接下來,讓我們看一下例子中事件的監(jiān)聽器。事件監(jiān)聽器在 handle 方法中接收實例。 event:generate 命令會自動加載正確的事件類,并且在 handle 方法中加入事件的類型提示。在 handle 方法中,你可以執(zhí)行任何必要的響應事件的操作:

<?php
    namespace App\Listeners;
    use App\Events\OrderShipped;
    class SendShipmentNotification{  
      /**
     * 創(chuàng)建事件監(jiān)聽器。
     *
     * @return void
     */  
   public function __construct()
      {      
        // 
      }  
     /**
     * 處理事件。
     *
     * @param  \App\Events\OrderShipped  $event
     * @return void
     */ 
    public function handle(OrderShipped $event) 
       {    
           // 使用 $event->order 來訪問 order ...  
        }
     }

{tip} 你的事件監(jiān)聽器也可以在構造函數(shù)中加入任何依賴關系的類型提示。所有的事件監(jiān)聽器都是通過 Laravel 的 服務容器 來解析的,因此所有的依賴都將會被自動注入。

停止事件傳播

有時,你可以通過在監(jiān)聽器的 handle 方法中返回 false 來阻止事件被其它的監(jiān)聽器獲取。

事件監(jiān)聽器隊列

如果你的監(jiān)聽器中要執(zhí)行諸如發(fā)送電子郵件或進行 HTTP 請求等比較慢的任務,你可以選擇將其丟給隊列處理。在開始使用隊列監(jiān)聽器之前,請確保在你的服務器或者本地開發(fā)環(huán)境中能夠 配置隊列 并啟動一個隊列監(jiān)聽器。

要指定監(jiān)聽器啟動隊列,你可以在監(jiān)聽器類中增加 ShouldQueue 接口。由 Artisan 命令 event:generate 生成的監(jiān)聽器已經將此接口導入到當前命名空間中,因此你可以直接使用:

<?php
    namespace App\Listeners;
    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;
    class SendShipmentNotification implements ShouldQueue{
        //
     }

就是這個!當這個監(jiān)聽器被事件調用時,事件調度器會自動使用 Laravel 的 隊列系統(tǒng)。如果在隊列中執(zhí)行監(jiān)聽器時沒有拋出異常,任務會在執(zhí)行完成后自動從隊列中刪除。

自定義隊列連接 & 隊列名稱

如果你想要自定義事件監(jiān)聽器所使用的隊列的連接和名稱,你可以在監(jiān)聽器類中定義 $connection$queue$delay 屬性:

<?php
    namespace App\Listeners;
    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;
    class SendShipmentNotification implements ShouldQueue{
       /**
     * The name of the connection the job should be sent to.
     *
     * @var string|null
     */  
   public $connection = 'sqs'; 
     /**
     * The name of the queue the job should be sent to.
     *
     * @var string|null
     */   
   public $queue = 'listeners';   
     /**
     * The time (seconds) before the job should be processed.
     *
     * @var int
     */ 
    public $delay = 60;
  }

手動訪問隊列

如果你需要手動訪問監(jiān)聽器下面隊列任務的 deleterelease 方法,你可以通過使用 Illuminate\Queue\InteractsWithQueue trait 來實現(xiàn)。這個 trait 會默認加載到生成的監(jiān)聽器中,并提供對這些方法的訪問:

<?php
    namespace App\Listeners;
    use App\Events\OrderShipped;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    class SendShipmentNotification implements ShouldQueue{
        use InteractsWithQueue;  
      /**
     * 處理事件。
     *
     * @param  \App\Events\OrderShipped  $event
     * @return void
     */   
    public function handle(OrderShipped $event)
        {     
           if (true) { 
                  $this->release(30);  
                  }  
          }
     }

處理失敗任務

有時事件監(jiān)聽器的隊列任務可能會失敗。如果監(jiān)聽器的隊列任務超過了隊列中定義的最大嘗試次數(shù),則會在監(jiān)聽器上調用 failed 方法。 failed 方法接收事件實例和導致失敗的異常作為參數(shù):

<?php
    namespace App\Listeners;use App\Events\OrderShipped;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Contracts\Queue\ShouldQueue;
    class SendShipmentNotification implements ShouldQueue{ 
       use InteractsWithQueue;   
       /**
     * 處理事件。
     *
     * @param  \App\Events\OrderShipped  $event
     * @return void
     */   
    public function handle(OrderShipped $event) 
       {    
           // 
        }  
    /**
     * 處理失敗任務。
     *
     * @param  \App\Events\OrderShipped  $event
     * @param  \Exception  $exception
     * @return void
     */  
    public function failed(OrderShipped $event, $exception)
        {   
             //  
         }
     }

分發(fā)事件

如果要分發(fā)事件,你可以將事件實例傳遞給輔助函數(shù) event 。該輔助函數(shù)將會把事件分發(fā)到所有該事件相應的已經注冊了的監(jiān)聽器上。 event 輔助函數(shù)可以全局使用,你可以在應用中的任何位置進行調用:

<?php
    namespace App\Http\Controllers;
    use App\Order;use App\Events\OrderShipped;
    use App\Http\Controllers\Controller;
    class OrderController extends Controller{   
       /**
     * 將傳遞過來的訂單發(fā)貨
     *
     * @param  int  $orderId
     * @return Response
     */   
   public function ship($orderId)
       {     
          $order = Order::findOrFail($orderId);        
          // 訂單發(fā)貨邏輯 ...        
          event(new OrderShipped($order));    
        }
       }

{tip} 在測試時,只需要斷言特定事件被分發(fā),而不需要真正地觸發(fā)監(jiān)聽器。 Laravel 的 內置測試輔助函數(shù) 可以輕松做到這一點。

事件訂閱者

編寫事件訂閱者

事件訂閱者是可以在自身內部訂閱多個事件的類,即能夠在單個類中定義多個事件處理器。訂閱者應該定義一個 subscribe 方法,這個方法接收一個事件分發(fā)器實例。你可以調用給定事件分發(fā)器上的 listen 方法來注冊事件監(jiān)聽器:

<?php
    namespace App\Listeners;
    class UserEventSubscriber{  
      /**
     * 處理用戶登錄事件。
     */   
   public function onUserLogin($event) {}    
      /**
     * 處理用戶注銷事件。
     */   
   public function onUserLogout($event) {}   
    /**
     * 為訂閱者注冊監(jiān)聽器
     *
     * @param  \Illuminate\Events\Dispatcher  $events
     */   
    public function subscribe($events) 
       {      
         $events->listen(         
            'Illuminate\Auth\Events\Login',           
            'App\Listeners\UserEventSubscriber@onUserLogin'       
           );        
          $events->listen(         
             'Illuminate\Auth\Events\Logout',            
             'App\Listeners\UserEventSubscriber@onUserLogout'    
              );  
         }
      }

注冊事件訂閱者

在編寫完訂閱者之后,就可以通過事件分發(fā)器對訂閱者進行注冊。你可以在 EventServiceProvider 中的 $subscribe 屬性中注冊訂閱者。例如,讓我們將 UserEventSubscriber 添加到數(shù)組列表中:

<?php
    namespace App\Providers;
    use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
    class EventServiceProvider extends ServiceProvider{   
     /**
     * 應用中事件監(jiān)聽器的映射。
     *
     * @var array
     */   
   protected $listen = [  
         //  
        ];  
     /**
     * 需要注冊的訂閱者類。
     *
     * @var array
     */ 
    protected $subscribe = [ 
           'App\Listeners\UserEventSubscriber',   
          ];
      }
本文章首發(fā)在 LearnKu.com 網站上。