2012-01-11 2 views
9

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

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(); 

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

+0

Спасибо всем комментариям. Все это хорошие варианты. – Santi

ответ

27

Вы можете просто ввести контейнер обслуживания. Во-первых изменить конструктор, чтобы получить 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 
+0

Спасибо, это хороший вариант – Santi

+3

Это лучший вариант. –

+0

Спасибо, что работал, как только я добавил «использовать Symfony \ Component \ DependencyInjection \ ContainerInterface;» – someuser

2

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

$doctrine = $this->container->get('doctrine'); 
1

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

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

+0

Спасибо, хороший вариант – Santi

0

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

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

2

Если Прецедент позволяет использовать Doctrine Event Listener относящиеся непосредственно

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

вы можете получить Entity менеджер из 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(); 
     } 
    } 
} 
Смежные вопросы