首页 > 解决方案 > Symfony DI:在包构建期间访问编译器传递的配置参数

问题描述

在编译器传递期间是否可以获取配置参数?我有这个扩展配置:

my_extension:
    foo: 'bar'

在添加编译器传递之前,我需要查看是否设置了配置:

<?php

namespace My\TestBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;

class MyTestBundle extends Bundle
{
    /**
     * @param ContainerBuilder $container
     */
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        // Here I need to check if 'foo' == 'bar' from the extension config and then add the following compiler pass
        $container->addCompilerPass(
            DoctrineOrmMappingsPass::createAnnotationMappingDriver(
                [__NAMESPACE__],
                [
                    __DIR__.'/Model',
                ]
            )
        );
    }
}

问题是在编译器通过时,扩展配置尚未处理:还是我错了?

标签: phpsymfonydependency-injectiondoctrinedoctrine-extensions

解决方案


通过在包上使用编译器传递来解决它,如下所示:

class MyTestBundle extends Bundle
{
    /**
     * @param ContainerBuilder $container
     */
    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $container->addCompilerPass(new MyTestBundleCompilerPass());
    }
}

然后在编译器传递上使用扩展,如下所示:

class MyTestBundleCompilerPass implements CompilerPassInterface
{
    /**
     * @param ContainerBuilder $container
     */
    public function process(ContainerBuilder $container)
    {
        if (!$container->hasExtension(MyTestExtension::ALIAS)) {
            return;
        }

        /** @var MyTestExtension $extension */
        $extension = $container->getExtension(MyTestExtension::ALIAS);
        $config = $extension->getConfig();

        if (array_key_exists('foo', $config) && $config['foo']) {
            $container->addCompilerPass(
                DoctrineOrmMappingsPass::createAnnotationMappingDriver(
                    [__NAMESPACE__],
                    [
                        __DIR__.'/Model',
                    ]
                )
            );
        }
    }
}

然后使用扩展来读取配置:

class MyTestExtension extends Extension
{
    const ALIAS = 'my_extension';

    private $config = array();

    /**
     * {@inheritdoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $this->config = $this->processConfiguration($configuration, $configs);

        $container->setParameter(self::ALIAS.'.foo', $this->config['foo']);

        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('services.yml');

        // Extensions to override configs for
        $loader->load('config.yml');
    }

    public function getConfig()
    {
        try {
            return $this->config;
        } finally {
            // Erases the config after it is retrieved, for security and performance reasons
            $this->config = array();
        }
    }
}

推荐阅读