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

问题描述 投票:0回答:8

我在 config.yml 文件中添加了一个设置,如下所示:

app.config:
    contact_email: [email protected]
    ...

对于我的一生,我不知道如何将其读入变量。我在我的一个控制器中尝试了类似的操作:

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

但是我收到一条错误消息:

参数“contact_email”必须是 定义。

我已经清除了缓存,我还到处查看了 Symfony2 重新加载的站点文档,但我不知道如何执行此操作。

现在可能太累了,无法弄清楚这一点。有人可以帮忙吗?

symfony configuration
8个回答
194
投票

不要在

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

parameters:
    contact_email: [email protected]

您应该会发现您在控制器中进行的调用现在可以正常工作了。


174
投票

虽然将

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

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

第一种方法:分离配置块,将其作为参数

通过扩展(更多关于扩展的信息),您可以轻松地将其“分离”到

config.yml
中的不同块中,然后将其作为可从控制器获取的参数注入。

DependencyInjection
目录中的扩展类中写入以下内容:

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: [email protected]

为了能够在

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' );

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

对于寻找类似内容但要从服务获取配置的读者来说,甚至有一种更好的方法,它永远不会弄乱“参数”公共空间,甚至不需要将

container
传递给服务(传递整个实践中要避免使用容器)。

上面的这个技巧仍然“注入”到您的配置的参数空间中。

尽管如此,在加载服务的定义后,您可以添加一个方法调用,例如

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' ];
    }
}

36
投票

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

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

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

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


16
投票

为了能够公开您的捆绑包的一些配置参数,您应该查阅相关文档。这很容易做到:)

这里是链接:如何公开捆绑包的语义配置


7
投票

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

“Symfony - 使用容器服务定义” 是一篇关于它的好文章。


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: [email protected]

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"));
    ...
    }

0
投票

控制器内部:

$this->container->getParameter('configname')

config/config.yaml
获取配置:

parameters:
   configname: configvalue

0
投票

从今天 2024 年 9 月 17 日起更新,Symfony 版本 7.1.3 你可以这样做:

$this->getParameter('app.category_modules')

获取配置变量,例如:

parameters: 
    app.locales:
        - bg
        - en
    app.default_language: 'bg' 
    app.category_modules:
        1: PRODUCTS
        2: TEXTS
© www.soinside.com 2019 - 2024. All rights reserved.