【问题标题】:How can I access the container in a before kernel listener in Symfony2?如何在 Symfony2 的内核监听器之前访问容器?
【发布时间】:2014-06-01 14:05:18
【问题描述】:

我尝试实现一个前内核侦听器 (see reference),在其中我只需设置一些参数值(我必须动态获取这些参数值,并且不能在我的 parameters.yml 文件中静态声明)。

这是我的监听类:

class AcmeListener
{
    public function onKernelController(FilterControllerEvent $event)
    {
        $event->getController()->getContainer()->setParameter('foo', 'bar');
    }
}

在我的config.yml:

services:
    kernel.listener.acme_listener:
        class: Acme\AcmeBundle\EventListener\AcmeListener
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

但我得到了一个

FatalErrorException: 错误:在非对象上调用成员函数 getContainer()

如果不是通过$event->getController() 中的getContainer(),我如何访问容器?

【问题讨论】:

    标签: symfony service kernel listener before-filter


    【解决方案1】:

    只需将容器作为参数添加到您的服务定义中。

    services:
        kernel.listener.acme_listener:
            class: Acme\AcmeBundle\EventListener\AcmeListener
            arguments:
                - @service_container
            tags:
                - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
    

    然后将构造函数添加到您的 AcmeListener 类,以便您可以访问它。

    use Symfony\Component\DependencyInjection\Container;
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    
    class AcmeListener
    {
        /**
         * @var Container
         */
        private $container;
    
        /**
         * Constructor
         *
         * @param Container $container
         */
        public function __construct(Container $container)
        {
                $this->container = $container;
        }
    
        public function onKernelController(FilterControllerEvent $event)
        {
                $this->container->...
        }
    }
    

    【讨论】:

    • 看起来很有希望,但我收到了 LogicException: Impossible to call set() on a frozen ParameterBag.
    • 我必须切换到onKernelRequest而不是onKernelController吗?
    • 可能。回顾我做这件事的时间,我使用了 onKernelRequest。这仍然符合您的需求吗?
    • 我现在看到了您的问题。文档提供了一些关于此的信息:“您只能在编译容器之前设置参数。要了解有关编译容器的更多信息,请参阅编译容器。” symfony.com/doc/current/components/dependency_injection/…
    • 您应该接受@Mark 的回答,因为它显示了如何访问容器。虽然我个人会实现 ContainerAware 接口,而不是将容器注入构造函数。但他的解决方案有效。完全更新冻结的参数包是另一个问题,基本上是不可能的。你需要使用语义配置来做这种事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-13
    相关资源
    最近更新 更多