活动和活动听众

活动和活动听众

在执行Symfony应用程序期间,触发了许多事件通知欧宝娱乐app下载地址。您的应用程序可以通过执行任何代码来收听这些通知并通过执行任何代码来响应它们。

欧宝娱乐app下载地址Symfony触发了几个与内核相关的事件处理HTTP请求时。第三方捆绑包也可能会派遣活动,甚至可以发货自定义事件来自您自己的代码。

本文中显示的所有示例都使用相同的例子内科特::例外活动以获得一致性目的。在您自己的应用程序中,您可以使用任何事件,甚至在同一订户中混合其中几个。

创建一个事件侦听器

倾听事件的最常见方法是注册一个活动侦听器

// src / eventListener / ExpedioNListener.php命名空间App \ EventListener.;欧宝娱乐app下载地址symfony \ component \ httpfoundation \ response;欧宝娱乐app下载地址symfony \ component \ httpkernel \ event \ ExceptionEvent;欧宝娱乐app下载地址symfony \ component \ httpkernel \异常\ httpExceptionInterface;班级Experiplistener.{上市功能onkernelexception.异常例外$赛事{//您从收到的事件中获取异常对象$例外=$赛事- >getthrocable.();$消息=Sprintf.'我的错误说:%s的代码:%s'$例外- >GetMessage.(),$例外- >GetCode.());//自定义响应对象以显示异常详细信息$响应=新的回复();$响应- >setContent.$消息);// httpExceptionInterface是一种特殊类型的异常//保存状态代码和标题详细信息如果$例外instanceof.httpExceptionInterface.{$响应- >setStatuscode.$例外- >getStatuscode.());$响应- >标题- >代替$例外- >Getheaders.());}别的{$响应- >setStatuscode.回复::http_internal_server_error.);}//将修改后的响应对象发送到事件$赛事- >setResponse.$响应);}}

小费

每个事件都会收到略微不同的类型$赛事目的。为了kernel.exception.事件,它是欧宝娱乐app下载地址symfony \ component \ httpkernel \ event \ ExceptionEvent。看看欧宝娱乐app下载地址Symfony Events参考查看每个事件提供的对象类型。

既然类是创建的,您需要将其注册为服务,并通知symfony它是一个“侦听器”欧宝娱乐app下载地址kernel.exception.使用特殊的“标签”事件:

  • yaml.
    1 2 3 4 5
    #配置/服务.YAML服务App \ EventListener \ Experfiplistener标签-{名称kernel.event_listener.事件kernel.exception.}
  • XML.
    1 2 3 4 5 6 7 8 9 10 11 12 13
    <! -  config / services.xml  - ><?XML Version =“1.0”编码=“UTF-8”?><容器XMLNS =.“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services”XMLNS:XSI =“http://www.w3.org/2001/xmlschema-instance”XSI:Schemalocation =“http://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services.https://欧宝娱乐app下载地址www.oldmanjams.com/schema/dic/services/services-1.0.xsd“><服务><服务ID =“app \ enceListener \ Experfiplistener”>名称=“kernel.event_listener”事件=“kernel.exception”/>
  • PHP.
    1 2 3 4 5 6 7 8 9 10 11 12
    // config / services.php命名空间欧宝娱乐app下载地址Symfony \ Component \ DependencyIngreation \ Loader \ Configurator;App \ EventListener \ Experfiplistener;返回功能containerconfigurator$ Configurator.{$服务=$ Configurator.- >服务();$服务- >Experiplistener.::班级- >标签'kernel.event_listener'['事件'=>'kernel.exception']);};

欧宝娱乐app下载地址symfony遵循此逻辑来决定事件侦听器类中调用哪种方法:

  1. 如果是kernel.event_listener.标签定义了方法属性,这是要调用的方法的名称;
  2. 如果不方法属性已定义,尝试调用其名称的方法+“骆驼壳事件名称”(例如onkernelexception()kernel.exception.事件);
  3. 如果未定义该方法,请尝试调用__invoke()魔法方法(使事件侦听器可调用);
  4. 如果是__invoke()方法未定义,抛出异常。

笔记

有一个可选的属性kernel.event_listener.标签打电话优先事项,这是默认为的正面或负整数0.它控制执行侦听器的顺序(越多,执行较早的侦听器)。当您需要保证在另一个侦听器执行一个侦听器时,这非常有用。内部Symfony听众的优先级通常是欧宝娱乐app下载地址-256256.但是您自己的听众可以使用任何正面或负整数。

创建活动订阅者

通过一个倾听事件的另一种方法是通过活动订阅者,这是一个定义一个或多个收听一个或多个事件的方法的类。与事件侦听器的主要区别在于,订阅者始终知道他们正在倾听哪些事件。

