【问题标题】:Doctrine in Symfony 2: Listening for events from a particular EntitySymfony 2 中的原则:监听来自特定实体的事件
【发布时间】:2012-02-10 17:24:16
【问题描述】:

我有一个 Doctrine Entity (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 事件,然后将其传递给我的侦听器?

目前(据我了解),每当学说产生prePersist 事件时,所有听众都会收到通知。最好是说哪些侦听器应该侦听哪些事件生成器,即使这应该是可选的,而不是通知所有人并让他们过滤他们需要的那些?

我希望我的问题是正确的。

【问题讨论】:

    标签: php events doctrine symfony


    【解决方案1】:

    【讨论】:

    • Doctrine ORM 2.4 现在可以与 Symfony 一起使用:doctrine-bundle 1.2 -> doctrine/orm: >=2.2,<2.5-dev
    【解决方案2】:

    这在具有 Entity listener 功能的 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 开始你可以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 }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 在简要查看了 Doctrine 文档后,我发现这些事件是由 Doctrine 自己的事件调度程序产生的,所以它甚至不取决于 symfony。谢谢。
      【解决方案4】:

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

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

      这样,监听器将只为当前被持久化的实例调用。

      【讨论】:

      • 嗯,是的,但是我的prePersist 需要访问服务,并且由于我无法将此类注入实体中,因此我必须将其移至侦听器(不幸的是)。还是谢谢!
      猜你喜欢
      • 2016-07-09
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 2017-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多