Symfony - 事件和事件監聽器



Symfony 透過其事件排程器元件提供基於事件的程式設計。任何企業應用程式都需要基於事件的程式設計來建立高度可定製的應用程式。事件是物件相互互動的主要工具之一。沒有事件,物件就無法有效地互動。

基於事件的程式設計過程可以概括為:一個被稱為事件源的物件請求中央排程器物件註冊一個事件,例如 user.registered。一個或多個被稱為監聽器的物件請求中央排程器物件監聽特定事件,例如 user.registered。在某個時刻,事件源物件請求中央排程器物件排程事件,例如 user.registered,以及包含必要資訊的事件物件。中央排程器會通知所有監聽器物件有關事件(例如 user.registered)及其事件物件的資訊。

在基於事件的程式設計中,我們有四種類型的物件:事件源、事件監聽器、事件排程器和事件本身。

讓我們編寫一個簡單的應用程式來理解這個概念。

步驟 1 - 建立一個專案,event-dispatcher-example

cd /path/to/dir 
mkdir event-dispatcher-example 
cd event-dispatcher-example 
composer require symfony/event-dispatcher 

步驟 2 - 建立一個類,User

class User { 
   public $name; 
   public $age; 
}  

$user = new User(); 
$user->name = "Jon"; 
$user->age = 25

步驟 3 - 建立一個事件,UserRegisteredEvent

use Symfony\Component\EventDispatcher\Event;  
class UserRegisteredEvent extends Event {
   const NAME = 'user.registered';  
   protected $user;  
   
   public function __construct(User $user) { 
      $this-<user = $user; 
   }  
   public function getUser() { 
      return $this-<user; 
   } 
}  
$event = new UserRegisteredEvent($user);

這裡,UserRegisteredEvent 可以訪問User 物件。事件的名稱為user.registered

步驟 4 - 建立一個監聽器,UserListener

class UserListener { 
   public function onUserRegistrationAction(Event $event) { 
      $user = $event->getUser(); 
         echo $user->name . "\r\n"; 
         echo $user->age . "\r\n"; 
   } 
}  
$listener = new UserListener(); 

步驟 5 - 建立一個事件排程器物件。

use Symfony\Component\EventDispatcher\EventDispatcher;  
$dispatcher = new EventDispatcher(); 

步驟 6 - 使用排程器物件及其方法addListener連線監聽器和事件。

$dispatcher 
   ->addListener( 
      UserRegisteredEvent::NAME,  
      array($listener, 'onUserRegistrationAction'));  

我們還可以新增匿名函式作為事件監聽器,如下面的程式碼所示。

$dispatcher 
   ->addListener( 
      UserRegisteredEvent::NAME,  
      
      function(Event $event) { 
         $user = $event->getUser(); 
         echo $user->name . "\r\n"; 
      }); 

步驟 7 - 最後,使用事件排程器的dispatch方法觸發/排程事件。

 $dispatcher->dispatch(UserRegisteredEvent::NAME, $event);

完整的程式碼清單如下。

main.php

<?php  
   require __DIR__ . '/vendor/autoload.php';  
   use Symfony\Component\EventDispatcher\EventDispatcher; 
   use Symfony\Component\EventDispatcher\Event;  

   class User { 
      public $name; 
      public $age; 
   }  
   class UserRegisteredEvent extends Event { 
      const NAME = 'user.registered';  
      protected $user;  
      
      public function __construct(User $user) { 
         $this->user = $user; 
      }  
      public function getUser() { 
         return $this->user; 
      } 
   }  
   class UserListener { 
      public function onUserRegistrationAction(Event $event) { 
         $user = $event->getUser(); 
         echo $user->name . "\r\n"; 
         echo $user->age . "\r\n"; 
      } 
   } 
   $user = new User(); 
   $user->name = "Jon"; 
   $user->age = 25;  

   $event = new UserRegisteredEvent($user); 
   $listener = new UserListener();  

   $dispatcher = new EventDispatcher();  
   $dispatcher 
      ->addListener( 
         UserRegisteredEvent::NAME, 
         
         function(Event $event) { 
            $user = $event->getUser(); 
            echo $user->name . "\r\n"; 
         });  
   $dispatcher 
      ->addListener( 
         UserRegisteredEvent::NAME, array($listener, 'onUserRegistrationAction'));

   $dispatcher->dispatch(UserRegisteredEvent::NAME, $event); 
?>

結果

Jon 
Jon 
25

Symfony Web 框架有很多事件,可以為這些事件註冊監聽器並相應地進行程式設計。一個示例事件是 kernel.exception,相應的事件是GetResponseForExceptionEvent,它包含響應物件(Web 請求的輸出)。這用於捕獲異常並使用通用錯誤資訊修改響應,而不是向用戶顯示執行時錯誤。

廣告