Symfony2 войдет в систему пользователя в прослушивателе событий доктрины

Я создал класс прослушивателя событий для методов доктрины postPersist, PostUpdate и postRemove.

Мне нужен зарегистрированный идентификатор пользователя в моем классе, я пытался ввести @security.context , @security.token_storage и @session. Я получил ошибку циклической ссылки, даже если я попытался ввести @service_container и использовать container->get(), я получил ту же ошибку циклической ссылки.

ServiceCircularReferenceException: Обнаружена циклическая ссылка для > службы "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'];


person talha kazmi    schedule 06.04.2017    source источник
comment
Возможный дубликат Получить пользователя в Doctrine EventListener   -  person LBA    schedule 06.04.2017
comment
Итак, какую версию Symfony вы используете, потому что security.context давно исчез. Подозреваю, что у вас другие дела. Привязка слушателя доктрины непосредственно к Symfony, вероятно, является лучшим подходом. Рассмотрите возможность использования диспетчера событий Symfony для такого рода вещей.   -  person Cerad    schedule 06.04.2017


Ответы (1)


Это сложно. При создании службы доктрины слушатель прикрепляется при построении. Если прослушиватель, который вы пытаетесь создать, использует другой сервис (или какой-либо другой сервис в будущем), который требует доктрины в любом случае, вы получаете циклическую ссылку.

Но вы можете строить вокруг него.

  1. Вставьте eventDispatcher в ваш Listener
  2. Создайте собственное событие (или несколько) http://symfony.com/doc/current/components/event_dispatcher.html#creating-and-dispatching-an-event
  3. Отправьте событие в методах prePersist, postPersists.
  4. Создайте еще один слушатель, который подписывается на ваше пользовательское событие и обрабатывает там вашу логику.

Это достигается следующим образом: ваш пользовательский прослушиватель событий будет инициализирован только тогда, когда ваше пользовательское событие действительно запущено. В этот момент важные службы, такие как доктрина, уже запущены и работают, и вы избегаете проблемы циклических ссылок.

В моем проекте была аналогичная проблема, и я решил ее таким образом. Не совсем уверен, что это самый элегантный способ, но он определенно работает. (Если у кого-то есть лучшее решение, я бы тоже его приветствовал).

person Joe    schedule 06.04.2017
comment
вы видели мой комментарий reg. дубликат? проверить это - person LBA; 06.04.2017
comment
я видел это, но вопрос предполагает, что его проблема не в том, что он не знает, как внедрить необходимые классы в слушатель, а скорее, когда он это делает, это создает ошибку циклической ссылки, которая полностью нарушает структуру. (Не уверен, почему, но чтобы понять это, вам нужно посмотреть на полную иерархию DI проекта) - person Joe; 06.04.2017