Sylius框架中继承类构造函数新增参数无法识别的问题
我在使用PHP的Sylius框架开发Web应用时,创建了一个继承自框架内置ResourceController的自定义控制器:
class ResourceController extends \Sylius\Bundle\ResourceBundle\Controller\ResourceController
父类构造函数包含17个参数,我在自定义类的构造函数中新增了3个参数(Sender、ChannelContextInterface、LocaleContextInterface),代码如下:
public Sender $sender; public ChannelContextInterface $channelContext; public LocaleContextInterface $localeContext; public function __construct( MetadataInterface $metadata, RequestConfigurationFactoryInterface $requestConfigurationFactory, ?ViewHandlerInterface $viewHandler, RepositoryInterface $repository, FactoryInterface $factory, NewResourceFactoryInterface $newResourceFactory, ObjectManager $manager, SingleResourceProviderInterface $singleResourceProvider, ResourcesCollectionProviderInterface $resourcesFinder, ResourceFormFactoryInterface $resourceFormFactory, RedirectHandlerInterface $redirectHandler, FlashHelperInterface $flashHelper, AuthorizationCheckerInterface $authorizationChecker, EventDispatcherInterface $eventDispatcher, ?StateMachineInterface $stateMachine, ResourceUpdateHandlerInterface $resourceUpdateHandler, ResourceDeleteHandlerInterface $resourceDeleteHandler, Sender $sender, ChannelContextInterface $channelContext, LocaleContextInterface $localeContext ) { parent::__construct( $metadata, $requestConfigurationFactory, $viewHandler, $repository, $factory, $newResourceFactory, $manager, $singleResourceProvider, $resourcesFinder, $resourceFormFactory, $redirectHandler, $flashHelper, $authorizationChecker, $eventDispatcher, $stateMachine, $resourceUpdateHandler, $resourceDeleteHandler ); $this->sender = $sender; $this->channelContext = $channelContext; $this->localeContext = $localeContext; }
启动应用后出现Symfony错误:
Too few arguments to function App\Controller\Resource\ResourceController::__construct(), 17 passed in [...] on line 31 and exactly 20 expected
我的_sylius.yaml配置片段:
sylius_customer: resources: customer: classes: model: App\Entity\Customer\Customer repository: App\Repository\CustomerRepository controller: App\Controller\Resource\ResourceController
config/routes.yaml配置片段:
sylius_admin_customer_create: path: /admin/customers/new methods: [GET,POST] defaults: _controller: sylius.controller.customer::createAction
错误原因
Sylius的资源控制器由Symfony服务容器管理依赖注入,默认的sylius.controller.customer服务仅配置了父类ResourceController需要的17个参数。你仅在_sylius.yaml中指定了自定义控制器类,但容器未更新服务参数配置,仍按原服务的参数列表注入,导致参数数量不匹配。
解决方法
方法一:使用属性注入(推荐,Symfony 5.4+支持)
无需修改构造函数,直接用#[Autowire]注解自动注入新增依赖,无需调整服务配置:
use Symfony\Component\DependencyInjection\Attribute\Autowire; class ResourceController extends \Sylius\Bundle\ResourceBundle\Controller\ResourceController { // 保留原构造函数,复用父类参数 public function __construct( MetadataInterface $metadata, RequestConfigurationFactoryInterface $requestConfigurationFactory, ?ViewHandlerInterface $viewHandler, RepositoryInterface $repository, FactoryInterface $factory, NewResourceFactoryInterface $newResourceFactory, ObjectManager $manager, SingleResourceProviderInterface $singleResourceProvider, ResourcesCollectionProviderInterface $resourcesFinder, ResourceFormFactoryInterface $resourceFormFactory, RedirectHandlerInterface $redirectHandler, FlashHelperInterface $flashHelper, AuthorizationCheckerInterface $authorizationChecker, EventDispatcherInterface $eventDispatcher, ?StateMachineInterface $stateMachine, ResourceUpdateHandlerInterface $resourceUpdateHandler, ResourceDeleteHandlerInterface $resourceDeleteHandler ) { parent::__construct(...func_get_args()); } #[Autowire] private Sender $sender; #[Autowire] private ChannelContextInterface $channelContext; #[Autowire] private LocaleContextInterface $localeContext; // 后续在控制器方法中直接使用这些私有属性即可 }
注:属性建议设为private以符合封装原则;若Symfony版本低于5.4,可改用setter注入。
方法二:重写服务定义
在config/services.yaml中重新定义sylius.controller.customer服务,手动添加新增的三个依赖参数:
services: sylius.controller.customer: class: App\Controller\Resource\ResourceController arguments: - '@sylius.resource.metadata.customer' - '@sylius.resource.request_configuration_factory' - '@?sylius.resource.view_handler' - '@sylius.repository.customer' - '@sylius.factory.customer' - '@sylius.resource.new_resource_factory' - '@doctrine.orm.default_entity_manager' - '@sylius.resource.single_resource_provider' - '@sylius.resource.resources_collection_provider' - '@sylius.resource.form_factory' - '@sylius.resource.redirect_handler' - '@sylius.resource.flash_helper' - '@security.authorization_checker' - '@event_dispatcher' - '@?sm.factory' - '@sylius.resource.update_handler' - '@sylius.resource.delete_handler' # 新增的三个依赖参数 - '@your.service.sender' # 替换为Sender类对应的服务ID或完全限定类名 - '@sylius.context.channel' - '@sylius.context.locale' tags: - { name: sylius.resource.controller }
注意:@your.service.sender需要替换为你项目中Sender类的实际服务ID,若该类是自动注册的,直接写类的完全限定名即可。
内容的提问来源于stack exchange,提问作者TeslaX93

