如何从symfony2中的事件监听器发送var来查看?

 WEIAIXINGJIANMENG 发布于 2023-02-13 11:31

我试图从symfony2中的事件监听器发送var来查看,但我已经堆叠了.

1)这可能吗?

2)使用什么内核事件(kernel.view或kernel.request)?

3)最后如何发送一些var来查看?

我最好的猜测是,我必须从控制器延长返回,然后让控制器完成他的工作.

我需要发送一些对象(实体).

1 个回答
  • 我看到了几种处理这个问题的方法.

    kernel.request侦听器添加全局变量

    我们的想法是在kernel.request事件发生后直接添加一个全局变量.

    services.yml

    services:
        class: Acme\FooBundle\Listener\MyListener
        arguments:
            - @twig
        tags:
            -
                name: kernel.event_listener
                event: kernel.request
                method: onKernelRequest
    

    MyListener

    class MyListener
    {
        protected $twig;
    
        public function __construct(\Twig_Environment $twig)
        {
            $this->twig = $twig;
        }
    
        public function onKernelRequest(GetResponseEvent $event)
        {
            $myVar = 'foo'; // Process data
    
            $this->twig->addGlobal('myvar', $myVar);
        }
    }
    

    您现在可以随时使用它

    {{ myvar }}
    

    来自kernel.view听众

    首先,您需要了解何时kernel.view被调用.仅当控制器的返回不是Response对象的实例时才会调用它.
    那说,做

    // Acme/FooBundle/FooController#fooAction
    
    return $this->render();
    

    返回一个Response对象,因此kernel.view不会被调用.

    定义控制器

    我们的想法是让所有控制器返回一个数据数组,就像@Template要求一样.

    // Acme/FooBundle/FooController#fooAction
    
    return array(
        'template' => 'AcmeFooBundle:Foo:foo.html.twig',
        'data' => array(
            'entity' => $entity
        )
    );
    

    定义服务

    由于您已经拥有服务定义,因此您只需在服务声明中添加一些要求即可.
    您需要该@templating服务来呈现数据.
    您需要将自己设置为kernel.view侦听器

    // Acme/FooBundle/Resources/config/services.yml
    
    services:
        acme_foo.my_listener:
            class: Acme\FooBundle\Listener\MyListener
            arguments:
                - @templating
            tags:
                -
                    name: kernel.event_listener
                    event: kernel.request
                    method: onKernelRequest
                -
                    name: kernel.event_listener
                    event: kernel.view
                    method: onKernelView
    

    创建服务

    // Acme/FooBundle/Listener/MyListener.php
    
    use Symfony\Component\Templating\EngineInterface;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
    
    class MyListener
    {
        protected $templating;
        protected $myVar;
    
        public function __construct(EngineInterface $templating)
        {
            $this->templating = $templating;
        }
    
        public function getMyVar()
        {
            return $this->myVar;
        }
    
        public function onKernelRequest(GetResponseEvent $event)
        {
            $this->myVar = ""; // Process MyVar data
        }
    
        public function onKernelView(GetResponseForControllerResultEvent $event)
        {
            $result = $event->getControllerResult();
    
            if (null === $this->myVar || !isset($result['template']) || !isset($result['data'])) {
                return;
            }
    
            $data = array_merge($result['data'], array('myvar' => $this->myVar));
            $rendered = $this->templating->render($result['template'], $data);
    
            $event->setResponse(new Response($rendered));
        }
    }
    

    你有.监听器正在创建一个新的响应,将您的自定义定义添加myvar到他呈现的任何模板中.


    来自TWIG扩展

    另一种方法是创建TWIG扩展.在下面的例子中,我假设MyListener定义与上面相同.

    定义服务

    根据上面给出的文档,您只需创建一个简单的扩展类.

    // Acme/FooBundle/Resources/config/services.yml
    
    services:
        acme_foo.my_listener:
            class: Acme\FooBundle\Listener\MyListener
            tags:
                - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        acme_foo.my_extension:
            class: Acme\FooBundle\Extension\MyExtension
            arguments:
                - @acme_foo.my_listener
            tags:
                - { name: twig.extension }
    

    定义服务

    就像在文档中一样,我们将创建一个简单的函数.

    // Acme/FooBundle/Extension/MyExtension.php
    
    use Acme\FooBundle\Listener\MyListener;
    
    class MyExtension extends \Twig_Extension
    {
        protected $listener;
    
        public function __construct(MyListener $listener)
        {
            $this->listener = $listener;
        }
    
        public function getName()
        {
            return 'my_extension';
        }
    
        public function getFunctions()
        {
            return array(
                'myvar' => new \Twig_Function_Method($this, 'getMyVar')
            );
        }
    
        public function getMyVar()
        {
            return $this->listener->getMyVar();
        }
    }
    

    用法

    然后你可以在任何视图中使用它

    {{ myvar() }}
    

    从一个普通的控制器

    我不喜欢这个想法,但这是另一种选择.您只需要创建一个BaseController将覆盖默认render方法.

    // Acme/FooBundle/Controller/BaseController.php
    
    abstract class BaseController extends Controller
    {
        public function render($view, array $parameters = array(), Response $response = null)
        {
            $parameters = array_merge(
                $parameters,
                array(
                    'myvar' => $this->get('my_listener')->getMyVar()
                )
            );
    
            return parent::render($view, $parameters, $response);
        }
    }
    

    2023-02-13 11:33 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有