Доступ к базе данных в слушателе в Symfony 2 - PullRequest
10 голосов
/ 11 января 2012

Нам нужен доступ к информации базы данных в слушателе. Настраиваем слушателя в service.yml Слушатель похож на:

namespace company\MyBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class RequestListener
{
    protected $container;

public function __construct(ContainerInterface $container)
{
    $this->container = $container;
}

public function onKernelRequest(GetResponseEvent $event)
{
...

Как мы можем получить доступ к доктрине в функции onKernelRequest?

Я попытался достать из контроллера и сделать:

        $em = $this->getDoctrine()->getEntityManager(); 

и это работает, но я думаю, что это плохая практика.

Ответы [ 6 ]

28 голосов
/ 11 января 2012

Вы можете просто добавить сервисный контейнер.Сначала измените конструктор, чтобы получить EntityManager:

use Doctrine\ORM\EntityManager;

class RequestListener {
    protected $em;
    function __construct(EntityManager $em)
    {
        $this->em = $em;
    }
    //...
}

А затем настройте свой сервис:

#...
services:
    foo.requestlistener:
        class: %foo.requestlistener.class%
        arguments:
            - @doctrine.orm.entity_manager
2 голосов
/ 30 марта 2015

Если ваш вариант использования позволяет вам напрямую использовать прослушиватель событий Doctrine

#services.yml
qis.listener.contractBundleStatusListener:
    class: Acme\AppBundle\EventListener\MyListener
    tags:
        - { name: doctrine.event_listener, event: postPersist }

, вы можете получить Entity Manager из LifecycleEventArgs :

<?php

use Doctrine\ORM\Event\LifecycleEventArgs;

class MyListener
{
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Foo) {
            $entityManager = $args->getEntityManager();

            $entityManager->persist($entity);
            $entityManager->flush();
        }
    }
}
2 голосов
/ 11 января 2012

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

$doctrine = $this->container->get('doctrine');
1 голос
/ 11 января 2012

Я все еще новичок в Symfony, но вы пытались передать службу doctrine своему слушателю вместо контейнера службы?

С другой стороны, вы уже передаете контейнер службы, поэтомуэто должно быть так же просто, как звонить
$this->container->get('doctrine').Кроме того, мне сказали в IRC некоторое время назад, что пропуск служебного контейнера обычно считается плохой практикой.Лучше сдать отдельные услуги, которые вам нужны.

0 голосов
/ 29 октября 2018

в Symfony 4 вы должны использовать инъекцию зависимостей следующим образом

class eventSubscriber implements EventSubscriberInterface
{
    /**
     * @var EntityManagerInterface
     */
    private $em;


 public function __construct(EntityManagerInterface $em)
    {

        $this->em = $em;
    }
}
0 голосов
/ 26 апреля 2012

Я бы не стал использовать бизнес-логику для слушателей, так как они предназначены только для прослушивания событий.И как бы вы написали тесты для слушателя, используя doctrine ...

Я бы поместил доступ к доктрине в другой класс и затем вызвал бы его в слушателе.

...