dongyuan1160 2015-12-21 01:06
浏览 11
已采纳

使用ArrayNodeDefinition :: addDefaultChildrenIfNoneSet()的奇怪行为

I'm using Symfony Config Component in Silex framework and I need to have an array of data which holds an array of versions :

some_data:
    # some config...
    versions:
        - 1.1
        - 1.2-beta
        ...

Here's a glimpse at the config tree builder :

$node = $treeBuilder->root('some_data');

$node
    ->children()
        // some nodes...
        ->arrayNode('versions')
            ->addDefaultChildrenIfNoneSet()
            ->validate()
                ->ifTrue(function ($v) {
                    return !empty($v);
                })
                ->then(function ($v) {
                    $array = array_values(array_unique($v));
                    sort($array, SORT_NATURAL | SORT_FLAG_CASE);

                    return $array;
                })
            ->end()
            ->prototype('scalar')->defaultValue('1')->end()
        ->end()
    ->end()
->end()

When no versions are set I got default 1, alright. But when I add some other versions and then try to delete default value 1, it always comes back after processing config.

Does someone understand what I am doing wrong ? Is it an expected behaviour ?

  • 写回答

1条回答 默认 最新

  • douxie1894 2016-01-16 08:42
    关注

    It seems that addDefaultChildrenIfNoneSet() acts as a validation and while processing configuration both addDefaultChildrenIfNoneSet() and ->validate() result are merged.

    To avoid this behaviour just add performNoDeepMerging() to the node :

    $node = $treeBuilder->root('some_data');
    
    $node
        ->children()
            // some nodes...
            ->arrayNode('versions')
                ->addDefaultChildrenIfNoneSet()
                ->performNoDeepMerging() // This is the fix
                ->validate()
                    ->ifTrue(function ($v) {
                        return !empty($v);
                    })
                    ->then(function ($v) {
                        $array = array_values(array_unique($v));
                        sort($array, SORT_NATURAL | SORT_FLAG_CASE);
    
                        return $array;
                    })
                ->end()
                ->prototype('scalar')->defaultValue('1')->end()
            ->end()
        ->end()
    ->end()
    

    see http://symfony.com/doc/current/components/config/definition.html#optional-sections

    another ways to do it :

    // add a default value on the array, not on the prototype :
    $node
        ->children()
            // some nodes...
            ->arrayNode('versions')
                ->validate()
                    ->ifTrue(function ($v) {
                        return !empty($v);
                    })
                    ->then(function ($v) {
                        $array = array_values(array_unique($v));
                        sort($array, SORT_NATURAL | SORT_FLAG_CASE);
    
                        return $array;
                    })
                ->end()
                ->prototype('scalar')->end()
                ->defaultValue(['1']) // this is a fix
            ->end()
        ->end()
    ->end()
    
    // or just use one validation rule
    $node
        ->children()
            // some nodes...
            ->arrayNode('versions')
                ->validate()
                    ->always(function ($v) { // another fix
                        if (empty($v)) {
                            return ['1'];
                        }
    
                        $array = array_values(array_unique($v));
                        sort($array, SORT_NATURAL | SORT_FLAG_CASE);
    
                        return $array;
                    })
                ->end()
                ->prototype('scalar')->end()
            ->end()
        ->end()
    ->end()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 wpf界面一直接收PLC给过来的信号,导致UI界面操作起来会卡顿
  • ¥15 init i2c:2 freq:100000[MAIXPY]: find ov2640[MAIXPY]: find ov sensor是main文件哪里有问题吗
  • ¥15 运动想象脑电信号数据集.vhdr
  • ¥15 三因素重复测量数据R语句编写,不存在交互作用
  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了