【问题标题】:Symfony bundle configuration - conditional definitionsSymfony 包配置 - 条件定义
【发布时间】:2020-09-08 19:08:49
【问题描述】:

Symfony 文档有这样的描述(检查粗体部分):

加载多个配置文件时,应该可以 合并和覆盖一些值。其他值不应合并和 在第一次遇到时保持原样。 另外,有些键只有 当另一个键具有特定值时可用(在示例中 上面的配置:内存键只有在驱动时才有意义 是sqlite)。 https://symfony.com/doc/current/components/config/definition.html

这正是我所需要的。我想让一些配置只在特定条件下可用(并且需要)。但是在文档中没有示例或任何信息如何实现这样的事情。

示例 yaml:

my_bundle:
   storages:
      storage_name_1:
         type: TYPE_A         # Always required
         connection: default  # Always required
         path: somepath       # Required and available only if 'type' is TYPE_A
      storage_name_2:
         type: TYPE_B
         connection: default

示例配置:

$rootNode
    ->children()
        ->arrayNode('storages')
            ->isRequired()
            ->requiresAtLeastOneElement()
            ->useAttributeAsKey('name')
            ->arrayPrototype()
                ->children()
                    ->enumNode('type')
                        ->values(['TYPE_A', 'TYPE_B'])
                        ->isRequired()
                        ->cannotBeEmpty()
                    ->end()
                    ->scalarNode('connection')->isRequired()->end()
                    ->scalarNode('path')->isRequired()->end() // This should be required AND available only if type is TYPE_A. TYPE_B should not have this parameter.
                ->end()
            ->end()
        ->end()
    ->end();

【问题讨论】:

  • 目前,我知道你可以为路径设置一个默认值
  • 我认为这可能是一种误解; memory 键在不是 sqlite 时具有默认值。向下查看memory 的页面,您会看到->booleanNode('memory')->defaultFalse()。他们指的是memory 键本身是可选的(默认为false)。
  • 我不知道如何以这种方式误解“某些键仅在另一个键具有特定值时可用”。这当然并不意味着“某些键可以具有默认值并且可以省略”。
  • 考虑尝试 Slack Symfony 频道(来自 Symfony 社区)页面或深呼吸,看看其他捆绑包是如何做到的。配置树不适合胆小的人。
  • 并不是说它的措辞很好,但似乎表明该配置不需要 memory 键用于除父级 sqlite 之外的任何内容,因此可以默认设置(例如,可能是 @ 987654332@) 并且有人不必包含并非总是需要的内容。我认为你需要一个带有配置行/父访问权限的回调或重新排列它,所以它本质上更像mysqlsqlite (TYPE_A: ...),并且可以在未设置时默认设置。

标签: php symfony


【解决方案1】:

我认为您可以将不同的类型映射为它们自己的连接子集。这将是您类型的适配器需要工作的任何内容。

my_bundle:
    storage:
        TYPE_A:
            -   name: storage_1
                connection: default
                path: somepath
        TYPE_B:
            -   name: storage_2
                connection: default

猜测了一下,应该是这样的。

$rootNode
    ->children()
        ->arrayNode('storage')
            ->isRequired()
            ->requiresAtLeastOneElement()
            ->arrayNode('TYPE_A')
                ->arrayPrototype()
                    ->children()
                        ->arrayPrototype()
                            ->children()
                                ->scalarNode('name')->isRequired()->end()
                                ->scalarNode('connection')->isRequired()->end()
                                ->scalarNode('path')->isRequired()->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
            ->arrayNode('TYPE_B')
                ->arrayPrototype()
                    ->children()
                        ->arrayPrototype()
                            ->children()
                                ->scalarNode('name')->isRequired()->end()
                                ->scalarNode('connection')->isRequired()->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
        ->end()
    ->end();

【讨论】:

  • 所以你翻转了它,类型可以有多个定义。也许不那么优雅,但可以按预期工作。我会检查一下,看看它是如何工作的。谢谢!
猜你喜欢
  • 2018-02-22
  • 2020-03-22
  • 2014-05-03
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多