Symfony捆绑包配置数组节点默认值合并

时间:2019-02-21 13:41:52

标签: php symfony configuration bundle symfony4

我对Symfony4捆绑包配置有疑问。我有一个配置类:

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

这将返回默认配置,例如:

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"
}

如何设置此默认值以与提供的配置合并?当然,我想让“默认”配置被覆盖,但是默认情况下要被合并。

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

请帮助:)

2 个答案:

答案 0 :(得分:0)

如果我正确理解,您希望始终定义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值一起添加。它对解析的一个配置文件起作用。但是,如果您有两个以上的配置文件,则会遇到问题:

# 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合并。

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

一个好的解决方案

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

答案 1 :(得分:-1)

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

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

addDefaultsIfNotSet将添加您的默认值。 ignoreExtraKeys使您可以像示例中一样定义其他键。 最好完全配置密钥,因为您可以更好地控制它们。