이벤트 및 이벤트 수신


심포니 프로그램 실행 중에는 다수의 이벤트 알림이 발송됩니다. 귀하의 프로그램은 이러한 알림을 수신하고 이에 대한 응답으로 임의의 코드를 실행할 수 있습니다.

Symfony 자체에서 제공하는 내부 이벤트는 KernelEvents 클래스. 타사 번들 및 클래스 라이브러리도 다수의 이벤트를 트리거하며, 여러분의 프로그램이 맞춤 이벤트를 트리거할 수 있습니다. KernelEvents类中。第三方Bundle和类库也会触发大量事件,你自己的程序可以触发自定义事件

本文展示的所有例子,考虑到一致性,使用了相同的KernelEvents::EXCEPTION事件。在你自己的程序中,你可以使用任何事件,甚至在同一订阅器中(subscriber)混合若干事件。

创建一个事件监听 

监听一个事件最常用的方式是注册一个事件监听(event listener)

// src/AppBundle/EventListener/ExceptionListener.phpnamespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; class ExceptionListener{
    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        // You get the exception object from the received event
        // 你可以从接收到的事件中,取得异常对象
        $exception = $event->getException();
        $message = sprintf(
            'My Error says: %s with code: %s',
            $exception->getMessage(),
            $exception->getCode()
        );         // Customize your response object to display the exception details
        // 自定义响应对象,来显示异常的细节
        $response = new Response();
        $response->setContent($message);         // HttpExceptionInterface is a special type of exception that
        // holds status code and header details
        // HttpExceptionInterface是一个特殊类型的异常,持有状态码和头信息的细节
        if ($exception instanceof HttpExceptionInterface) {
            $response->setStatusCode($exception->getStatusCode());
            $response->headers->replace($exception->getHeaders());
        } else {
            $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
        }         // Send the modified response object to the event
        // 发送修改后的响应对象到事件中
        $event->setResponse($response);
    }}


每一个事件,都要接收“类型略有不同”的$event对象。对于kernel.exception事件,这个对象是GetResponseForExceptionEvent。要了解每一个“事件监听”所接收到的“事件对象”之类型,参考KernelEvents,或是你要监听的特定事件之文档。


现在,类被创建了,你只需把它注册成服务,然后通过使用一个特殊的“tag”(标签),告诉Symfony这是一个针对kernel.exception事件的“监听”:

YAML:# app/config/services.ymlservices:
    app.exception_listener:
        class: AppBundle\EventListener\ExceptionListener
        tags:
            - { name: kernel.event_listener, event: kernel.exception }
xml:<!-- app/config/services.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">     <services>
        <service id="app.exception_listener"            class="AppBundle\EventListener\ExceptionListener">             <tag name="kernel.event_listener" event="kernel.exception" />
        </service>
    </services></container>
php:// app/config/services.php$container
    ->register('app.exception_listener', 'AppBundle\EventListener\ExceptionListener')
    ->addTag('kernel.event_listener', array('event' => 'kernel.exception'));

有一个可选的tag属性是method,它定义了“当事件被触发时,哪个方法要被执行”。默认时,方法的名字是on+“驼峰事件名”。如果事件是kernel.exception的话,默认执行的方法则是onKernelException()

另有一个可选的tag属性是priority,它的默认值是0,用来控制监听被执行的顺序(一个监听器的优先级愈高则愈早被执行)。这在你要“确保某个监听在其他监听之前被执行”时是有用的。Symfony的内部监听,其优先级范围是-255255

이 문서에 표시된 모든 예제는 일관성을 고려하여 동일한 KernelEvents::EXCEPTION 이벤트를 사용합니다. 자신의 프로그램에서는 모든 이벤트를 사용할 수 있으며 동일한 구독자에서 여러 이벤트를 혼합할 수도 있습니다.

이벤트 리스너 만들기

듣는 가장 일반적인 방법 이벤트 이벤트 리스너를 등록하는 것입니다: #🎜🎜#
// src/AppBundle/EventSubscriber/ExceptionSubscriber.phpnamespace AppBundle\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;use Symfony\Component\HttpKernel\KernelEvents; class ExceptionSubscriber implements EventSubscriberInterface{
    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        // 返回被订阅的事件,以及它们的方法和属性
        return array(
           KernelEvents::EXCEPTION => array(
               array('processException', 10),
               array('logException', 0),
               array('notifyException', -10),
           )
        );
    }     public function processException(GetResponseForExceptionEvent $event)
    {
        // ...
    }     public function logException(GetResponseForExceptionEvent $event)
    {
        // ...
    }     public function notifyException(GetResponseForExceptionEvent $event)
    {
        // ...
    }}
#🎜🎜#
#🎜🎜#
#🎜🎜#Every 이벤트는 "약간 다른 유형"의 $event 개체를 수신해야 합니다. kernel.Exception 이벤트의 경우 이 개체는 GetResponseForExceptionEvent. 각 "이벤트 리스너"가 수신하는 "이벤트 객체"의 유형을 이해하려면 KernelEvents 또는 듣고 싶은 특정 이벤트에 대한 문서입니다. #🎜🎜##🎜🎜##🎜🎜#
#🎜🎜##🎜🎜#이제 클래스가 생성되었으므로 클래스를 서비스로 등록한 다음 다음을 사용하여 서비스로 등록하면 됩니다. 특수 "태그"(태그)는 이것이 kernel.Exception 이벤트에 대한 "리스너"임을 Symfony에 알려줍니다. #🎜🎜#
PHP:// app/config/services.php$container
    ->register(
        'app.exception_subscriber',
        'AppBundle\EventSubscriber\ExceptionSubscriber'
    )
    ->addTag('kernel.event_subscriber');
