Symfony 4:如何在包配置中允许数组节点的动态值?
Symfony 4: how to allow dynamic values for array nodes in bundle configuration?
在我的包的 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".
允许数组节点使用此类动态值的正确方法是什么?例如,我是否需要在配置树中实现自己的规范化?
你需要在.env文件中定义JSON为string
这是正确的:FOO='["Lorem","Ipsum","Dolor"]'
静态yaml配置和'%env(json:FOO)%'
有很大区别:env变量的内容在编译时不可用。见 docs:
You can reference environment variables using the special syntax %env(ENV_VAR_NAME)%. The values of these options are resolved at runtime (only once per request, to not impact performance).
在你的 BundleExtension
中(在编译时)你的配置值 foobar
将包含像 env_514deb50f3dcab34_json_FOO_ac251f2b9ef3c85f94a68df880763311
这样的字符串(而不是真正的数组)。
这意味着您不能有条件地在您的包中加载某些配置,例如。
但是,应该在编译时验证此节点。在 JSON 的情况下,它不能被验证为 scalarNode(...)
,因为包含 JSON env-processor。无法验证为 arrayNode(...)
,因为 ArrayNode
不支持动态值。
所以你可以跳过验证:
$treeBuilder
->getRootNode()
->children()
->variableNode('foobar')->end()
->end()
;
您还可以在 bundle 中添加两个不同的配置项:用于静态配置(作为 arrayNode)和用于动态配置(作为 variableNode),然后检查扩展,只定义了其中一个。
PS:看起来不方便。但这些都是很自然的限制,如果我们记得环境变量可以在运行时更改(即在编译容器之后)。
在我的包的 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".
允许数组节点使用此类动态值的正确方法是什么?例如,我是否需要在配置树中实现自己的规范化?
你需要在.env文件中定义JSON为string
这是正确的:FOO='["Lorem","Ipsum","Dolor"]'
静态yaml配置和'%env(json:FOO)%'
有很大区别:env变量的内容在编译时不可用。见 docs:
You can reference environment variables using the special syntax %env(ENV_VAR_NAME)%. The values of these options are resolved at runtime (only once per request, to not impact performance).
在你的 BundleExtension
中(在编译时)你的配置值 foobar
将包含像 env_514deb50f3dcab34_json_FOO_ac251f2b9ef3c85f94a68df880763311
这样的字符串(而不是真正的数组)。
这意味着您不能有条件地在您的包中加载某些配置,例如。
但是,应该在编译时验证此节点。在 JSON 的情况下,它不能被验证为 scalarNode(...)
,因为包含 JSON env-processor。无法验证为 arrayNode(...)
,因为 ArrayNode
不支持动态值。
所以你可以跳过验证:
$treeBuilder
->getRootNode()
->children()
->variableNode('foobar')->end()
->end()
;
您还可以在 bundle 中添加两个不同的配置项:用于静态配置(作为 arrayNode)和用于动态配置(作为 variableNode),然后检查扩展,只定义了其中一个。
PS:看起来不方便。但这些都是很自然的限制,如果我们记得环境变量可以在运行时更改(即在编译容器之后)。