10

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

4

3 回答 3

17

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

在 Symfony2 中确实不可能做到这一点。

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

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

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

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

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

更新

我发现您可以通过以下方式即时设置容器配置参数

$container->setParameter('parameter', value);

查看Symfony2 文档

于 2013-04-05T13:49:54.857 回答
5

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

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

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

于 2016-06-01T10:44:31.570 回答
0

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

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

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

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

/**
 * 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参数和服务都标有'reinitialized_bundle_config_prefix'前缀,所以在容器中很容易识别,即:

reinitialized_bundle_config_prefix.service1 reinitialized_bundle_config_prefix.param1

  1. 这是 Yaml 配置的解决方案,因此使用了 YamlFileLoader。
  2. ReinitializedBundle 配置文件结构:

.ReinitializedBundle └── Resources └── config ├── production | ├─── services.yml | └─── other stuff └── staging ├─── services.yml └─── other stuff

于 2018-05-08T10:41:27.503 回答