2012-01-11 16 views
9

Abbiamo bisogno di accedere alle informazioni del database in un listener. configuriamo l'ascoltatore in un service.yml L'ascoltatore è come:Accesso al database in un listener in 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) 
{ 
... 

Come possiamo accedere alla dottrina in funzione onKernelRequest?

ho cercato di estende dal regolatore e da fare:

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

e funziona, ma penso che questo sia una cattiva pratica.

+0

Grazie a tutti i commenti. Tutte sono buone opzioni. – Santi

risposta

27

Si può semplicemente iniettare il contenitore di servizio. In primo luogo cambiare il costruttore per ottenere un EntityManager:

use Doctrine\ORM\EntityManager; 

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

E la prossima configurare il vostro servizio:

#... 
services: 
    foo.requestlistener: 
     class: %foo.requestlistener.class% 
     arguments: 
      - @doctrine.orm.entity_manager 
+0

Grazie, è una buona opzione – Santi

+3

Questa è l'opzione migliore. –

+0

Grazie che ha funzionato dopo aver aggiunto "use Symfony \ Component \ DependencyInjection \ ContainerInterface;" – someuser

2

Sembra che si sta iniettando il contenitore di servizi in chi ascolta, in modo da poter accedere dottrina in questo modo:

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

Sono un po 'un novizio in Symfony ancora, ma hai provato passando il doctrine servizio al listener invece del container di servizio?

In alternativa, si sta già passando il contenitore dei servizi, quindi dovrebbe essere semplice come chiamare
$this->container->get('doctrine'). Inoltre, qualche tempo fa mi è stato detto in IRC che passare il container di servizio è generalmente considerato una cattiva pratica. È meglio passare i singoli servizi di cui hai bisogno.

+0

Grazie, è una buona opzione – Santi

0

non avrei messo la logica di business agli ascoltatori come sono solo per l'ascolto di eventi. E come scriveresti test per l'ascoltatore usando doctrine ...

Metterei la dottrina che accede a una classe diversa e poi la chiamiamo nell'ascoltatore.

2

Se il vostro caso d'uso consente di utilizzare un Dottrina evento Listener directely

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

è possibile ottenere l'Entità Manager dal 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(); 
     } 
    } 
}