首页 > 解决方案 > 如何为 Symfony 捆绑参数/配置值提供默认值?

问题描述

我创建了一个 Symfony 5.3+ 包,它应该用于将通用代码添加到不同的项目中。捆绑包包含一些服务,这些服务应该可以使用 Symfony 文档中描述的参数/选项进行配置。

如何为这些选项提供默认值?捆绑包中设置的默认值Configuration.php没有任何影响。


细节:

我使用以下结构创建了一个捆绑项目,并使用 composer 将其添加到我的 Symfony 项目中:

path/to/bundles/XYCommonsBundle/
    config/
        services.yaml
    src/
        Service/
            SomeService.php
        DependencyInjection
            Configuration.php
            XYCommensExtension.php
    XYCommensBundle.php
    composer.json
    ...


// src/DependencyInjection/XYCommensExtension.php
<?php

namespace XY\CommensBundle\DependencyInjection;

use ...

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

        // make config available as parameters. Necessary?
        foreach ($config as $key => $value) {
            $container->setParameter('xy_commons.' . $key, $value);
        }


        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../../config'));
        $loader->load('services.yaml');
    }
}


// src/DependencyInjection/Configuration.php
class Configuration implements ConfigurationInterface {
    public function getConfigTreeBuilder() {
        $treeBuilder = new TreeBuilder('xy_commons');
        
        $treeBuilder->getRootNode()
            ->children()
                ->arrayNode('params')
                    ->children()
                        ->integerNode('paramA')->defaultValue(100)->end()
                        ->integerNode('ParamB')->defaultValue(200)->end()
                    ->end()
                ->end()
            ->end()
        ;
        
        return $treeBuilder;
    }
}


// config/services.yaml
services:
    xy_commons.service.some_service:
        class:  XY\CommonsBundle\Service\SomeService
        arguments:   
            - $paramA: '%xy_commons.params.paramA%'
            - $paramB: '%xy_commons.params.paramB%' 


// src/Service/SomeService.php
<?php

namespace XY\CommensBundle\Service;

use ...

class SomeService {
    public function __construct(LoggerInterface $logger, $paramA, $paramB) {
}    

问题:如何使用参数的默认值?

paramA并在默认值为 100 和 200paramB的捆绑包中定义Configuration.php。我想在项目中使用这些默认值而不指定自定义值。但是,我没有config/packages/xy_commons.yaml在项目中创建文件并明确指定值,我收到以下错误:

您请求了一个不存在的参数“xy_commons.params.paramA”。

创建config/packages/xy_commons.yaml文件时,我不能使用~默认值:

xy_commons:
    params:
        paramA: ~
        paramB: ~

路径“xy_commons.params.paramA”的类型无效。预期为“int”,但得到“null”。

只有当明确指定一个值时它才有效:

xy_commons:
    params:
        paramA: 300
        paramB: 400

如何使用中定义的默认值Configuration.php

标签: symfonycomposer-phpautowired

解决方案


这里存在三个问题。第一个处理可能是我在 Symfony 中最不喜欢的课程。可怕的配置对象。特别是在处理数组时需要使用addDefaultsIfNotSet :

class Configuration implements ConfigurationInterface 
{
  public function getConfigTreeBuilder() 
  {
      $treeBuilder = new TreeBuilder('my');

      $rootNode = $treeBuilder->getRootNode();

      $rootNode
          ->children()
              ->arrayNode('params')->addDefaultsIfNotSet() # ADD THIS
                  ->children()
                      ->integerNode('paramA')->defaultValue(100)->end()
                      ->integerNode('paramB')->defaultValue(200)->end()
                  ->end()
              ->end()
          ->end()
      ;
      
      return $treeBuilder;
  }
}

第二个问题是您没有正确定义参数。特别是参数将被分组到一个称为 params 的数组中。你几乎拥有它:

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

        foreach($config['params'] as $key => $value) {
           $container->setParameter('xy_commons.params.' . $key, $value);
        }

# Use bin/console dump:container --parameters to verify

最后一件事是使用波浪号来表示默认值。我认为这可能是一个设计问题。从技术上讲,yaml 上的波浪号意味着 null 并且由处理器来获得它的含义。ArrayNode 按预期工作,但 IntegerNode 没有。所以这有效:

# config/packages/my.yaml
my:
    params: ~
#        paramA: ~
#        paramB: 666

推荐阅读