Symfony 4:如何在捆绑配置中允许阵列节点的动态值?

tquggr8v  于 2022-11-16  发布在  其他
关注(0)|答案(2)|浏览(139)

在我的包的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".

什么是允许数组节点使用这样的动态值的正确方法?例如,我需要在配置树中实现我自己的规范化吗?

a2mppw5e

a2mppw5e1#

静态yaml配置和'%env(json:FOO)%'之间有很大的区别:env变量的内容在编译时不可用。请参阅文档:
可以使用特殊语法%env(ENV_VAR_NAME)%引用环境变量。这些选项的值在运行时解析(每个请求仅解析一次,以免影响性能)。
BundleExtension中(编译时),配置值foobar将包含类似env_514deb50f3dcab34_json_FOO_ac251f2b9ef3c85f94a68df880763311的字符串(而不是真实的数组)。
例如,这意味着您不能有条件地加载包中的某些配置。
但是,应该在编译时验证此节点。在JSON的情况下,它不能被验证为scalarNode(...),因为包含JSON env-processor。它不能被验证为arrayNode(...),因为ArrayNode不支持动态值。因此,您可以跳过验证:

$treeBuilder
    ->getRootNode()
    ->children()
        ->variableNode('foobar')->end()
    ->end()
;

您还可以在捆绑包中添加两个不同的配置项:对于静态配置(作为arrayNode)和动态配置(作为variableNode),然后签入扩展,确保只定义了其中一个。
PS:看起来很不方便。但是这些都是很自然的限制,如果我们记住环境变量可以在运行时(即编译容器后)改变的话。

hzbexzde

hzbexzde2#

您需要在.env文件中将JSON定义为string
这是正确:FOO='["Lorem","Ipsum","Dolor"]'

相关问题