如何在Symfony2中动态设置参数?

Got*_*bel 10 service kernel before-filter listener symfony

我正在尝试在Symfony2中动态设置一个参数(我无法在我的parameters.yml文件中静态设置).我的方法是使用EventListener:

namespace Acme\AcmeBundle\EventListener;

use Symfony\Component\DependencyInjection\Container;

class AcmeListener
{
    private $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function onKernelRequest()
    {
        // Dynamically fetch $bar
        $bar = fetch('foobar');

        // Set parameter
        $this->container->setParameter('foo', $bar);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的服务定义config.yml如下所示:

service:
    kernel.listener.acme_listener:
        class: Acme\AcmeBundle\EventListener\AcmeListener
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
        arguments: [ '@service_container' ]
Run Code Online (Sandbox Code Playgroud)

问题是,我得到一个例外:

LogicException:无法在冻结的ParameterBag上调用set().

我如何解决此异常,或者您是否看到另一种动态设置参数的方法?

Mar*_*nte 10

容器参数规则是:

您只能在编译容器之前设置参数

如何解决问题取决于您的需求,前提是容器不被认为具有动态参数.

  1. 创建自定义动态"选项"服务并将其注入其他服务,这样你也可以在数据库中管理你的参数(如wordpress wp_options),但我不知道这样做的捆绑.对于现有服务(例如邮件程序),您可以使用配置程序.

  2. 当参数更改时,缓存使缓存无效是一种简单的方法,因此当您重新加载页面时,将重建容器.如果参数频繁更改,则可能会频繁重新加载缓存,如果您的负载较大,则会出现问题.

如果选择第二个选项,则需要在填充容器之前设置参数,这样您就可以:

  • 在清除缓存之前参数更改时,在app/config/config.yml中加载的自定义yaml文件中导出,这样您就可以从其他服务获取数据
  • 在这个cookbook中加载一个bundle扩展的参数,这样你就无法访问其他服务来获取数据,扩展只能访问containerbuilder

但是,我建议选项1(选项服务和配置程序)因为(我重复)容器不被认为具有动态参数,但它提供了使用来自任何源的数据的自定义动态服务配置器的能力.