Symfony事件和EventListener


Symfony通过其 EventDispatcher 组件提供基于事件的编程。任何企业应用程序都需要基于事件的编程来创建高度可定制的应用程序。事件是对象互相交互的主要工具之一。没有事件,对象不会有效地交互。

基于事件的编程过程可以概括为: - 称为 事件源 的对象要求中央调度器对象注册一个事件,比如user.registered。一个或多个称为侦听器的对象询问中央调度器对象是否想要侦听特定事件,如user.registered。在某个时间点,事件源对象要求中央调度器对象派发事件,比如说user.registered和Event对象以及必要的信息。中央调度器通知所有监听器对象有关事件,比如说user.registered和它的Event *对象。

在基于事件的编程中,我们有四种类型的对象:Event Source,Event Listener,Even Dispatcher和Event本身。

让我们写一个简单的应用程序来理解这个概念。

第1步 - 创建一个项目, 事件调度程序示例

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步 - 最后,使用事件调度程序的方法 调度 /发送事件 。

$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请求的输出)。这用于捕获异常并使用通用错误信息修改响应,而不是向用户显示运行时错误。