2012-01-11 26 views
9

Chúng tôi cần truy cập vào thông tin cơ sở dữ liệu trong một người nghe. Chúng tôi cấu hình người nghe trong một service.yml Người nghe cũng giống như:Truy cập vào cơ sở dữ liệu trong một người nghe trong 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) 
{ 
... 

Làm thế nào chúng ta có thể tiếp cận với học thuyết tại chức năng onKernelRequest?

tôi cố gắng kéo dài từ bộ điều khiển và làm:

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

và nó hoạt động nhưng tôi nghĩ rằng đây là một thực tế xấu.

+0

Nhờ tất cả ý kiến. Tất cả đều là lựa chọn tốt. – Santi

Trả lời

27

Bạn chỉ có thể tiêm vùng chứa dịch vụ. Đầu tiên thay đổi các nhà xây dựng để có được một EntityManager:

use Doctrine\ORM\EntityManager; 

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

Và tiếp theo cấu hình dịch vụ của bạn:

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

Cảm ơn, là một lựa chọn tốt – Santi

+3

Đây là tùy chọn tốt nhất. –

+0

Cảm ơn đã làm việc khi tôi thêm vào "sử dụng Symfony \ Component \ DependencyInjection \ ContainerInterface;" – someuser

2

Nó có vẻ như bạn đang tiêm container dịch vụ vào người nghe, vì vậy bạn có thể truy cập vào Học thuyết theo cách này:

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

tôi là loại mới làm quen với Symfony vẫn còn, nhưng bạn đã cố gắng vượt qua doctrine dịch vụ cho người nghe của bạn thay vì container dịch vụ?

Cách khác, bạn đã chuyển vùng chứa dịch vụ, vì vậy nó phải đơn giản như gọi
$this->container->get('doctrine'). Ngoài ra, tôi đã được nói ở IRC một thời gian trước rằng việc đi qua các container dịch vụ thường được coi là thực hành xấu. Tốt hơn là nên chuyển các dịch vụ riêng lẻ mà bạn cần.

+0

Cảm ơn, là một lựa chọn tốt – Santi

0

tôi sẽ không đặt logic kinh doanh với khán giả là những chỉ để nghe sự kiện. Và làm thế nào bạn sẽ viết các bài kiểm tra cho người nghe bằng cách sử dụng doctrine ...

Tôi sẽ đặt giáo lý truy cập vào một lớp khác và sau đó gọi nó trong người nghe.

2

Nếu trường hợp sử dụng của bạn cho phép bạn sử dụng một học thuyết Event Listener directely

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

bạn có thể lấy Entity Manager từ 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(); 
     } 
    } 
} 
Các vấn đề liên quan