如何在Symfony2中添加可以访问容器的特定于实体的侦听器


How to add an entity-specific listener in Symfony2 that has access to container

在Symfony2应用程序中,我有一个实体,需要在预保存中填充各种上下文属性(如用户id,从哪个页面调用它,等等)

我认为要做到这一点,我需要添加一个学说事件监听器,它可以访问"service_container",而提供这种访问的最好方法是将"service_container"作为参数传递给这个监听器。

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

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

我也尝试使用jmsdiextrabundance注释,就像下面的例子:http://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations#doctrinelistener-or-doctrinemongodblistener-但这种方式需要将侦听器声明为非实体特定的

是否有任何方法使侦听器只为一个实体,并有它访问容器?

通过依赖注入的方式与教条文档类似:

<?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: ~

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

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');
    }
}