【问题标题】:Symfony 3.4: Access doctrine within an EventListenerSymfony 3.4:在 EventListener 中访问学说
【发布时间】:2018-04-28 21:43:01
【问题描述】:

我正在尝试访问测试数据库表的 EventListener 中的学说,如果它无效,则用户将被重定向到他将解决问题的配置页面!

测试将在每次调用控制器之前执行,所以我将使用 Event kernel.controller:

[已编辑:已解决、测试和重定向非常好]

<?php

namespace AdminBundle\EventListener;

use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Session;

class BuildReferencesEventListener
{
    /**
     * @var EntityManager
     */
    protected $em;
    /**
     * @var Router
     */
    protected $router;
    protected $references = [
        1 => 'oxygen',
        2 => 'pH',
        3 => 'pCO2'
    ];
    protected $redirect_route = 'references';
    protected $requestStack;
    protected $session;

    public function __construct(EntityManager $entityManager, Router $router, RequestStack $requestStack, Session $session)
    {
        $this->em = $entityManager;
        $this->router = $router;
        $this->requestStack = $requestStack;
        $this->session = $session;
    }

    public function onKernelController()
    {
        $em = $this->em;
        $savedReferences = $em->getRepository('AdminBundle:ParamReference')->findAll();
        $references = $this->references;

        if (count($savedReferences) <= 0){
            $this->redirect();
        }

        for ($i =0; $i<count($savedReferences); $i++){
            if ($savedReferences[$i] !== $references[$i]) {
                $this->redirect();
            }
        }
    }

    public function redirect()
    {
        $request = $this->requestStack->getCurrentRequest();
        $route = $request->get('_route');
        $this->session->getFlashBag()->add('warning', 'You need to setup the references for the parameters before starting the work');
        if ($route != 'references'){
            $url = $this->router->generate('references');
            $redirect = new RedirectResponse($url);
            $redirect->send();
        }
    }
}

这里是 services.yml

build.references:
    class: AdminBundle\EventListener\BuildReferencesEventListener
    arguments: ['@doctrine.orm.entity_manager', '@router', '@request_stack', '@session']
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

【问题讨论】:

    标签: symfony doctrine symfony-3.4


    【解决方案1】:

    在你的 service.yml 事件监听器服务部分添加参数

    Your.service:
        Class: AdminBundle\EventListener\BuildReferencesEventListener
        arguments: ['@doctrine.orm.entity_manager']
        tags:
            - { name: kernel.event_listener, event: kernel.controller }
    

    并在您的列表器中添加此 __cunstruct 代码:

    namespace AdminBundle\EventListener;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    use Doctrine\ORM\EntityManager;
    
    class BuildReferencesEventListener
    {
    
        protected $em;
    
        function __construct(EntityManager $em)
        {
            $this->em = $em;
        }
    
        public function onKernelController(FilterControllerEvent $event)
        {
            //TO DO call doctrine
            // $em = Enity Manager...
            // $em->getRepository...
            // I hope its clear enough what im trying to do
        }
    

    【讨论】:

    • 在我尝试这个之前,你能给我一个如何命名服务的例子吗?因为你说的是​​Your.service,但我不太理解这种形式。
    • 你的事件可以有一个像build.reference.event这样的名字,它可以是你喜欢的任何名字,你可以很容易地在你的应用程序中调用一个服务$this-&gt;get('build.reference.event')。 $this 用于对象容器,如果您没有直接获得容器,请使用像这样的调用$this-&gt;container-&gt;get('build.reference.event')。为了更好地理解这里的文档:symfony.com/blog/…
    • 如果您得到了有效的答案,则标记为正确,这样其他开发人员将专注于其他问题以提供更多帮助。
    • 我正在尝试获取 Http 响应,例如渲染视图或重定向到路由!那可能吗?检查上面的代码我做了一个编辑。
    • 为了更好地理解看这个stackoverflow.com/questions/40433405/…
    【解决方案2】:

    在 Symfony 3.4 及更高版本中,默认情况下启用自动装配,因此您只需向服务的构造函数方法添加一个类型提示的参数,并为该参数的值分配一个私有属性。

    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    
    class BuildReferencesEventListener
    {
        private $em;
    
        public __construct(EntityManagerInterface $em)
        {
            $this->em = $em;
        }
    
        public function onKernelController(FilterControllerEvent $event)
        {
            $em = this->em;
            // [...]
        }
    
    }
    



    如果您需要 显式声明参数,您可以在服务配置中执行此操作:

    # config/services.yaml
    services:
        # ... same code as before
    
        # explicitly configure the service
        AdminBundle\EventListener\BuildReferencesEventListener:
            arguments:
                $em: '@doctrine.orm.entity_manager_interface'
    

    这对于传递服务容器不知道的参数很有用。

    要了解有关服务容器的更多信息,https://symfony.com/doc/3.4/service_container.html#injecting-services-config-into-a-service。

    【讨论】:

    • 我正在尝试获取 Http 响应,例如渲染视图或重定向到路由!那可能吗?检查上面的代码我做了一个编辑。
    • 无法自动装配服务“AdminBundle\EventListener\BuildReferencesEventListener”:方法“__construct()”的参数“$entityManager”引用类“Doctrine\ORM\EntityManager”,但不存在此类服务。尝试将类型提示更改为其父项之一:接口“Doctrine\ORM\EntityManagerInterface”或接口“Doctrine\Common\Persistence\ObjectManager”。
    • 你试过这样做吗?用建议的接口之一替换类型提示?
    • 第一个 anwser 工作正常,我只需要将参数添加到配置中
    猜你喜欢
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    • 2023-03-18
    • 2019-12-28
    • 2019-02-21
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    相关资源
    最近更新 更多