Symfony 2中的Doctrine:监听特定实体的事件

8

我有一个Doctrine实体(News),我监听事件prePersist。为此,我使用了一个具有方法prePersist的事件监听器。

我的services.yml文件如下所示:

listener.entity.news:
    class: A\BBundle\Listeners\Entity\NewsListener
    tags:
        - { name: doctrine.event_listener, event: prePersist }

这很好,一切都正常。但是文档说明在调用persist()时会生成一个prePersist事件。然后根据我的配置,NewsListener将捕获它并执行一些代码。在我捕获事件的方法中,我应该检查事件是否来自News实体。这就是我想知道的地方,是否可以告诉Symfony监听特定实体的prePersist事件,然后将其传递给我的监听器?
目前(据我所知),每当Doctrine生成prePersist事件时,所有侦听器都会被通知。即使这是可选的,是否指定哪些侦听器应该侦听哪些事件生成器,也比通知所有侦听器并让它们过滤需要的事件更好吗?
我希望我正确地提出了我的问题。
4个回答

21

2
Doctrine ORM 2.4现在可以与Symfony一起使用:doctrine-bundle 1.2 -> doctrine/orm: >=2.2,<2.5-dev - thomaskonrad

7
自Doctrine 2.4起,实体监听器功能使这成为可能。
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\EntityListeners({"AppBundle\EntityListener\PostListener"})
 */
class Post
{
}

namespace AppBundle\EntityListener;

use Doctrine\ORM\Mapping as ORM;

class PostListener
{
    public function preUpdate() {  }

    // or

    /** @ORM\PreUpdate */
    public function someOtherName() {  }
}

如果我想在监听器中注入依赖项,这可能吗?
是的,在DoctrineBundle 1.3开始,这是可能的。您只需要将实体监听器注册为服务并使用doctrine.orm.entity_listener标记进行标记。
class PostListener
{
    public function __construct(SomeDependency $someDependency) {  }
}

services:
    app.post_listener:
        class: AppBundle\EntityListener\PostListener
        arguments: ["@app.some_dependency"]
        tags:
            - { name: doctrine.orm.entity_listener }

替代方法

自DoctrineBundle 1.5以来,您可以使用标签注册实体监听器,但是该方法尚未记录文档。 这种方法不需要使用EntityListeners注释映射监听器。

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Post
{
}

namespace AppBundle\EntityListener;

class PostListener
{
    public function __construct(SomeDependency $someDependency) {  }

    public function preUpdate() {  }

    public function someOtherName() {  }
}

services:
    app.post_listener:
        class: AppBundle\EntityListener\PostListener
        arguments: ["@app.some_dependency"]
        tags:
            - { name: doctrine.orm.entity_listener, entity: AppBundle\Entity\Post, event: preUpdate }
            # or
            - { name: doctrine.orm.entity_listener, entity: AppBundle\Entity\Post, event: preUpdate, method: someOtherName }

4

是否可以让Symfony监听特定实体的prePersist事件,然后将其传递给我的监听器?

不可以。您的监听器将对持久化的每个实体触发。需要在事件侦听器中使用instanceof检查以确保您的代码仅针对特定实体运行。


1
在简要查看Doctrine文档后,我发现事件是由Doctrine自己的事件调度器生成的,所以这实际上并不完全取决于Symfony。谢谢。 - Tony Bogdanov

0

是的,但我的 prePersist 需要访问服务,而且由于我无法在实体中注入这样的内容,所以不得不将其移到一个监听器中(可惜了)。无论如何感谢! - Tony Bogdanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接