Symfony/Config的arrayNode原型addDefaultsIfNotSet

4
很抱歉我找不到在 "symfony/config": "2.6.4" ConfigurationInterface 中添加默认值的方法!
所需的配置应该是这样的:
X:
    Y:
        - test
        - testing

默认为:

X:
    Y:
        - test

所谓 "默认" 是指:如果读取配置文件中未设置 Y 配置分支,则 $processor->processConfiguration 应将其添加(实际上也是这样的!如果我删除 ->prototype...)

以下是我的代码:

class Definition implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root("X");
        $rootNode
            ->children()
                ->arrayNode("Y")
                    ->addDefaultsIfNotSet()
                    ->info("Multiple values can be used")
                    ->cannotBeEmpty()
                    ->addDefaultIfNotSet()
                    ->defaultValue(array("test"))
                    ->prototype("scalar")
                        ->validate()
                        ->ifNotInArray(array("test", "testing"))
                            ->thenInvalid("Invalid value %s")
                        ->end()
                    ->end()
                ->end()
            ->end()
        ;

        return $treeBuilder;
    }
}

当然,我阅读了这个问题: 使用Symfony2配置类,如何定义一个子节点没有键的数组节点? 正如您所读到的,我的当前代码实现方式不起作用,并会抛出以下错误:
[Symfony\Component\Config\Definition\Exception\InvalidDefinitionException]
  ->addDefaultsIfNotSet() is not applicable to prototype nodes at path "X.Y"
3个回答

2

作为参考,我最终通过一个variableNode实现了它,在撞墙前的一分钟内完成了。

class Definition implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root("X");
        $rootNode
            ->children()
                ->variableNode("Y")
                    ->info("Multiple values can be used")
                    ->cannotBeEmpty()
                    ->defaultValue(array("test"))
                    ->validate()
                        ->always(function ($values) {
                            foreach ((array) $values as $value) {
                                if (! in_array($value, array("test", "testing"))) {
                                    throw new \Symfony\Component\Config\Definition\Exception\InvalidTypeException("Invalid value ".$value);
                                }
                            }
                            return (array) $values;
                        })
                    ->end()
                ->end()
            ->end()
        ;

        return $treeBuilder;
    }
}

看起来用arrayNode没有办法做到这一点!但如果有人找到了方法,请不要犹豫回答,我很乐意接受使用arrayNode的答案,因为集成验证可能比我的更好...


1
什么情况:
<?php
    $rootNode
        ->children()
            ->arrayNode("Y")
                ->defaultValue(array("test"))
                ->prototype("scalar")
                    ->validate()
                    ->ifNotInArray(array("test", "testing"))
                        ->thenInvalid("Invalid value %s")
                    ->end()
                ->end()
            ->end()
        ->end()
    ;

另一个问题是,为什么不重构配置。您想要一个testtest,testingtesting的列表。为什么不像这样配置:
X:
  Y:
    test: true
    testing: false

如果默认情况下 X.Y.test = trueX.Y.testing = false,那么你的 Configuration 将非常简单。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接