Symfony 4.4.25(Akeneo)依赖注入出现诡异行为求助
问题根源与解决方案
核心问题:错误将Bundle类注册为事件订阅者服务
Symfony中,Bundle类(比如AcmeCategoryBuilderBundle)的实例化由Kernel负责,应用启动时Kernel会直接调用无参构造创建Bundle实例,不会通过服务容器管理。你把Bundle类当成事件订阅者注册到服务容器的操作完全无效,这就是所有矛盾的起因。
两种矛盾情况的解释
构造函数无参时的报错
- 写法一(命名参数):Symfony服务容器会严格校验构造函数参数,发现构造函数没有
$productModelRepository参数,直接抛出配置错误,这是容器的正常校验逻辑。 - 写法二(索引参数):容器尝试向构造函数传参,但构造函数定义为无参,PHP直接触发参数不匹配的致命错误,属于语言层面的正常报错。
- 写法一(命名参数):Symfony服务容器会严格校验构造函数参数,发现构造函数没有
构造函数加参数后的报错
你修改构造函数添加参数后,Kernel实例化Bundle时仍然会调用无参构造(Kernel不会从服务容器获取Bundle实例),所以出现0 passed, 1 expected的错误——你的服务配置根本没被用来创建Bundle实例,自然不会注入参数。
正确解决方案
创建独立的事件订阅者类
不要用Bundle类处理事件逻辑,新建专门的订阅者:// src/EventSubscriber/CategoryBuilderSubscriber.php namespace Acme\Bundle\CategoryBuilderBundle\EventSubscriber; use Akeneo\Pim\Enrichment\Component\Product\Repository\ProductModelRepositoryInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class CategoryBuilderSubscriber implements EventSubscriberInterface { public function __construct( private ProductModelRepositoryInterface $productModelRepository ) {} // 实现订阅的事件方法 public static function getSubscribedEvents(): array { return [ // 配置你要监听的事件,例如: // 'some.event.name' => 'handleEvent', ]; } // 对应事件处理方法 // public function handleEvent(SomeEvent $event): void // { // // 使用$productModelRepository处理逻辑 // } }修改服务配置指向新的订阅者
更新services.yaml配置:services: acme_category_builder.event_subscriber.category_builder: class: Acme\Bundle\CategoryBuilderBundle\EventSubscriber\CategoryBuilderSubscriber arguments: $productModelRepository: '@pim_catalog.repository.product_model' tags: ['kernel.event_subscriber']恢复Bundle类的无参构造
Bundle类只需要保持默认结构,负责Bundle注册即可:// src/AcmeCategoryBuilderBundle.php namespace Acme\Bundle\CategoryBuilderBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class AcmeCategoryBuilderBundle extends Bundle { // 保持默认无参构造,无需额外参数 }
内容的提问来源于stack exchange,提问作者Tom Lorenz
相关产品推荐
相关产品推荐

