Symfony bundle 配置数组节点默认值合并

Symfony bundle configuration array node default value merge

我对 Symfony4 捆绑配置有疑问。我的配置 class 具有:

$rootNode
        ->children()
            ->arrayNode('mapping')
                ->useAttributeAsKey('code')
                ->prototype('scalar')->end()
                ->defaultValue(['default' => 'test'])
            ->end()
            .....
        ->end();

此 returns 默认配置如下:

array(1) {
   ["default"]=> string(4) "test"
}

但是当我添加配置文件时:

bundle:
    mapping:
        test: newvalue
        test2: newvalue2

我正在获取配置:

array(2) {
   ["test"]=> string(8) "newvalue"
   ["test2"]=> string(9) "newvalue2"
}

但我希望合并这两个配置以获得:

array(3) {
   ["default"]=> string(4) "test"
   ["test"]=> string(8) "newvalue"
   ["test2"]=> string(9) "newvalue2"
}

如何将此默认值设置为与提供的配置合并?当然,我想让 "default" 配置被覆盖,但默认情况下会被合并。

我在文档上找不到任何解决方案https://symfony.com/doc/current/components/config/definition.html#array-node-options

请帮忙:)

为此,您必须更深入地定义阵列配置:

$treeBuilder
   ->children()
       ->arrayNode('mapping')
           ->ignoreExtraKeys()
           ->addDefaultsIfNotSet()
           ->children()
               ->scalarNode('default')
                   ->defaultValue('test)
               ->end()
           ->end()
       ->end()
   ->end()

addDefaultsIfNotSet 将添加您的默认值。 ignoreExtraKeys 允许您像示例中那样定义其他键。 最好把按键全部配置好,因为你可以更好地控制它们。

如果我理解正确的话,您希望 default 条目始终被定义。应用程序将能够覆盖 default 键的默认值 DEFAULT

好的,有两个解决方案:

一个糟糕的解决方案

    $rootNode = $treeBuilder->getRootNode()
        ->children()
            ->arrayNode('mapping')
                ->useAttributeAsKey('code')
                ->prototype('scalar')->end()
                ->beforeNormalization()
                    ->ifArray()
                    ->then(function ($mapping) {
                        return $mapping + ['default' => 'DEFAULT'];
                    })
                ->end()
            ->end();

如果未定义默认键,它将与默认 DEFAULT 值一起添加。它将对 ONE 配置文件进行解析。但是如果你有两个或更多的配置文件,你就会遇到问题:

# config.yml
mapping:
    some: value
    default: MY_DEVELOPMENT_DEFAULT

# prod/config.yml
mapping:
    some: value_prod

您将拥有:

['some' => 'value_prod', 'default' => 'DEFAULT']

这是错误的。默认值替换 MY_DEVELOPMENT_DEFAULT 因为它被添加到 prod/config.yml 并与 config.yml.

合并

不幸的是,树生成器不允许在合并后定义回调。

很好的解决方案

您可以在合并配置值后添加默认条目(例如,在编译器传递中)。