为矩阵定义 Symfony 配置
Define Symfony Configuration for matrix
我想要捆绑包的下一个 Symfony 配置:
'foo' => [
'bar' => [
'item_1' => [
[
'id' => '25',
'url' => 'https://foo',
],
[
'id' => '26',
'url' => 'https://bar',
],
],
],
]
我想保留所有密钥,所以我使用了 useAttributeAsKey
:
class Configuration implements ConfigurationInterface
{
/**
* Generates the configuration tree builder.
*
* @return TreeBuilder $builder The tree builder
*/
public function getConfigTreeBuilder()
{
$builder = new TreeBuilder();
$rootNode = $builder->root('foo');
$rootNode->children()
->arrayNode('bar')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->scalarNode('id')->end()
->scalarNode('url')->end()
->end()
->end()
->end()
->end();
return $builder;
}
}
但是,我收到了这个错误:
"Unrecognized options "0, 1" under "foo.bar.item_1""
正在阅读 https://symfony.com/doc/4.4/components/config/definition.html 我知道这应该行得通。有什么想法吗?
这是您的配置 class 希望您提供的输入数组示例:
'foo' => [
'bar' => [
'item_1' => [
'id' => '25',
'url' => 'https://foo',
],
'item_2' => [
'id' => '26',
'url' => 'https://bar',
],
],
]
似乎没有开箱即用的方法来创建问题中所示的配置。不过,这里有几个选项:
选项 1
如果您可以在 item_{1}
下创建额外的嵌套级别,那么您可以这样做:
'foo' => [
'bar' => [
'item_1' => [
// `rows` is an additional nesting level
'rows' => [
[
'id' => '25',
'url' => 'https://foo',
],
[
'id' => '26',
'url' => 'https://bar',
]
]
],
'item_2' => [
'rows' => [
[
'id' => '27',
'url' => 'https://foo',
]
]
]
]
]
$rootNode->children()
->arrayNode('bar')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->arrayNode('rows')
->arrayPrototype()
->children()
->scalarNode('id')->end()
->scalarNode('url')->end()
->end()
->end()
->end()
->end()
// If you'd like, you can git rid of the extra
// nesting level in the parsed configuration
->validate()
->always()
->then(function ($v) {
return $v['rows'] ?? [];
})
->end()
->end()
->end();
选项 2
如果您绝对必须使用您在问题中提供的输入配置结构(即没有额外的嵌套级别),看起来唯一的选择是对 bar
使用 variableNode 并手动执行验证:
$rootNode->children()
->variableNode('bar')
->validate()
->ifTrue( function($barConfig) {
// the config under `bar` has to be an array
if (!is_array($barConfig)) {
return true;
}
return 0 < count(array_filter($barConfig, function ($rowConfig) {
// every item under `item_1`, `item_2`... keys also has to be an array
if (!is_array($rowConfig)) {
return true;
}
return 0 < count(array_filter($rowConfig, function ($cellConfig) {
// every cell has to be an array with `id` and `url` keys
return !is_array($cellConfig) || empty($cellConfig['id']) || empty($cellConfig['url']);
}));
}));
})
->thenInvalid('Invalid matrix config')
->end()
->end()
我想要捆绑包的下一个 Symfony 配置:
'foo' => [
'bar' => [
'item_1' => [
[
'id' => '25',
'url' => 'https://foo',
],
[
'id' => '26',
'url' => 'https://bar',
],
],
],
]
我想保留所有密钥,所以我使用了 useAttributeAsKey
:
class Configuration implements ConfigurationInterface
{
/**
* Generates the configuration tree builder.
*
* @return TreeBuilder $builder The tree builder
*/
public function getConfigTreeBuilder()
{
$builder = new TreeBuilder();
$rootNode = $builder->root('foo');
$rootNode->children()
->arrayNode('bar')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->scalarNode('id')->end()
->scalarNode('url')->end()
->end()
->end()
->end()
->end();
return $builder;
}
}
但是,我收到了这个错误:
"Unrecognized options "0, 1" under "foo.bar.item_1""
正在阅读 https://symfony.com/doc/4.4/components/config/definition.html 我知道这应该行得通。有什么想法吗?
这是您的配置 class 希望您提供的输入数组示例:
'foo' => [
'bar' => [
'item_1' => [
'id' => '25',
'url' => 'https://foo',
],
'item_2' => [
'id' => '26',
'url' => 'https://bar',
],
],
]
似乎没有开箱即用的方法来创建问题中所示的配置。不过,这里有几个选项:
选项 1
如果您可以在 item_{1}
下创建额外的嵌套级别,那么您可以这样做:
'foo' => [
'bar' => [
'item_1' => [
// `rows` is an additional nesting level
'rows' => [
[
'id' => '25',
'url' => 'https://foo',
],
[
'id' => '26',
'url' => 'https://bar',
]
]
],
'item_2' => [
'rows' => [
[
'id' => '27',
'url' => 'https://foo',
]
]
]
]
]
$rootNode->children()
->arrayNode('bar')
->useAttributeAsKey('name')
->arrayPrototype()
->children()
->arrayNode('rows')
->arrayPrototype()
->children()
->scalarNode('id')->end()
->scalarNode('url')->end()
->end()
->end()
->end()
->end()
// If you'd like, you can git rid of the extra
// nesting level in the parsed configuration
->validate()
->always()
->then(function ($v) {
return $v['rows'] ?? [];
})
->end()
->end()
->end();
选项 2
如果您绝对必须使用您在问题中提供的输入配置结构(即没有额外的嵌套级别),看起来唯一的选择是对 bar
使用 variableNode 并手动执行验证:
$rootNode->children()
->variableNode('bar')
->validate()
->ifTrue( function($barConfig) {
// the config under `bar` has to be an array
if (!is_array($barConfig)) {
return true;
}
return 0 < count(array_filter($barConfig, function ($rowConfig) {
// every item under `item_1`, `item_2`... keys also has to be an array
if (!is_array($rowConfig)) {
return true;
}
return 0 < count(array_filter($rowConfig, function ($cellConfig) {
// every cell has to be an array with `id` and `url` keys
return !is_array($cellConfig) || empty($cellConfig['id']) || empty($cellConfig['url']);
}));
}));
})
->thenInvalid('Invalid matrix config')
->end()
->end()