在我的包的Configuration
中,我定义了以下示例:
$treeBuilder = new TreeBuilder('foo');
$treeBuilder
->getRootNode()
->children()
->arrayNode('foobar')
->scalarPrototype()->end()
->defaultValue([])
->end()
->end()
;
也就是说,这个包需要一个foo.foobar
的数组,现在,在我的包中,这些值取决于应用程序运行的环境。因此,通过环境变量提供此配置值是有意义的。可以处理环境变量的Since Symfony 3.4值。所以这个数组可以用JSON编码存储在环境变量中,然后通过%env(json:FOO)%
解码。
foo:
foobar:
- Lorem
- Ipsum
- Dolor
可以使用
foo:
foobar: '%env(json:FOO)%'
其中
FOO=["Lorem","Ipsum","Dolor"]
但是,在尝试执行此操作时,Symfony会抛出以下异常:
A dynamic value is not compatible with a "Symfony\Component\Config\Definition\PrototypedArrayNode" node type at path "foo.foobar".
什么是允许数组节点使用这样的动态值的正确方法?例如,我需要在配置树中实现我自己的规范化吗?
2条答案
按热度按时间a2mppw5e1#
静态yaml配置和
'%env(json:FOO)%'
之间有很大的区别:env变量的内容在编译时不可用。请参阅文档:可以使用特殊语法%env(ENV_VAR_NAME)%引用环境变量。这些选项的值在运行时解析(每个请求仅解析一次,以免影响性能)。
在
BundleExtension
中(编译时),配置值foobar
将包含类似env_514deb50f3dcab34_json_FOO_ac251f2b9ef3c85f94a68df880763311
的字符串(而不是真实的数组)。例如,这意味着您不能有条件地加载包中的某些配置。
但是,应该在编译时验证此节点。在JSON的情况下,它不能被验证为
scalarNode(...)
,因为包含JSON env-processor。它不能被验证为arrayNode(...)
,因为ArrayNode
不支持动态值。因此,您可以跳过验证:您还可以在捆绑包中添加两个不同的配置项:对于静态配置(作为arrayNode)和动态配置(作为variableNode),然后签入扩展,确保只定义了其中一个。
PS:看起来很不方便。但是这些都是很自然的限制,如果我们记住环境变量可以在运行时(即编译容器后)改变的话。
hzbexzde2#
您需要在.env文件中将JSON定义为string
这是正确:
FOO='["Lorem","Ipsum","Dolor"]'