You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 4.4.25(Akeneo)依赖注入出现诡异行为求助

问题根源与解决方案

核心问题:错误将Bundle类注册为事件订阅者服务

Symfony中,Bundle类(比如AcmeCategoryBuilderBundle)的实例化由Kernel负责,应用启动时Kernel会直接调用无参构造创建Bundle实例,不会通过服务容器管理。你把Bundle类当成事件订阅者注册到服务容器的操作完全无效,这就是所有矛盾的起因。


两种矛盾情况的解释

  1. 构造函数无参时的报错

    • 写法一(命名参数):Symfony服务容器会严格校验构造函数参数,发现构造函数没有$productModelRepository参数,直接抛出配置错误,这是容器的正常校验逻辑。
    • 写法二(索引参数):容器尝试向构造函数传参,但构造函数定义为无参,PHP直接触发参数不匹配的致命错误,属于语言层面的正常报错。
  2. 构造函数加参数后的报错
    你修改构造函数添加参数后,Kernel实例化Bundle时仍然会调用无参构造(Kernel不会从服务容器获取Bundle实例),所以出现0 passed, 1 expected的错误——你的服务配置根本没被用来创建Bundle实例,自然不会注入参数。


正确解决方案

  1. 创建独立的事件订阅者类
    不要用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处理逻辑
        // }
    }
    
  2. 修改服务配置指向新的订阅者
    更新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']
    
  3. 恢复Bundle类的无参构造
    Bundle类只需要保持默认结构,负责Bundle注册即可:

    // src/AcmeCategoryBuilderBundle.php
    namespace Acme\Bundle\CategoryBuilderBundle;
    
    use Symfony\Component\HttpKernel\Bundle\Bundle;
    
    class AcmeCategoryBuilderBundle extends Bundle
    {
        // 保持默认无参构造,无需额外参数
    }
    

内容的提问来源于stack exchange,提问作者Tom Lorenz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:16:11