我有一个对 Symfony2 配置进行更改的脚本,需要在继续之前了解新配置(特别是添加 dbal 连接)。有没有办法在脚本执行期间强制重新加载配置?
3 回答
更新:您无法重新加载配置,但您可以即时设置参数,请参阅第二个“更新”段落
在 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 文档。
我的答案可能很晚才到达,但可能对其他人有用。
“prod”环境的 Symfony 缓存存储在“app/cache/prod/”文件夹中并包含许多东西(用 PHP 翻译的 Twig 模板在“twig/”子文件夹中,注释在“annotations/”子文件夹中,以及...配置参数, app*ProjectContainer.php 文件等)。
所以你可以做的是:当你的配置脚本更改parameters.yml时,它也可以删除appProdProjectContainer.php。下一个使用 Symfony 应用程序的用户将面临更长的响应时间,但新的配置参数将被考虑并缓存。
这是部分解决方案,除了我在 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
- 这是 Yaml 配置的解决方案,因此使用了 YamlFileLoader。
- ReinitializedBundle 配置文件结构:
.ReinitializedBundle
└── Resources
└── config
├── production
| ├─── services.yml
| └─── other stuff
└── staging
├─── services.yml
└─── other stuff