Symfony中的学说2:倾听来自特定实体的事件

时间:2012-02-10 17:24:16

标签: php events doctrine symfony

我有一个Doctrine Entity(新闻),我在这里听取事件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 个答案:

答案 0 :(得分:21)

答案 1 :(得分:6)

从Doctrine 2.4开始,这可能具有Entity listener功能。

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起,您可register entity listeners via tags,但此方法为yet to be documented。 此方法不需要使用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 }

答案 2 :(得分:4)

  

是否有可能告诉Symfony监听prePersist事件   特定实体,然后将其传递给我的听众?

不,这是不可能的。您的监听器将为持久存在的每个实体触发。您可以在事件监听器中进行instanceof检查,以确保您的代码仅针对特定实体运行。

答案 3 :(得分:0)

根据您在侦听器中的操作,您可以在News实体中使用生命周期回调,并实现prePersist钩子。

http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/events.html#lifecycle-callbacks

这样,只会为当前持久存在的实例调用侦听器。