我在Symfony2项目中有一个Doctrine过滤器。我试图在每个请求上将filter的参数设置为某个值(取自session)。 问题是过滤器对象是在Symfony的onKernelRequest事件之后创建的,所以我无法从那里设置它。如果我尝试在Doctrine的postConnect事件中设置它,则会检测到循环依赖:
ServiceCircularReferenceException: Circular reference detected for service "doctrine.orm.private_entity_manager", path: "routing.loader -> assetic.asset_manager -> twig -> translator.default -> doctrine.orm.private_entity_manager -> doctrine.dbal.private_connection -> year_visibility.parameter_setter".
问题是,我应该在哪里(或者更确切地说)设置过滤器的参数?
答案 0 :(得分:5)
您可以尝试手动定义过滤器并同时传递所需的参数。
services:
app.filter_manager:
class: App\Bundle\AppBundle\Filter\FilterManager
arguments: [@doctrine.orm.entity_manager, @session]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
在过滤器管理器类中:
// ...
public function __construct(EntityManager $em, SessionInterface $session)
{
$this->em = $em;
$this->session = $session;
}
// ...
public function onKernelRequest()
{
$this->em->getConfiguration()->addFilter('filter_name', 'Filter/Class/Name/With/Ns');
$filter = $this->em->getFilters()->enable('filter_name');
$filter->setParameter('param_name', $this->session->get('param_name'));
}
答案 1 :(得分:2)
如下所示:https://stackoverflow.com/a/14650403/244058,
您可以在内核启动时拥有Filter类的实例。 因此,您的实例可以提前非常。
<?php
class MyBundle extends Bundle
{
public function boot()
{
$em = $this->container->get('doctrine.orm.default_entity_manager');
$conf = $em->getConfiguration();
$conf->addFilter(
'filter_name',
'Doctrine\Filter\TestFilter'
);
// either enable it here, or later in the event listener
$em->getFilters()->enable('filter_name');
}
}
之后,只需添加一个侦听kernel.request
的kernel.event_listener并设置一个过滤器参数(如下所示):
<?php
class DoctrineSqlFilterConfigurator
{
private $em; // inject the entity manager somehow (ctor is a good idea)
public function onKernelRequest(GetResponseEvent $event)
{
$filter = $this->em->getFilters()->enable('filter_name');
$filter->setParameter('param_name', $event->getRequest()->getSession()->get('param_name'));
}
}