原型节点中键值对中键的Symfony配置验证

时间:2017-09-17 13:24:53

标签: php symfony dependency-injection symfony-2.8

在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配置执行此操作的一些神奇的内置方法?

0 个答案:

没有答案