如何从Symfony2 config.yml读取配置设置?

时间:2011-01-27 20:50:21

标签: symfony configuration

我已经在config.yml文件中添加了一个设置:

app.config:
    contact_email: somebody@gmail.com
    ...

对于我的生活,我无法弄清楚如何将其读入变量。我在我的一个控制器中尝试过类似的东西:

$recipient =
$this->container->getParameter('contact_email');

但是我收到一个错误说:

  

参数“contact_email”必须是   定义

我已经清除了我的缓存,我也在Symfony2重新加载的网站文档中查看了所有内容,但我无法知道如何执行此操作。

现在可能只是太累了。任何人都可以帮忙吗?

6 个答案:

答案 0 :(得分:192)

不是在contact_email中定义app.config,而是在parameters条目中定义它:

parameters:
    contact_email: somebody@gmail.com

您应该可以在控制器中找到正在进行的通话。

答案 1 :(得分:168)

虽然将contact_email移动到parameters.yml的解决方案很容易,但正如其他答案中所提出的那样,如果您处理许多捆绑或者如果您处理嵌套块,则很容易使参数文件混乱配置。

  • 首先,我将严格回答这个问题。
  • 稍后,我将提供一种从服务中获取这些配置的方法,而不必通过公共空间作为参数。

FIRST APPROACH:分离配置块,将其作为参数

使用扩展程序(more on extensions here),您可以轻松地保持这种状态并且分开#34;进入config.yml中的不同块,然后将其作为参数gettable从控制器中注入。

DependencyInjection目录内的Extension类中写下这个:

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        // The next 2 lines are pretty common to all Extension templates.
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // This is the KEY TO YOUR ANSWER
        $container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ] );

        // Other stuff like loading services.yml
    }

然后在你的config.yml,config_dev.yml中,你可以设置

my_nice_project:
    contact_email: someone@example.com

为了能够在config.yml内处理MyNiceBundleExtension,您还需要在同一命名空间中使用Configuration类:

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root( 'my_nice_project' );

        $rootNode->children()->scalarNode( 'contact_email' )->end();

        return $treeBuilder;
    }
}

然后,您可以根据原始问题的需要从控制器获取配置,但保持parameters.yml清洁,并将其设置在config.yml的分隔部分中:

$recipient = $this->container->getParameter( 'my_nice_project.contact_email' );

第二种方法:分离配置块,将配置注入服务

对于那些寻找类似东西但是从服务中获取配置的读者来说,甚至有一种更好的方法可以让#34; paramaters"公共空间,甚至不需要将container传递给服务(传递整个容器是为了避免)。

上面的这个技巧仍然是#34;注入"进入参数空间你的配置。

然而,在加载服务定义之后,您可以添加一个方法调用,例如setConfig(),只将该块注入服务。

例如,在Extension类中:

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // Do not add a paramater now, just continue reading the services.
        $loader = new YamlFileLoader( $container, new FileLocator( __DIR__ . '/../Resources/config' ) );
        $loader->load( 'services.yml' );

        // Once the services definition are read, get your service and add a method call to setConfig()
        $sillyServiceDefintion = $container->getDefinition( 'my.niceproject.sillymanager' );
        $sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'contact_email' ] ) );
    }
}

然后在services.yml中,您照常定义服务,不做任何绝对更改:

services:
    my.niceproject.sillymanager:
        class: My\NiceProjectBundle\Model\SillyManager
        arguments: []

然后在您的SillyManager课程中,只需添加方法:

class SillyManager
{
    private $contact_email;

    public function setConfig( $newConfigContactEmail )
    {
        $this->contact_email = $newConfigContactEmail;
    }
}

请注意,这也适用于数组而不是标量值!想象一下,您配置了一个兔子队列并需要主机,用户和密码:

my_nice_project:
    amqp:
        host: 192.168.33.55
        user: guest
        password: guest

当然你需要更改你的树,但是你可以这样做:

$sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'amqp' ] ) );

然后在服务中执行:

class SillyManager
{
    private $host;
    private $user;
    private $password;

    public function setConfig( $config )
    {
        $this->host = $config[ 'host' ];
        $this->user = $config[ 'user' ];
        $this->password = $config[ 'password' ];
    }
}

希望这有帮助!

答案 2 :(得分:34)

我必须添加道格拉斯的答案,你可以访问全局配置,但symfony翻译一些参数,例如:

# config.yml
... 
framework:
    session:
        domain: 'localhost'
...

$this->container->parameters['session.storage.options']['domain'];

您可以使用var_dump搜索指定的键或值。

答案 3 :(得分:17)

为了能够公开捆绑包的某些配置参数,您应该参考文档来执行此操作。这很容易做到:)

以下是链接:How to expose a Semantic Configuration for a Bundle

答案 4 :(得分:7)

就像之前所说的那样 - 您可以使用注入容器访问任何参数并使用其参数属性。

"Symfony - Working with Container Service Definitions"是关于它的好文章。

答案 5 :(得分:3)

我从http://tutorial.symblog.co.uk/

的代码示例中学到了一种简单的方法

1)注意ZendeskBlueFormBundle和文件位置

# myproject/app/config/config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: @ZendeskBlueFormBundle/Resources/config/config.yml }

framework:

2)注意Zendesk_BlueForm.emails.contact_email和文件位置

# myproject/src/Zendesk/BlueFormBundle/Resources/config/config.yml

parameters:
    # Zendesk contact email address
    Zendesk_BlueForm.emails.contact_email: dunnleaddress@gmail.com

3)注意我如何在$ client和控制器的文件位置

中获取它
# myproject/src/Zendesk/BlueFormBundle/Controller/PageController.php

    public function blueFormAction($name, $arg1, $arg2, $arg3, Request $request)
    {
    $client = new ZendeskAPI($this->container->getParameter("Zendesk_BlueForm.emails.contact_email"));
    ...
    }