学说听者与订阅者

我正在Symfony2框架中工作,想知道什么时候会使用Doctrine用户而不是监听器。 听众对于听众的文件是非常清楚的,然而用户却被掩盖了。 Symfony的食谱条目是相似的。

从我的angular度来看,只有一个主要区别:

  • 监听器注册,指定它监听的事件。
  • 订户有一个方法告诉调度员正在收听的事件

这看起来可能没有什么太大的差别,但是如果你仔细想一想,有些情况下你想用另一个:

  • 您可以将一个监听器分配给许多具有不同事件的调度器,因为它们是在注册时设置的。 你只需要确保每个方法都在监听器中就位
  • 您可以更改订阅者在运行时注册的事件,甚至可以在注册订阅者之后通过更改getSubscribedEvents的返回值来设置事件(想想听一个非常嘈杂的事件并且只想执行一次的事情)

可能还有其他的差异,我不知道!

不知道是不是有意或无意地做了..但订阅者有更高的优先级,听众 – 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 doc页面的文章中 ,可能会注意到事件监听者只能pipe理一个事件,但可以说你想要处理一个事件实体,prePersist,preUpdate,postPersist等…如果你使用事件监听器,你将不得不编写几个事件监听器,每个事件监听器,但是如果你使用事件订阅者,你只需要编写一个事件驱动器类,通过事件订阅者,您可以在一个类中pipe理多个事件,这就是我使用它的方式,我主要关注的是模型业务所需的代码,其中一个例子可能是您希望处理几个全局生命周期事件只有一组实体可以这样做,你可以编写一个父类并在其中定义这些全局方法,然后让你的实体inheritance这个类,然后在你的事件中,你订阅你想要的每个事件prePersist,preUpdate,po stPersist等…然后请求该父类并执行这些全局方法。

两者都允许你执行一些特定的事件前/后继续等。

然而,监听器只允许你执行封装在你的实体中的行为。 所以一个例子可能是更新“date_edited”的时间戳。

如果您需要移出实体的环境,那么您将需要订阅者。 一个很好的例子可能是调用外部API,或者如果您需要使用/检查与您的实体不直接相关的数据。

另一个重要的事情:Doctrine EventSubscribers不允许你设置优先级。

在这里阅读更多关于这个问题