我的配置节点source
是否支持string
和array
值?
从string
采购:
# Valid configuration 1
my_bundle:
source: %kernel.root_dir%/../Resources/config/source.json
从array
采购:
# Valid configuration 2
my_bundle:
source:
operations: []
commands: []
扩展类可以区分它们:
if (is_array($config['source']) {
// Bootstrap from array
} else {
// Bootstrap from file
}
我可能会使用这样的东西:
$rootNode->children()
->variableNode('source')
->validate()
->ifTrue(function ($v) { return !is_string($v) && !is_array($v); })
->thenInvalid('Configuration value must be either string or array.')
->end()
->end()
->end();
但是我如何向变量节点添加source
(操作,命令等等)的结构约束(只应在其值为array
时强制执行) ?
答案 0 :(得分:20)
我认为您可以通过重构扩展程序来使用配置规范化。
在您的扩展程序中更改代码以检查路径是否已设置
if ($config['path'] !== null) {
// Bootstrap from file.
} else {
// Bootstrap from array.
}
并允许用户使用字符串进行配置。
$rootNode
->children()
->arrayNode('source')
->beforeNormalization()
->ifString()
->then(function($value) { return array('path' => $value); })
->end()
->children()
->scalarNode('foo')
// ...
->end()
->end()
->end()
;
像这样,您可以允许用户使用可以验证的字符串或数组。
请参阅symfony documentation for normalisation
希望它有用。 最好的。
答案 1 :(得分:7)
可以将variable node类型与一些自定义验证逻辑结合使用:
<?php
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('my_bundle');
$rootNode
->children()
->variableNode('source')
->validate()
->ifTrue(function ($v) {
return false === is_string($v) && false === is_array($v);
})
->thenInvalid('Here you message about why it is invalid')
->end()
->end()
->end();
;
return $treeBuilder;
}
这将成功完成:
my_bundle:
source: foo
# and
my_bundle:
source: [foo, bar]
但它不会处理:
my_bundle:
source: 1
# or
my_bundle
source: ~
当然,您将无法获得正常配置节点将为您提供的良好验证规则,并且您将无法在传递的数组(或字符串)上使用这些验证规则,但您将能够验证在使用的闭包中传递数据。