事件监听器和订阅器

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 4.2,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

事件监听器和订阅器

Doctrine包有一个丰富的事件系统,当系统内几乎发生任何事情时,它都会触发事件。对您来说,这意味着您可以任意创建服务并告诉Doctrine在任何时候通知这些对象某个动作(例如:prePersist ())发生在教义中。这可能很有用,例如,每当保存数据库中的对象时,都可以创建一个独立的搜索索引。

Doctrine定义了两种可以侦听Doctrine事件的对象:侦听器和订阅者。两者都非常相似,但是侦听器更直接一些。有关更多信息,请参见事件系统Doctrine的文档。欧宝体育电话

在使用它们之前,请记住Doctrine事件是用于持久性钩子的。"保存那个的时候也保存这个").它们不应该用于域逻辑,例如记录更改、设置updatedAt而且createdAt属性,等等。

另请参阅

本文介绍Doctrine ORM的侦听器和订阅者。如果您正在为MongoDB使用ODM,请阅读DoctrineMongoDBBundle文欧宝体育电话档

配置监听器/订阅者

要注册一个服务作为事件监听器或订阅者,您必须标签它具有适当的名称。根据您的用例,您可以将侦听器连接到每个DBAL连接和ORM实体管理器,或者仅将侦听器连接到一个特定的DBAL连接和使用此连接的所有实体管理器。

  • YAML
  • XML
  • PHP
12 3 4 5 6 7 8 9 10 11 12
服务:#……App \ EventListener \ SearchIndexer:标签:-名称:doctrine.event_listener,事件:postPersistApp \ EventListener \ SearchIndexer2:标签:-名称:doctrine.event_listener,事件:postPersist,连接:默认的App \ EventListener \ SearchIndexerSubscriber:标签:-名称:doctrine.event_subscriber,连接:默认的

创建侦听器类

在前面的例子中,aSearchIndexer服务被配置为事件上的Doctrine侦听器postPersist.该服务背后的类必须具有postPersist ()方法,该方法将在事件分派时被调用:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
/ / src / EventListener / SearchIndexer.php名称空间应用程序EventListener使用应用程序实体产品//对于Doctrine < 2.4:使用Doctrine\ORM\Event\LifecycleEventArgs;使用学说常见的持久性事件LifecycleEventArgsSearchIndexer公共函数postPersist(LifecycleEventArgsarg游戏实体arg游戏->getObject ();//仅作用于某些“Product”实体如果(!实体运算符产品){返回;}entityManagerarg游戏->getObjectManager ();/ /……对产品做些什么}}

在每个事件中,你都可以访问一个LifecycleEventArgs对象,它使您可以访问事件的实体对象和实体管理器本身。

要注意的一件重要的事情是听者会听什么所有应用程序中的实体。因此,如果您只对处理特定类型的实体感兴趣(例如a产品实体,而不是博客实体),您应该在方法中检查实体的类类型(如上所示)。

提示

在Doctrine 2.4中,引入了一个称为实体监听器的特性。它是用于实体的生命周期侦听器类。你可以在DoctrineBundle文档欧宝体育电话

创建订阅者类

Doctrine事件订阅者必须实现主义\ \ EventSubscriber接口,并为它订阅的每个事件提供一个事件方法:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/ / src / EventListener / SearchIndexerSubscriber.php名称空间应用程序EventListener使用应用程序实体产品使用学说常见的EventSubscriber//对于Doctrine < 2.4:使用Doctrine\ORM\Event\LifecycleEventArgs;使用学说常见的持久性事件LifecycleEventArgs使用学说ORM事件SearchIndexerSubscriber实现了EventSubscriber公共函数getSubscribedEvents()返回(事件::postPersist、事件::postUpdate);}公共函数postUpdate(LifecycleEventArgsarg游戏->指数(arg游戏);}公共函数postPersist(LifecycleEventArgsarg游戏->指数(arg游戏);}公共函数指数(LifecycleEventArgsarg游戏实体arg游戏->getObject ();//也许你只想作用于某个"Product"实体如果实体运算符产品){entityManagerarg游戏->getObjectManager ();/ /……对产品做些什么}}}

提示

事件订阅者不能返回灵活的方法数组来调用事件,例如欧宝娱乐app下载地址Symfony事件订阅器可以。Doctrine事件订阅者必须返回其订阅的事件名称的简单数组。Doctrine将期望订阅者上的方法与每个订阅的事件具有相同的名称,就像使用事件侦听器时一样。

要获得完整的参考,请参见章节事件系统在Doctrine文档中。欧宝体育电话

性能考虑

监听器和订阅者之间的一个重要区别是Symfony会延迟加载实体监听器。欧宝娱乐app下载地址这意味着只有在相关事件实际触发时,侦听器类才会从服务容器中获取(并实例化)。

这就是为什么尽可能使用实体侦听器而不是订阅者更可取的原因。

事件监听器的优先级

类控件控制同一个事件的多个侦听器的调用顺序优先级属性。优先级用正整数或负整数定义(默认为0).数值越大,监听器就越早被调用。

  • YAML
  • XML
  • PHP
1 2 3 4 5 6 7 8 9
#配置/ services.yaml服务:App \ EventListener \ MyHighPriorityListener:标签:-名称:doctrine.event_listener,事件:postPersist,优先级:10App \ EventListener \ MyLowPriorityListener:标签:-名称:doctrine.event_listener,事件:postPersist,优先级:1
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。