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