【问题标题】:How to add an entity-specific listener in Symfony2 that has access to container如何在可以访问容器的 Symfony2 中添加特定于实体的侦听器
【发布时间】:2015-05-27 17:09:27
【问题描述】:

在 Symfony2 应用程序中,我有一个实体,需要在 pre-persist 上填充各种上下文属性(如用户 ID、调用它的页面等)

我认为要做到这一点,我需要添加一个可以访问“service_container”的原则事件侦听器,而提供这种访问权限的最佳方法是将“service_container”作为参数传递给该侦听器。

我有一个我想收听的特定实体,并且我不想触发侦听器与任何其他实体发生事件。

我们可以添加一个实体特定的监听器,文档可以在这里找到: http://docs.doctrine-project.org/en/latest/reference/events.html#entity-listeners - 但这没有提供如何传递参数的示例(我使用 PHP 注释来声明侦听器)。

我还尝试使用 JMSDiExtraBundle 注释,如下例所示: http://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations#doctrinelistener-or-doctrinemongodblistener - 但是这种方式需要将监听器声明为非实体特定

有没有办法只为一个实体创建一个监听器,并让它可以访问容器?

【问题讨论】:

    标签: php symfony doctrine-orm


    【解决方案1】:

    通过依赖注入类似于doctrine docs的一种方式:

    <?php
    
    namespace AppBundle\EntityListener;
    
    use AppBundle\Entity\User;
    use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
    use Psr\Log\LoggerInterface;
    use Symfony\Component\Routing\RouterInterface;
    
    class UserListener {
    
        /**
         * @var LoggerInterface
         */
        private $logger;
    
        public function __construct(LoggerInterface $logger)
        {
            $this->logger = $logger;
        }
    
        public function postPersist(User $user, LifecycleEventArgs $args)
        {
            $logger = $this->logger;
    
            $logger->info('Event triggered');
    
            //Do something
        }
    }
    

    services:
      user.listener:
          class: AppBundle\EntityListener\UserListener
          arguments: [@logger]
          tags:
              - { name: doctrine.orm.entity_listener }
    

    别忘了给实体映射添加监听器:

    AppBundle\Entity\User:
        type: entity
        table: null
        repositoryClass: AppBundle\Entity\UserRepository
        entityListeners:
            AppBundle\EntityListener\UserListener: ~
    

    【讨论】:

      【解决方案2】:

      我会简单地从事件中检查实体类型。如果您检查订阅者内部或外部的类型,它具有相同的性能成本。并且简单的类型条件已经足够快了。

      namespace App\Modules\CoreModule\EventSubscriber;
      
      use Doctrine\Common\EventSubscriber;
      use Doctrine\ORM\Event\LifecycleEventArgs;
      use Doctrine\ORM\Events;
      
      
      class SetCountryToTaxSubscriber implements EventSubscriber
      {
      
          /**
           * {@inheritdoc}
           */
          public function getSubscribedEvents()
          {
              return [Events::prePersist];
          }
      
      
          public function prePersist(LifecycleEventArgs $lifecycleEventArgs)
          {
              $entity = $lifecycleEventArgs->getEntity();
              if ( ! $entity instanceof Tax) {
                  return;
              }
      
              $entity->setCountry('myCountry');
          }
      
      }
      

      【讨论】:

      • 谢谢,我就是这么做的。我想这是最简单的方法。如果性能成本相同,这可能也是最好的方法。
      猜你喜欢
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 2014-06-01
      • 2016-08-05
      • 1970-01-01
      • 2017-04-27
      • 2011-08-16
      • 1970-01-01
      相关资源
      最近更新 更多