【问题标题】:Access to database in a listener in Symfony 2在 Symfony 2 的监听器中访问数据库
【发布时间】:2012-02-08 01:29:24
【问题描述】:

我们需要在监听器中访问数据库信息。 我们在 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(); 

它有效,但我认为这是一种不好的做法。

【问题讨论】:

  • 感谢所有 cmets。都是不错的选择。

标签: symfony doctrine-orm listener bundle


【解决方案1】:

您可以只注入服务容器。先改构造函数,得到一个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

【讨论】:

  • 谢谢,一旦我添加了“使用 Symfony\Component\DependencyInjection\ContainerInterface;”,它就起作用了
【解决方案2】:

如果您的用例允许您直接使用 Doctrine 事件监听器

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

您可以从 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();
        }
    }
}

【讨论】:

    【解决方案3】:

    您似乎将服务容器注入到侦听器中,因此您可以通过这种方式访问​​ Doctrine:

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

    【讨论】:

      【解决方案4】:

      我还是 Symfony 的新手,但是您是否尝试过将 doctrine 服务传递给您的侦听器而不是服务容器?

      或者,您已经在传递服务容器,所以它应该像调用
      $this-&gt;container-&gt;get('doctrine') 一样简单。另外,前段时间在 IRC 中有人告诉我,传递服务容器通常被认为是不好的做法。最好传递您需要的个别服务。

      【讨论】:

        【解决方案5】:

        我不会将业务逻辑放在监听器中,因为它们仅用于监听事件。以及如何使用教义为听众编写测试...

        我会将访问内容的原则放在不同的类中,然后在侦听器中调用它。

        【讨论】:

          【解决方案6】:

          在 symfony 4 中你应该像这样使用依赖注入

          class eventSubscriber implements EventSubscriberInterface
          {
              /**
               * @var EntityManagerInterface
               */
              private $em;
          
          
           public function __construct(EntityManagerInterface $em)
              {
          
                  $this->em = $em;
              }
          }
          

          【讨论】:

          • 还是需要配置服务并通过EntityManager服务,否则会报auto-wire错误。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-07-27
          • 2016-10-23
          • 1970-01-01
          • 2016-02-09
          • 2013-07-04
          • 2015-09-02
          • 1970-01-01
          相关资源
          最近更新 更多