在Symfony2中强制配置重新加载

时间:2013-04-04 14:37:00

标签: symfony

我有一个脚本可以更改Symfony2配置,需要在继续之前了解新配置(特别是添加dbal连接)。有没有办法在脚本执行期间强制重新加载配置?

3 个答案:

答案 0 :(得分:14)

更新:您无法重新加载配置,但您可以即时设置参数,请参阅第二个“更新”段落

在Symfony2中实际上不可能这样做。

在生产模式下,所有内容(甚至是配置)都会被缓存,因此您必须使用

清除缓存

app/console cache:clear --env=prod --no-debug

(可能后跟app/console cache:warmup --env=prod --no-debug

重新加载配置。在开发模式下,您可以尝试使用shutdown(),然后尝试boot()Symfony\Component\HttpKernel\Kernel中的loadClassCache - 但所有这些都不是您想要的。

对配置文件进行了哪些更改?也许您应该为不同的环境使用不同的文件或考虑任何其他方法来获取这些更改(通过简单的Web服务或甚至从Controller中读取的静态文件)。

<强>更新

我发现你可以通过

动态设置容器配置参数
$container->setParameter('parameter', value);

查看the Symfony2 documentation

答案 1 :(得分:5)

我的回答可能很晚才到,但可能对其他人有用。

“prod”环境的Symfony缓存存储在“app / cache / prod /”文件夹中并包含许多内容(在“twig /”子文件夹中用PHP翻译的Twig模板,“annotations /”子文件夹中的注释,以及.. 。配置参数,app * ProjectContainer.php文件等等。)

所以你可以做的是:当配置脚本改变parameters.yml时,它也可以删除appProdProjectContainer.php。下一次使用Symfony应用程序的用户将面临更长的响应时间,但新的配置参数将被考虑并缓存。

答案 2 :(得分:0)

这是部分解决方案,除了我在Symfony 3.2中使用它,但是这段代码用于动态重新加载bundle配置。

首先,你应该在服务/控制器中注入容器实例,你想要使用其他配置重新初始化的bundle实例:

/**
 * Service constructor.
 *
 * @param ContainerInterface $container
 */
public function __construct(ContainerInterface $container)
{
    $container = ReinitializedBundleExtension::updateContainerWithProdConfiguration($container);
}

其次,您应该为ReinitializedBundleExtension类添加一个方法,该方法将使用重新初始化的bundle实例和依赖项更新容器:

/**
 * Updates container with bundle services resolved with production configuration.
 *
 * @param ContainerInterface $oldContainer
 *
 * @return ContainerInterface $container
 */
public static function updateContainerWithProdConfiguration(ContainerInterface $oldContainer)
{
    $containerBuilder = new ContainerBuilder();

    // Copy external services used in the bundle.
    $logger = $oldContainer->get('logger');
    $containerBuilder->set('logger', $logger);

    // Load the production config files.
    $bundleResourcesPath = $oldContainer->get('kernel')->locateResource('@ReinitializedBundle/Resources/');
    $fileLocator = new FileLocator($bundleResourcesPath . '/config');
    $loader = new Loader\YamlFileLoader($containerBuilder, $fileLocator);
    $loader->setResolver(new LoaderResolver([$loader]));
    $loader->load($bundleResourcesPath . 'config/production/services.yml');

    // Resolving bundle services with prduction config.
    $containerBuilder->compile();
    $containerBuilder->resolveServices($containerBuilder->getDefinitions());

    // Merge resolved prod-configured services with old container.
    $serviceIds = $containerBuilder->getServiceIds();

    foreach ($serviceIds as $serviceId) {
        // Services which are not related to the bundle.
        if (strpos($serviceId, 'reinitialized_bundle_config_prefix') === false) {
            continue;
        }

        $oldContainer->set($serviceId, $containerBuilder->get($serviceId));
    }

    return $oldContainer;
}

PS: 1.所有ReinitializedBundle参数和服务都标有&#39; reinitialized_bundle_config_prefix&#39;前缀,所以很容易在容器中识别它们,即:

reinitialized_bundle_config_prefix.service1 reinitialized_bundle_config_prefix.param1

  1. 这是Yaml配置的解决方案,因此使用了YamlFileLoader。
  2. ReinitializedBundle配置文件结构:
  3. .ReinitializedBundle └── Resources └── config ├── production | ├─── services.yml | └─── other stuff └── staging ├─── services.yml └─── other stuff