【问题标题】:Symfony 6.1 get another bundle configuration dataSymfony 6.1 获取另一个包配置数据
【发布时间】:2022-06-18 04:25:51
【问题描述】:

我正在尝试从我的捆绑包中获取一个捆绑包的配置,使用https://symfony.com/blog/new-in-symfony-6-1-simpler-bundle-extension-and-configuration 处的新的简化捆绑包配置进行配置

我的 bundle 有 symfony/maker-bundle 作为依赖,我想知道 maker-bundle 的配置

maker: 
  root_namespace: MyApp

我正试图弄清楚我在哪里可以访问该信息,特别是因为我不再有明确的 MyBundleExtension 类。当我的包正在加载时,参数“maker.root_namespace”不在容器 parameterBag 中。所以我添加了一个 CompilerPass,它在那里也不可见。

我尝试使用 prepend() 和 prependExtension() 调用,但不确定如何将它们连接到新的捆绑配置中,或者即使这是正确的位置。

虽然我在特定情况下使用 symfony/maker-bundle,但我经常想知道其他包配置的值,这似乎是一件很常见的事情。我怀疑不创建扩展类是可能的,但不确定如何。

【问题讨论】:

  • 虽然这似乎是一件显而易见的事情,但基本上是不可能的。问题是配置文件数据被合并到包的配置树中并被处理。包含最终值的结果配置不会保存在任何地方,据我所知根本无法访问。如果捆绑包想要公开信息,则由捆绑包创建参数。如果您需要数据,请创建自己的参数,然后更新 bundle 的配置文件以使用它。

标签: symfony bundle


【解决方案1】:

目前可以在prependExtension() 方法中访问其他捆绑配置,这是推荐的地方:

class MyMakerBundle extends AbstractBundle
{
    public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void
    {
        $configs = $builder->getExtensionConfig('maker');
        
        // ...
    }
}

但是,此方法旨在预先添加更多配置,而不是获取/处理这些配置。因此,您必须考虑到它是一个未处理和未合并的配置列表,如果另一个扩展在您自己的扩展之后将新配置添加到 MakerBundle,这些配置可能会发生变化。

此外,这个root_namespace 的值可以是(在这种情况下不太可能)参数或环境变量(没有意义,但仍然可能),此时尚未解决(原始值)。

选项 1(最安全)

在您的 MyMakerBundle::configure() 方法中创建一个类似的配置,并将从 MakerBundle 扩展中获得的配置添加到前面:

public function configure(DefinitionConfigurator $definition): void
{
    $definition->rootNode()
        ->children()
            ->scalarNode('root_namespace')->end()
        ->end();
}

public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void
{
    $configs = $builder->getExtensionConfig('maker');
        
    // iterate in reverse to preserve the original order after prepending the config
    foreach (array_reverse($configs) as $config) {
        $container->prependExtensionConfig('my_maker', [
            'root_namespace' => $config['root_namespace'],
        ]);
    }
}

public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
{
    // do something with 
    $config['root_namespace'];
}

https://symfony.com/doc/current/bundles/prepend_extension.html

选项 2(有风险)

因为是只在dev模式下使用的简单配置,所以可以直接做一个简单的$config = array_merge(...$configs)得到$config['root_namespace']的值:

public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void
{
    $configs = $builder->getExtensionConfig('maker');

    $config = array_merge(...$configs);
    $container->parameters()
        ->set('my_maker.root_namespace', $config['root_namespace']);
}

public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
{
    // do something with 
    $builder->getParameter('my_maker.root_namespace'));

    $builder->getParameterBag()->remove('my_maker.root_namespace');
}

第二个选项也可以在 CompilerPass 中完成,其好处是您不需要创建时间参数。

选项 3(有风险)

在 CompilerPass 类中,从属于 MakerBundle 的以下服务之一获取根命名空间值:

  • maker.generator 参数 1(例如 $container->getDefinition('maker.generator')->getArgument(1)
  • maker.autoloader_finder 参数 0。

我知道,到目前为止,它并不像您想象的那么简单和直观。

【讨论】:

    猜你喜欢
    • 2012-07-17
    • 1970-01-01
    • 2015-05-11
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多