Symfony 2.8下重写FOSUserBundle注册控制器报错求助
我最近在Symfony 2.8环境下尝试重写FOSUserBundle的注册控制器,已经完成了服务配置和继承基类的控制器编写,但访问注册页面时遇到了构造函数参数未传入的错误,具体情况如下:
我的配置与代码
服务配置
services: project.registration.controller: class: Project\UserBundle\Controller\RegistrationController arguments: [ @event_dispatcher,@fos_user.registration.form.factory,@fos_user.user_manager,@security.token_storage]
控制器代码
<?php namespace Project\UserBundle\Controller; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use FOS\UserBundle\Form\Factory\FactoryInterface; use FOS\UserBundle\Model\UserManagerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use FOS\UserBundle\Controller\RegistrationController as BaseController; class RegistrationController extends BaseController { public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager, TokenStorageInterface $tokenStorage) { parent::__construct($eventDispatcher, $formFactory, $userManager, $tokenStorage); } }
错误信息
Catchable Fatal Error: Argument 1 passed to Project\UserBundle\Controller\RegistrationController::__construct() must implement interface Symfony\Component\EventDispatcher\EventDispatcherInterface, none given, called in C:\wamp\www\cmagic\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Controller\ControllerResolver.php on line 187 and defined
问题原因与解决步骤
这个错误的核心原因是:Symfony默认的控制器解析器没有从你的服务容器中获取控制器实例,而是直接实例化了你的RegistrationController类,自然没有传入构造函数所需的参数。
你需要做的是覆盖FOSUserBundle原有的注册控制器服务,而不是自定义一个新的服务ID,具体修改如下:
修改服务配置,替换原FOSUserBundle的控制器服务
FOSUserBundle的注册控制器服务ID是fos_user.registration.controller,你需要把这个服务替换成自己的控制器类,而不是定义新的project.registration.controller:services: fos_user.registration.controller: class: Project\UserBundle\Controller\RegistrationController arguments: - @event_dispatcher - @fos_user.registration.form.factory - @fos_user.user_manager - @security.token_storage确保路由使用正确的控制器服务
如果你使用的是FOSUserBundle自带的注册路由,那么替换服务后会自动使用你的控制器;如果是自定义路由,需要用服务引用的方式指定控制器,比如:# 示例自定义路由 project_user_registration: path: /register defaults: { _controller: fos_user.registration.controller:registerAction }可选:启用控制器参数解析器(Symfony 2.8+)
如果你不想覆盖原服务,也可以在config.yml中启用参数解析器,让Symfony自动注入构造函数参数:framework: controller: argument_resolver: enabled: true不过这种方式在Symfony 2.8中属于新特性,覆盖原服务的方式更符合FOSUserBundle的常规扩展流程。
完成以上修改后,清除缓存(php app/console cache:clear),再访问注册页面应该就能正常加载了。
内容的提问来源于stack exchange,提问作者Fabien Claude