XML:<!-- app/config/services.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">     <services>
        <service id="app.exception_subscriber"            class="AppBundle\EventSubscriber\ExceptionSubscriber">             <tag name="kernel.event_subscriber"/>
        </service>
    </services></container>
YAML:# app/config/services.ymlservices:
    app.exception_subscriber:
        class: AppBundle\EventSubscriber\ExceptionSubscriber
        tags:
            - { name: kernel.event_subscriber }
#🎜🎜#선택적 태그 속성은 "이벤트가 트리거될 때 실행할 메소드"를 정의하는 method입니다. 기본적으로 메소드 이름은 on+"camel Case event name"입니다. 이벤트가 kernel.Exception인 경우 기본 실행 방법은 onKernelException()입니다.
#🎜🎜##🎜🎜#또 다른 선택적 태그 속성은 우선순위이며 기본값은 0이며 모니터링 명령 실행을 제어하는 ​​데 사용됩니다( 리스너의 우선순위가 높을수록 더 일찍 실행됩니다. 이는 특정 리스너가 다른 리스너보다 먼저 실행되도록 하려는 경우에 유용합니다. Symfony의 내부 리스너의 우선순위 범위는 -255부터 255까지이지만, 자체 리스너는 양수 또는 음수 정수를 사용할 수 있습니다. #🎜🎜##🎜🎜##🎜🎜#

이벤트 구독 만들기

이벤트를 듣는 또 다른 방법은 event subscriber이벤트 구독입니다. 이벤트 구독은 하나 이상의 이벤트를 듣는 하나 이상의 메서드를 정의하는 클래스입니다. 이벤트 수신과의 주요 차이점은 구독자는 자신이 수신 중인 이벤트를 항상 알고 있다는 것입니다.

특정 구독자 내에서 동일한 이벤트를 다양한 방법으로 들을 수 있습니다. 메소드가 실행되는 순서는 각 메소드의 priority 매개변수에 의해 정의됩니다(우선순위가 높을수록 메소드가 더 일찍 호출됩니다). 구독자에 대해 자세히 알아보려면 EventDispatcher 구성요소priority参数来定义(优先级愈高则方法愈早被调用)。要了解更多关于订阅器的内容,参考EventDispatcher组件

下例展示了一个事件订阅,定义了若干方法,监听的是同一个kernel.exception事件:

// src/AppBundle/EventListener/RequestListener.phpnamespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseEvent;use Symfony\Component\HttpKernel\HttpKernel;use Symfony\Component\HttpKernel\HttpKernelInterface; class RequestListener{
    public function onKernelRequest(GetResponseEvent $event)
    {
        if (!$event->isMasterRequest()) {
            // don't do anything if it's not the master request
            // 如果不是主请求,就什么也不做
            return;
        }         // ...
    }}

现在,你只需把这个类注册成服务,并打上kernel.event_subscriber를 참조하세요.

다음 예는 여러 메서드를 정의하고 동일한 kernel.Exception 이벤트를 수신하는 이벤트 구독을 보여줍니다.

1
이제 이 클래스를 서비스로 등록하고 < 코드를 표시하기만 하면 됩니다. >kernel.event_subscriber 태그는 Symofny에게 이것이 이벤트 구독자임을 알릴 수 있습니다:

$  php bin/console debug:event-dispatcher
1
$  php bin/console debug:event-dispatcher kernel.exception

이벤트 요청, 유형 확인

한 페이지에서 여러 요청(기본 요청 [마스터 요청] 및 그런 다음 일반적으로 템플릿에 컨트롤러를 포함하는 방법과 같은 여러 하위 요청[하위 요청]). Symfony 핵심 이벤트의 경우 해당 이벤트가 "기본" 요청인지 "하위" 요청인지 확인할 수 있습니다.
rrreee

실제요청 확인과 같은 특정 작업은 필요하지 않을 수 있습니다. 청취에서 수행됩니다. 하위 요청.

듣기 또는 구독

  • 청취자와 구독자는 동일한 프로그램에서 사용될 때 경계가 흐려질 수 있습니다. 어떤 것을 사용할지 결정하는 것은 개인 취향에 따라 결정되는 경우가 많습니다. 그러나 각각 고유한 장점이 있습니다.

  • 이벤트와 관련된 콘텐츠가 서비스 정의가 아닌 클래스에 있기 때문에 구독자는 쉽게 재사용할 수 있습니다

    . 이로 인해 Symfony는 구독자를 내부적으로 사용하게 됩니다.

청취자는 구성 파일의 특정 "옵션 값"에 따라 조건부로 구독자를 켜거나 끌 수 있기 때문에 청취자가 더 유연해집니다.

이벤트 리스너 디버그

명령줄을 사용하면 "이벤트 디스패처에 등록된 리스너"를 찾을 수 있습니다. 모든 이벤트와 해당 리스너를 표시하려면 다음을 실행합니다.

이벤트 이름을 지정하면 이 특정 이벤트에 등록된 청취자를 얻을 수 있습니다.

rrreee
rrreee