我正在使用Symfony2框架,想知道何时使用Doctrine订户而不是侦听器。对于听众,Doctrine的文档非常清晰,但是订阅者却被蒙蔽了。Symfony的食谱条目与此类似。
Answers:
在我看来,只有一个主要区别:
这看起来似乎没有太大的区别,但是如果您考虑一下,在某些情况下,您可能会希望使用其中一种:
getSubscribedEvents
:(考虑一下您听到一个非常嘈杂的事件并且只想执行一次的事件)我可能还没有意识到其他差异!
getSubscribedEvents
我会再返回一个数组,像array(Events::prePersist, Events::postUpdate)
我猜?
不知道它是偶然还是有意完成。但是订户比侦听器具有更高的优先级-https: //github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass .php#L73-L98
从学说的角度讲,它不在乎它是什么(侦听器或订户),最终两者都注册为侦听器-https: //github.com/doctrine/common/blob/master/lib/Doctrine/Common/EventManager.php #L137-L140
这就是我发现的。
如果要在一个类中处理多个事件,则应使用事件订阅程序,例如,在此symfony2文档页面文章中,您可能会注意到事件监听器只能管理一个事件,但是假设您要处理一个实体的多个事件,例如prePersist,preUpdate,postPersist等...如果您使用事件监听器,则必须编写多个事件监听器,每个事件一个,但是如果您与事件订阅者一起使用,则只需要为事件订阅者编写一个类,就可以看到事件订阅者可以在一个类中管理多个事件,这就是我的使用方式,我认为为了专注于模型业务需要的代码,您可能想只为一组实体全局处理多个生命周期事件,为此,您可以编写父类并在其中定义这些全局方法,然后让您的实体继承该类,然后在事件订阅者中订阅您想要的每个事件,prePersist,preUpdate,postPersist等...,然后请求该父类并执行那些全局方法。
两者都允许您在持久之前/之后的特定事件上执行某些操作。
但是,侦听器仅允许您执行封装在实体中的行为。因此,一个示例可能是更新“ date_edited”时间戳。
如果您需要移出实体的上下文,则需要一个订阅者。一个很好的例子可能是调用外部API,或者如果您需要使用/检查与您的实体不直接相关的数据。
doctrine.event_subscriber
而不是doctrine.event_listener
。
这就是文档在4.1中所说的。因为这是全局性地应用于事件,所以我认为它也适用于“教义”(并非100%肯定)。
侦听器或订户
侦听器和订阅者可以在同一应用程序中模糊地使用。选择使用其中之一通常取决于个人喜好。但是,它们每个都有一些次要的优点:
- 订户更易于重用,因为事件的知识保存在类中,而不是服务定义中。这就是Symfony内部使用订户的原因。
- 侦听器更加灵活,因为捆绑包可以根据某些配置值有条件地启用或禁用它们。
http://symfony.com/doc/master/event_dispatcher.html#listeners-or-subscribers
从文档中:
侦听事件的最常见方法是在调度程序中注册事件侦听器。该侦听器可以侦听一个或多个事件,并在每次调度这些事件时收到通知。
监听事件的另一种方法是通过事件订阅者。事件订阅者是一个PHP类,它能够准确告知调度程序应订阅的事件。它实现了EventSubscriberInterface接口,该接口需要一个名为getSubscribedEvents()的静态方法。
在这里查看示例:
https://symfony.com/doc/3.3/components/event_dispatcher.html