事件监听器和订阅器
编辑本页警告:您正在浏览的文档欧宝体育电话欧宝娱乐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,事件:postPersist}App \ 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;使用学说\常见的\持久性\事件\LifecycleEventArgs;类SearchIndexer{公共函数postPersist(LifecycleEventArgs$arg游戏){$实体=$arg游戏->getObject ();//仅作用于某些“Product”实体如果(!$实体运算符产品){返回;}$entityManager=$arg游戏->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(LifecycleEventArgs$arg游戏){$这->指数($arg游戏);}公共函数postPersist(LifecycleEventArgs$arg游戏){$这->指数($arg游戏);}公共函数指数(LifecycleEventArgs$arg游戏){$实体=$arg游戏->getObject ();//也许你只想作用于某个"Product"实体如果($实体运算符产品){$entityManager=$arg游戏->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,优先级:10}App \ EventListener \ MyLowPriorityListener:标签:-{名称:doctrine.event_listener,事件:postPersist,优先级:1}