如果不同的事件订阅者方法收听相同的事件,则其订单由其定义优先事项范围。此值是默认为的正面或负整数0.。数量越高,方法的越早调用。所有侦听器和订阅者都会汇总优先级,因此您的方法可以在其他侦听器和订阅者中定义的方法之前或之后调用。要了解有关活动订阅者的更多信息,请阅读EventDispatcher组件

以下示例显示了一个事件订阅者,用于定义几种收听相同的方法kernel.exception.事件:

// src / fementubscriber / ExpedioSubScriber.php命名空间App \ EventsubScriber.;欧宝娱乐app下载地址symfony \ component \ enceDispatcher \ eventsubscriberInterface;欧宝娱乐app下载地址symfony \ component \ httpkernel \ event \ ExceptionEvent;欧宝娱乐app下载地址symfony \ component \ httpkernel \ kernelevents;班级ExpiteTomsubScriber.实施eventsubscriberInterface.{上市静止的功能getsubscribedEvents.(){//返回订阅的事件,方法和优先级返回[内科特::例外=>[['processException'10.],['logexception'0.],['notifyException'-10.],],];}上市功能processException.异常例外$赛事{// ......}上市功能logexception.异常例外$赛事{// ......}上市功能notifyException.异常例外$赛事{// ......}}

就是这样!你的服务.Yaml.文件应该已经设置为加载服务EventsubScriber.目录。欧宝娱乐app下载地址Symfony照顾其余的。

小费

如果你的方法是不是当抛出异常时,调用,仔细检查您是加载服务来自EventsubScriber.目录和有AutoconFigure.启用。您也可以手动添加kernel.event_subscriber.标签。

请求事件,检查类型

单个页面可以制作几个请求(一个主请求,然后是多个子请求 - 通常何时嵌入模板中的控制器)。对于核心Symfony事件欧宝娱乐app下载地址,您可能需要检查该事件是否为“主”请求或“子请求”:

// src / eventListener / requestListener.php命名空间App \ EventListener.;欧宝娱乐app下载地址symfony \ component \ httpkernel \ event \ RequestEvent;班级RequestListener.{上市功能onkernelrequest要求申请$赛事{如果!!$赛事- >ismasterrequest.()){//如果不是主请求,请不要做任何事情返回;}// ......}}

某些事情,如检查信息真实的请求可能不需要在子申请侦听器上完成。

听众或用户

侦听器和订阅者可以模糊地使用相同的应用程序。使用其中任何一个的决定通常是个人品味的问题。但是,每个人都有一些小的优势:

  • 订阅者更易于重用因为事件的知识保持在课堂上,而不是在服务定义中。这就是为什么Symfony在内部使用订阅者的原欧宝娱乐app下载地址因;
  • 听众更灵活因为捆绑包可以根据某些配置值使能或禁用它们中的每一个。

活动别名

通过依赖项注入配置事件侦听器和订阅者,Symfony的核心事件也可以通过相应的事件类的完全限定类名(FQCN)引用:欧宝娱乐app下载地址

// src / evaceubscriber / requestsubscriber.php命名空间App \ EventsubScriber.;欧宝娱乐app下载地址symfony \ component \ enceDispatcher \ eventsubscriberInterface;欧宝娱乐app下载地址symfony \ component \ httpkernel \ event \ RequestEvent;班级RequestSubscriber.实施eventsubscriberInterface.{上市静止的功能getsubscribedEvents.()大批{返回[要求申请::班级=>'onkernelrequest'];}上市功能onkernelrequest要求申请$赛事{// ......}}

在内部,事件FQCN被视为原始事件名称的别名。由于映射已经在编译服务容器时发生,因此在检查事件调度程序时将在原始事件名称中使用FQCN而不是事件名称使用FQCN而不是事件名称的事件侦听器和订阅者。

可以通过注册编译器通过来扩展此别名映射。adeventaliasespass.

// src / kernel.php命名空间应用程序;app \ event \ mycustomevent;欧宝娱乐app下载地址symfony \ component \ decigendencyIngreation \ containerBuilder;欧宝娱乐app下载地址symfony \ component \ enceDispatcher \依赖性inpects \ addeventaliaseSpass;欧宝娱乐app下载地址symfony \ component \ httpkernel \ kernel作为BaseKernel.;班级核心延伸BaseKernel.{保护功能建造ContainerBuilder.$容器{$容器- >addcompilerpass.新的adeventaliasespass.([mycustomevent.::班级=>'my_custom_event']));}}

编译器通过始终扩展现有的别名列表。因此,通过使用不同的配置注册多个传递实例是安全的。

调试活动侦听器

您可以使用控制台找到在事件调度程序中注册的侦听器。要显示所有活动及其侦听器,请运行:

1
$PHP BIN / CONSOLE调试:事件调度程序

您可以通过指定其名称来获得特定事件的已注册侦听器:

1
$PHP BIN / CONSOLE调试:EVENT-DISPATCHER KERNEL.EXCEPTION

这项工作包括代码样本,是在a下获得的许可Creative Commons by-SA 3.0执照。