Php 使用ArrayNodeDefinition::AddDefaultChildreniFuneset()的奇怪行为
我在Silex framework中使用的是Symfony配置组件,我需要有一个数据数组来保存一个版本数组:Php 使用ArrayNodeDefinition::AddDefaultChildreniFuneset()的奇怪行为,php,symfony,yaml,config,Php,Symfony,Yaml,Config,我在Silex framework中使用的是Symfony配置组件,我需要有一个数据数组来保存一个版本数组: some_data: # some config... versions: - 1.1 - 1.2-beta ... 下面是对配置树生成器的简要介绍: $node = $treeBuilder->root('some_data'); $node ->children() // some
some_data:
# some config...
versions:
- 1.1
- 1.2-beta
...
下面是对配置树生成器的简要介绍:
$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()
当没有设置版本时,我得到了默认的1
,好的。
但当我添加一些其他版本,然后尝试删除默认值1
,它总是在处理配置后返回
有人知道我做错了什么吗?
这是一种预期行为吗?似乎addDefaultChildrenIfNoneSet()
充当验证,并且在处理配置时,将addDefaultChildrenIfNoneSet()
和->validate()
结果合并
要避免这种行为,只需向节点添加performNoDeepMerging()
:
$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()
看
另一种方法是:
// 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()
似乎addDefaultChildrenIfNoneSet()
充当验证,在处理配置时,将addDefaultChildrenIfNoneSet()
和->validate()
结果合并
要避免这种行为,只需向节点添加performNoDeepMerging()
:
$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()
看
另一种方法是:
// 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()