Symfony Bundle无法在项目中生成bundle配置YAML文件
问题描述
原本正常运行的Symfony Bundle,需要在使用该Bundle的项目中自动生成专属配置YAML文件,用于单独管理Bundle设置。但无论是采用Symfony 6.1之前继承Bundle类的旧方式,还是继承AbstractBundle的新方式,都无法在项目的./config/packages/目录下自动生成对应的.yaml文件。Bundle能正常安装,但配置文件始终不会自动生成,且已确认依赖symfony/flex。
以下是采用的旧方式代码:
Bundle类
mycorpforms/src/MyCorpFormsBundle.php
<?php namespace MyCorp\FormsBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class MyCorpFormsBundle extends Bundle { // empty }
配置类
mycorpforms/src/DependencyInjection/Configuration.php
<?php namespace MyCorp\FormsBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder('mycorp_forms'); $treeBuilder->getRootNode() ->children() ->booleanNode('favorite_submenu_enabled')->defaultFalse()->end() ->end() ; return $treeBuilder; } }
扩展类
mycorpforms/src/DependencyInjection/MyCorpFormsExtension.php
<?php namespace MyCorp\FormsBundle\DependencyInjection; // 注意:原代码引入了错误的Configuration类,已修正 use MyCorp\FormsBundle\DependencyInjection\Configuration; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\Config\FileLocator; class MyCorpFormsExtension extends Extension { public function load(array $configs, ContainerBuilder $containerBuilder) { $loader = new YamlFileLoader( $containerBuilder, new FileLocator(__DIR__.'/../../config/packages') ); $loader->load('mycorp_forms.yaml'); $configuration = new Configuration(); $processor = new Processor(); $config = $processor->processConfiguration($configuration, $configs); $containerBuilder->setParameter('mycorp_forms.favorite_submenu_enabled', $config['favorite_submenu_enabled']); } }
Bundle内的配置YAML文件
mycorpforms/config/packages/mycorp_forms.yaml
mycorp_forms: # Enable Favorite-Sub-Menu (Requires Knp-Snappy-Bundle !) favorite_submenu_enabled: false
核心原因
Symfony Flex自动生成项目配置文件的核心依赖Flex配方(Recipes),仅在Bundle内部放置配置文件无法触发自动复制操作,必须通过配方告诉Flex如何将配置文件同步到项目中。
解决步骤
1. 创建Flex配方目录结构
在Bundle根目录下创建recipes/目录,按照Flex规范组织配置文件:
mycorpforms/ └── recipes/ ├── manifest.json └── config/ └── packages/ └── mycorp_forms.yaml
将Bundle原有的config/packages/mycorp_forms.yaml复制到recipes/config/packages/目录下。
2. 编写配方清单文件manifest.json
在recipes/目录下创建manifest.json,定义Flex需要执行的操作:
{ "bundles": { "MyCorp\\FormsBundle\\MyCorpFormsBundle": ["all"] }, "copy-from": { "recipes/config/packages/": "%CONFIG_DIR%/packages/" } }
bundles:指定Bundle在所有环境(all)下自动启用copy-from:定义配置文件的复制规则,%CONFIG_DIR%对应项目的config目录
3. 在Bundle的composer.json中声明配方
修改Bundle根目录的composer.json,添加extra字段指定配方位置:
{ "name": "mycorp/forms-bundle", // 保留原有其他字段 "extra": { "symfony": { "allow-contrib": true, "recipes": { "": "recipes/" } } } }
allow-contrib:允许使用非官方维护的Flex配方(自定义Bundle必须开启)recipes:指定配方文件所在的目录
4. 重新安装Bundle到项目
在使用该Bundle的项目中执行以下命令,Flex会自动复制配置文件到项目的config/packages/目录:
composer require mycorp/forms-bundle
额外修正
原扩展类中错误引入了KnpSnappyBundle的Configuration类,需替换为自身Bundle的Configuration类,否则会导致配置处理逻辑错误。
内容的提问来源于stack exchange,提问作者Jonathan

