在Symfony 2.1语义化配置中允许包含默认值的数组或null。

13

我需要在捆绑的语义配置中定义一个带有给定默认值的数组节点。目前看起来是这样的:

$node->arrayNode('foo')
         ->prototype('scalar')->end()
         ->defaultValue(array('1', '2', '3'))
     ->end();

我想给用户提供一个选项,让他们可以用 null 来覆盖这个数组,例如:

my_bundle:
  foo: ~

由于 [] 的语义应与 null 不同,因此我无法使用空数组 ([]array()) 代替 null

这是否有可能?还是有其他不丑陋的解决方法吗?目前我只会得到一个异常:

  

InvalidTypeException: Invalid type for path "my_bundle.foo". Expected array, but got NULL


你将其定义为“标量”,但默认值是“数组”,它应该是数组类型吗?标量是整数、布尔和字符串。 - olegkhuss
1
原型是指数组的元素。 - Thomas Luzat
1个回答

20

你可以尝试像这样:

$node->arrayNode('foo')
     ->beforeNormalization()
       ->ifTrue(function($v) { return $v === null; })
       ->then(function($v) { return array(); })
     ->end()
     ->prototype('scalar')->end()
     ->defaultValue(array('1', '2', '3'))
 ->end();

或者更简单的方式:

$node->arrayNode('foo')
     ->treatNullLike(array())
     ->prototype('scalar')->end()
     ->defaultValue(array('1', '2', '3'))
 ->end();
否则,您可以使用variableNode而不是arrayNode;这将为您提供更多的自由度,但开箱即用的验证/合并逻辑会减少。

谢谢,但看起来我会得到 array() 而不是 null。虽然我几乎怀疑没有其他选择,毕竟在 XML 中很难表达“用 null 覆盖”与空数组(对于 Yaml 来说不是那么困难)。 - Thomas Luzat
1
是的,这就是将要发生的事情,但我认为从这里没有容易的逃脱:如果你定义了一个arrayNode,在配置合并和规范化之后最终会得到一个数组。否则,你可以考虑将foo节点作为变量节点,这将给你更多的自由,但是缺少开箱即用的验证/合并逻辑。 - Aldo Stracquadanio
如果您在答案中添加了variableNode部分,我可以接受它,因为我明确要求一种允许将[]视为null的方法。arrayNode似乎不是完全符合我的要求的选项。 - Thomas Luzat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接