在Symfony 2.8中,给出了这个YAML配置块
collection_select
如何验证配置文件下的键值中的键是否为非空字符串?
在这种情况下' abc'和' def'只是例子,这些是任意的,它们不能预先定义。
这是我的配置文件 -
my_bundle:
profiles:
'abc': 123
'def: 456
'...': ...
问题是
->arrayNode('profiles')
->isRequired()
->requiresAtLeastOneElement()
->useAttributeAsKey('name')
->prototype('integer')
->min(0)
->end()
->end()
在我不想要它时有效。
我找不到一种简单的内置方法来验证原型数组的键。
可能的解决方案
一个:似乎我可以使它成为一个数组数组
my_bundle:
profiles:
123
456
与
my_bundle:
profiles:
-
name: abc
value: 123
-
name: def
value: 456
但我不愿意这样做,因为我们的客户已在其配置中使用原始格式,我们可以更轻松地更新配置而不是配置文件本身。
二:似乎我可以执行#1而不更改配置,只需添加一些规范化以将旧配置格式转换为新格式
->arrayNode('profiles')
->isRequired()
->useAttributeAsKey('name')
->requiresAtLeastOneElement()
->prototype('array')
->children()
->scalarNode('name')
->isRequired()
->cannotBeEmpty()
->validate()
->ifTrue(
function($s) {
return !is_string($s);
}
)
->thenInvalid('Profile key must be a non-empty string')
->end()
->end()
->integerNode('value')
->isRequired()
->min(0)
->end()
->end()
->end()
但这似乎是一个巨大的矫枉过正。
(这两个选项也意味着我需要更改配置文件数据的接收器,以便知道不是使用数字,而是需要使用指向数字的数组键索引,->arrayNode('profiles')
->beforeNormalization()
->ifTrue(
function($array) {
$hasSimpleKeyValuePair = false;
foreach ($array as $key => $value) {
if (!is_array($value)) {
$hasSimpleKeyValuePair = true;
break;
}
}
return $hasSimpleKeyValuePair;
}
)
->then(
function($array) {
$newArray = [];
foreach ($array as $key => $value) {
if (!is_array($value)) {
$newArray[] = ['name' => $key, 'value' => $value];
}
}
return $newArray;
}
)
->end()
->isRequired()
->requiresAtLeastOneElement()
->prototype('array')
->children()
->scalarNode('name')
->isRequired()
->cannotBeEmpty()
->validate()
->ifTrue(
function($s) {
return !is_string($s);
}
)
->thenInvalid('Profile key must be a non-empty string')
->end()
->end()
->integerNode('value')
->isRequired()
->min(0)
->end()
->end()
->end()
->end()
而不是仅仅$profile[$key]['value']
,我可以我猜)
三:似乎我可以在整个块上添加自定义验证
$profile[$key]
这就是我现在要使用的内容,但对于我认为常见用例的内容,似乎仍然是不必要的定制/ hacky。
我只是想检查一下我是否已经错过了使用Symfony配置执行此操作的一些神奇的内置方法?