2012-01-11 9 views
9

Necesitamos acceder a la información de la base de datos en un oyente. Nos configurar la escucha en un service.yml El oyente es como:Acceso a la base de datos en un oyente en 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) 
{ 
... 

¿Cómo podemos acceder a la doctrina en función onKernelRequest?

Me trataron de extiende desde el controlador y hacer:

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

y funciona pero creo que esto es una mala práctica.

+0

Gracias a todos los comentarios. Todas son buenas opciones. – Santi

Respuesta

27

Puede simplemente inyectar el contenedor de servicio. En primer lugar cambiar el constructor para conseguir un EntityManager:

use Doctrine\ORM\EntityManager; 

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

Y la próxima configurar su servicio:

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

Gracias, es una buena opción – Santi

+3

Esta es la mejor opción. –

+0

Gracias que funcionó una vez que agregué "use Symfony \ Component \ DependencyInjection \ ContainerInterface;" – someuser

2

Parece como que está inyectando el contenedor de servicios en el oyente, para que pueda acceder Doctrina de esta manera:

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

Soy una especie de un principiante en Symfony todavía, pero ¿ha intentado pasar la doctrine servicio a su oyente en lugar del contenedor de servicio?

Como alternativa, ya está pasando el contenedor de servicio, por lo que debe ser tan simple como llamar al
$this->container->get('doctrine'). Además, me dijeron en el IRC hace un tiempo que pasar el contenedor de servicio generalmente se considera una mala práctica. Es mejor pasar los servicios individuales que necesita.

+0

Gracias, es una buena opción – Santi

0

No voy a poner la lógica de negocio a los oyentes como son sólo para escuchar a los eventos. Y cómo escribirías las pruebas para el oyente usando la doctrina ...

Me gustaría poner la doctrina accediendo a cosas en una clase diferente y luego llamarlo en el oyente.

2

Si su caso de uso permite el uso de una Doctrina Procesador de eventos directely

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

puede obtener el gestor de entidades de las 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(); 
     } 
    } 
} 
Cuestiones relacionadas