Symfony中如何将Voters注入Form Types?注入遇构造函数参数错误
哎,这个错误我太熟了——本质就是你的UserType表单类需要AuthorizationChecker实例来做角色判断,但Symfony的容器在创建这个表单的时候没给它传这个依赖,所以直接抛错了。结合你说的Bart的方案,我给你一步步捋怎么修复:
1. 先确认你的UserType构造函数写法正确
首先确保你的表单类里已经正确声明了依赖,注意要用接口而不是具体类(这是Symfony依赖注入的最佳实践):
// PortalBundle/Form/UserType.php namespace PortalBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; class UserType extends AbstractType { private $authorizationChecker; // 这里一定要用AuthorizationCheckerInterface,不要用具体的AuthorizationChecker类 public function __construct(AuthorizationCheckerInterface $authorizationChecker) { $this->authorizationChecker = $authorizationChecker; } public function buildForm(FormBuilderInterface $builder, array $options) { // 比如在这里用权限检查来动态添加字段 $builder->add('username'); if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) { $builder->add('voters'); // 这就是你要访问的Voters字段吧? } } // ... 其他必要的方法(比如configureOptions) }
2. 把UserType注册为Symfony服务
这是最关键的一步——Symfony的表单类型如果需要依赖注入,必须被注册为服务,这样容器才会自动把AuthorizationChecker传给它。
方法A:用YAML配置服务(适合所有Symfony版本)
打开你的config/services.yaml(或者PortalBundle下的Resources/config/services.yaml),添加以下配置:
services: PortalBundle\Form\UserType: arguments: ['@security.authorization_checker'] tags: ['form.type'] # 这个标签告诉Symfony这是一个表单类型
方法B:用自动注册(Symfony 3.3+推荐)
如果你的项目已经开启了服务自动注册(现在大部分项目都是默认开启的),只需要给UserType加个注解,让Symfony自动把它标记为表单类型:
// 在UserType类顶部加注解 use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; #[AutoconfigureTag('form.type')] class UserType extends AbstractType { // ... 你的构造函数和buildForm代码 }
同时确保你的services.yaml里有类似这样的自动注册配置:
services: _defaults: autowire: true # 自动注入依赖 autoconfigure: true # 自动配置标签 public: false PortalBundle\: resource: '../src/PortalBundle/' exclude: '../src/PortalBundle/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
3. 确保控制器里正确创建表单
最后别踩这个坑:绝对不要手动new UserType()来创建表单!一定要用Symfony的createForm方法,这样容器才会帮你拿已经注入好依赖的表单实例:
// 控制器里的正确写法 public function edit(Request $request, User $user) { // 直接传类名,不要new! $form = $this->createForm(UserType::class, $user); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { // ... 保存逻辑 } return $this->render('user/edit.html.twig', [ 'form' => $form->createView(), ]); }
这样一套操作下来,那个构造函数参数缺失的错误应该就消失了,你也能正常在UserType里用AuthorizationChecker来根据角色控制Voters字段的显示啦。
内容的提问来源于stack exchange,提问作者Thomas Fournet
相关产品推荐
相关产品推荐

