我试图在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);
}
}
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' ]
问题是,我得到一个例外:
LogicException:无法在冻结的ParameterBag上调用set()。
我如何解决此异常,或者您是否看到另一种动态设置参数的方法?
答案 0 :(得分:9)
容器参数规则是:
您只能在编译容器之前设置参数
如何解决问题取决于您的需求,前提是容器不被认为具有动态参数。
创建自定义动态“选项”服务并将其注入其他服务,这样您也可以在数据库中管理您的参数(如wordpress wp_options),但我不知道这样做的捆绑。对于现有服务(例如邮件程序)you can use configurators。
在参数更改here an easy method时使缓存无效,因此当您重新加载页面时,将重建容器。如果参数频繁更改,则可能会频繁重新加载缓存,如果您的负载较大,则会出现问题。
如果你选择了第二个选项,你需要在容器填充之前设置参数,这样你就可以:
然而,我建议选项1(选项服务和配置程序)因为(我重复)容器不被认为具有动态参数,但它提供了使用来自任何源的数据的自定义动态服务配置器的能力。
答案 1 :(得分:1)
当我想要执行故障转移系统时,我在%base_url%
开头的网址列表中遇到了问题。
我最终将%base_url%
替换为#base_url#
并在服务中执行了手动占位符解析。
$tries = array (
$this->container->getParameter('base_url'),
$this->container->getParameter('base_url_failover'),
);
foreach ($tries as $try)
{
$url = str_replace('#base_url#', $try, $unresolvedUrl);
// whatever
}
答案 2 :(得分:0)
我认为我们可以将参数作为简单的类函数添加到服务中。
这是我的控制器功能。
/**
* @Route("/products/checkService")
* @Template()
*/
public function checkServiceAction() {
$paypal = $this->get('Paypal');
return new Response($paypal->chkVal('dsdd'));
}
这是我的服务
<?php
namespace Eagle\ShopBundle\Services;
use Symfony\Component\HttpFoundation\Response;
class Paypal {
public function __construct($var) {
$this->paypalCongig = $var;
}
public function getVal() {
return $this->paypalCongig;
}
public function chkVal($var) {
return $var;
}
}