Symfony3.4 FOSUserBundle重置控制器依赖注入仅dev环境生效
问题根因
dev环境运行正常、prod环境报构造函数传参不足,核心原因是你定义的ResettingController服务在prod环境下无法被ControllerResolver正确识别拉取,Symfony触发默认的控制器直接实例化逻辑,没有传入构造函数要求的6个依赖项。
常见触发场景有两个:
- Symfony 3.4及以上版本默认所有服务
public: false,你定义的fos_user.resetting.reset服务没有显式设置public属性。dev环境容器不会严格限制私有服务的获取,因此可以正常调用;prod环境容器做了编译优化,私有服务无法被ControllerResolver直接拉取,就会绕过服务定义直接实例化控制器类,导致传参缺失。 - prod环境缓存生成时权限配置错误,web服务进程(nginx/apache/php-fpm的运行用户)无法读取重新编译后的容器缓存文件,回退到旧的实例化逻辑。
解决步骤
按顺序操作即可修复:
- 修正services.yml中的服务定义,显式将控制器服务标记为public,修改后的配置如下:
//services.yml services: fos_user.resetting.reset: class: FOS\UserBundle\Controller\ResettingController public: true arguments: - "@event_dispatcher" - "@fos_user.resetting.form.factory" - "@fos_user.user_manager" - "@fos_user.util.token_generator" - "@fos_user.mailer" - "%fos_user.resetting.retry_ttl%"
- 修正routing.yml中的路由配置,显式绑定对应服务id,不要使用控制器短命名写法,避免ControllerResolver走默认实例化逻辑。找到
fos_user_resetting_reset配置段,修改defaults部分:
fos_user_resetting_reset: path: /resetting/reset/{token} methods: ['GET', 'POST'] defaults: { _controller: fos_user.resetting.reset:resetAction }
- 使用正确权限重新生成prod环境缓存,避免权限导致的缓存读取异常(以下命令中
www-data替换为你实际的web服务运行用户):
rm -rf var/cache/prod sudo -u www-data bin/console cache:clear --env=prod --no-debug sudo -u www-data bin/console cache:warmup --env=prod --no-debug
- 前置检查项:
- 确认上述services.yml配置写在全局生效的配置文件(如
app/config/services.yml)中,不是仅写在config/services_dev.yml这类仅dev环境加载的配置文件里 - 确认项目没有额外加载FOSUserBundle默认的路由配置文件,避免自定义路由被默认路由覆盖,默认路由的短命名控制器写法在新版本FOSUserBundle下会触发相同报错
- 确认prod环境debug模式处于关闭状态,避免环境配置不一致
修改完成后直接访问密码重置链接即可验证,此时ControllerResolver会直接从容器中拉取提前配置好依赖的public控制器服务,不会再出现参数不足的报错。
内容的提问来源于stack exchange,提问作者Jjanin
相关产品推荐
相关产品推荐

