symfony / config arrayNode prototype addDefaultsIfNotSet

时间:2015-03-13 07:44:53

标签: php symfony

我很遗憾地说我找不到向“symfony / config”添加默认值的方法:“2.6.4”ConfigurationInterface!

这种配置需要什么:

X:
    Y:
        - test
        - testing

默认为:

X:
    Y:
        - test

“默认”我的意思是:如果没有在读配置文件上设置Y config分支,$ processor-> processConfiguration应该添加它(它确实如此!如果我删除了 - >原型......)

这是我的代码:

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

当然,我读了这个问题Using the Symfony2 configuration class, how do I define an array node whose children don't have keys?

我当前的代码实现了这种方式,因为你可以阅读,但它不起作用,我的代码抛出:

[Symfony\Component\Config\Definition\Exception\InvalidDefinitionException]
  ->addDefaultsIfNotSet() is not applicable to prototype nodes at path "X.Y"

3 个答案:

答案 0 :(得分:2)

作为参考,我终于通过一个变量节点得到它,就在用我的头撞到墙前一分钟;)

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 :(得分: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会很容易。

答案 2 :(得分:0)

您可以这样做:

$node
    ->fixXmlConfig('driver')
    ->children()
        ->arrayNode('drivers')
            ->scalarPrototype()->end()
        ->end()
    ->end()
;

这允许:

drivers: ['mysql', 'sqlite']

更多信息在这里 https://symfony.com/doc/current/components/config/definition.html#array-node-options