Symfony config:如何验证一个配置,其中值可能不存在,但如果存在,则必须是定义的类型
给定如下所示的配置文件:Symfony config:如何验证一个配置,其中值可能不存在,但如果存在,则必须是定义的类型,symfony,configuration,bundle,Symfony,Configuration,Bundle,给定如下所示的配置文件: 我的包: 端点: api1: 端点1_名称:[头,获取] 端点2_名称:[头,获取,删除] api2: 端点1_名称:[获取] api3: 端点1_名称:[头] 我希望我可以为每个API设置可以配置的端点,并为每个端点获取一个包含我想要使用的HTTP方法的数组 因此,例如,对于Api1/endpoint1_name我想使用HTTP方法head和get,而对于Api2/endpoint1_name我只想使用getHTTP方法 约束 每个API都有自己的端点,我希望在配
我的包:
端点:
api1:
端点1_名称:[头,获取]
端点2_名称:[头,获取,删除]
api2:
端点1_名称:[获取]
api3:
端点1_名称:[头]
我希望我可以为每个API设置可以配置的端点,并为每个端点获取一个包含我想要使用的HTTP方法的数组
因此,例如,对于Api1/endpoint1_name
我想使用HTTP方法head
和get
,而对于Api2/endpoint1_name
我只想使用get
HTTP方法
约束
每个API都有自己的端点,我希望在配置期间检查端点是否受支持。
每个端点可以有五种HTTP方法中的一些:delete
、get
、head
、post
和put
因此,如果我为端点设置的HTTP方法不是上述五种方法之一,则配置是错误的
这是我开始编写以检查配置的内容,但现在我收到以下错误:
[Symfony\Component\Config\Definition\Exception\InvalidTypeException]路径“my_bundle_hub.endpoints.api1.endpoint1_name.0”的类型无效。 应为数组,但得到字符串
php
$rootNode
->儿童()
->arrayNode(“端点”)
->儿童()
->arrayNode('api1')
->儿童()
->arrayNode('端点名称')
->儿童()
->scalarNode('head')->end()
->scalarNode('get')->end()
->完()
->完()
->完()
->end()//api1
->arrayNode('api2')
->儿童()
->arrayNode('端点名称')
->儿童()
->scalarNode('head')->end()
->scalarNode('get')->end()
->完()
->完()
->完()
->end()//api2
->arrayNode('api3')
->儿童()
->arrayNode('端点名称')
->儿童()
->scalarNode('head')->end()
->scalarNode('get')->end()
->完()
->完()
->完()
->end()//Api 3
->完()
->end()//端点
->完()
;
如何检查这些值?哇,多么好的配置啊 据我所知,yaml with files中不支持简单数组表示法
[]
(带键或不带键)
我将使用标量节点列出http方法,以保持内联的“语法糖”。
我会这样处理你的案子
endpoints:
api1:
endpoint1_name: head, get
endpoint2_name: head, get, delete
api2:
endpoint1_name: delete, post
# ...
…具有适当的配置类
// Some properties inside Configuration class
private $expectedApiMethod = ['get','post','head','delete','put'];
private $methodSplitPattern = '~\s+|\s*,\s*+~';
...
// Inside getConfigTreeBuilder method
// …
->arrayNode('endpoints')
// Each api's endpoints are arrays with ARBITRARY keys
// To handle this, you can use "prototype()" method with 'array' parameter
->prototype('array')
// Now, you expect enpoints to hold one or more children (with arbitrary keys). Go for prototype !
// I advise you to use scalar node to be able to declare method the inline way
->prototype('scalar')
->end()
// validation of provided http methods for each endpoint
->validate()
->ifTrue( function($value) {
foreach ( $value as $ep){
// Set syntax rules for http method enumeration
// $this can be used within lambdas since php 5.4.0
// Otherwise, just harcode values
// The one used here let's you put commas and/or spaces between http method names
foreach (preg_split($this->methodSplitPattern, $ep) as $split){
if( ! in_array($split, $this->expectedApiMethod) )
return true;
}
}
})
->thenInvalid("Wrong http method or syntax error detected.\nExpected values are ".implode(', ',$this->expectedApiMethod)." separated by commas and/or spaces!\n%s")
->end()
// You may want to validate api keys as well here.
->end()
// …
$config
扩展类中的输出将为您提供:
…
[endpoints] => Array
(
[api1] => Array
(
[endpoint1_name] => head get
[endpoint2_name] => head get delete
)
[api2] => Array
(
[endpoint1_name] => delete post
)
)
任何错误的配置都会出现异常/致命错误。请注意,您可以使用相同的方式对“api”和/或“端点”键进行事件验证