Symfony2 在 doctrine 事件侦听器中登录用户



我为postPersist,PostUpdate和postMove的教义方法创建了一个事件侦听器类。

我需要在我的班级中登录用户ID,我尝试注入@security.context@security.token_storage@session即使我尝试注入@service_container并使用container->get()我也得到了循环引用错误。

服务循环引用

异常:检测到>服务"doctrine.orm.default_entity_manager"的循环引用

我在serviec.yml代码中的代码是这样的

my.listener:
class: projectCreateEventListener
arguments: ["@service_container"]
tags:
- { name: doctrine.event_listener, event: postPersist }
- { name: doctrine.event_listener, event: postUpdate }
- { name: doctrine.event_listener, event: postRemove }

我的事件侦听器类是这样的

class myListener
{
private $container;
public function 
__construct(ContainerInterface $container)
{
$this->container = $container;
}
public function prePersist(LifeCycleEventArgs $args)
{
$entity = $args->getEntity();
//Circular reference error
$user = $this->container->get('security.context')-
>getToken()->getUser();
//getToken() is always null
//Circular reference error
$user = $this->container->get('security.token_storage')-
>getToken()->getUser();
//getToken() is always null
//Circular reference error
$userId = $this->container->get('auth.user')-
>getIdentity()['id'];
}
}

虽然我在$this->persist()之前在我的代码中登录了用户信息$this->container->get('auth.user')->getIdentity()['id'];

这是一个棘手的问题。创建教义服务时,侦听器在构造时附加。如果您尝试构建的侦听器使用其他服务(或其他一些服务),以任何方式需要原则,您将获得循环引用。

但是你可以围绕它进行构建。

  1. 将事件调度程序注入侦听器
  2. 创建自定义事件(或多个)http://symfony.com/doc/current/components/event_dispatcher.html#creating-and-dispatching-an-event
  3. 在 prePersist, postPersists 方法中调度事件。
  4. 构建另一个订阅自定义事件的侦听器,并在其中处理您的逻辑。

这样做的结果是:只有在实际触发自定义事件时,才会初始化自定义事件侦听器。此时,像 doctrine 这样的关键服务已经启动并运行,您可以避免循环引用问题。

在我的项目中遇到了类似的问题,并以这种方式解决了它。不太确定这是否是最优雅的方式,但它绝对有效。(如果有人有更好的解决方案,我也欢迎它)。

最新更新