Symfony表单提交报错:预期string类型却传入User实体
问题解决:表单提交时类型不匹配错误
错误原因
你遇到的Expected argument of type "string", "App\Entity\User" given at property path "naamklant"错误,核心原因是数据类型不匹配:
Dagrooster实体中naamklant字段被定义为字符串类型,但表单里给该字段使用了EntityType组件,提交时会将选中的User对象赋值给它,直接触发类型校验失败。- 另外你已经在
Dagrooster中定义了User关联字段,naamklant属于冗余字段,完全可以通过关联关系存储用户数据。
解决方案
1. 修改Dagrooster实体,移除冗余字段并规范关联映射
删除实体中naamklant相关的属性、getter和setter方法,同时规范User关联字段的命名(首字母小写符合PHP命名规范):
<?php namespace App\Entity; use App\Repository\DagroosterRepository; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: DagroosterRepository::class)] class Dagrooster { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] private ?string $klant = null; #[ORM\Column(length: 255)] private ?string $kamer = null; #[ORM\Column(length: 255)] private ?string $onderwerp = null; #[ORM\Column(type: Types::DATETIME_MUTABLE)] private ?\DateTimeInterface $datum = null; #[ORM\ManyToOne(inversedBy: 'dagroosters')] #[ORM\JoinColumn(nullable: false)] // 强制必须选择用户 private ?User $user = null; public function getId(): ?int { return $this->id; } public function getKlant(): ?string { return $this->klant; } public function setKlant(string $klant): static { $this->klant = $klant; return $this; } public function getKamer(): ?string { return $this->kamer; } public function setKamer(string $kamer): static { $this->kamer = $kamer; return $this; } public function getOnderwerp(): ?string { return $this->onderwerp; } public function setOnderwerp(string $onderwerp): static { $this->onderwerp = $onderwerp; return $this; } public function getDatum(): ?\DateTimeInterface { return $this->datum; } public function setDatum(\DateTimeInterface $datum): static { $this->datum = $datum; return $this; } public function getUser(): ?User { return $this->user; } public function setUser(?User $user): static { $this->user = $user; return $this; } }
2. 调整DagroosterType表单,绑定正确的关联字段
将原表单中naamklant字段替换为user字段,保留你原有的QueryBuilder筛选逻辑,同时修正拼写错误并优化配置:
<?php namespace App\Form; use App\Entity\Dagrooster; use App\Entity\User; use Doctrine\ORM\EntityRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class DagroosterType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('klant', TextType::class, [ 'label' => 'Bedrijfsnaam', ]) ->add('kamer', ChoiceType::class, [ 'choices' => [ 'Kamer 1' => 1, 'Kamer 2' => 2, 'Kamer 3' => 3, ], 'choice_label' => fn($value) => "Kamer {$value}", 'data_class' => null, // 适配实体中kamer的string类型 ]) ->add('user', EntityType::class, [ 'label' => 'Naam klant', 'class' => User::class, 'query_builder' => fn(EntityRepository $er) => $er->createQueryBuilder('u') ->where('u.roles LIKE :role') ->setParameter('role', '%ROLE_MEMBER%'), 'choice_label' => fn(User $user) => $user->getFname(), 'required' => true, ]) ->add('onderwerp', TextType::class) ->add('datum', DateTimeType::class) ->add('submit', SubmitType::class) // 修正原拼写错误sumbit ; } public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Dagrooster::class, ]); // 移除不必要的ROLE_MEMBER配置项 } }
3. 同步数据库变更
执行以下命令生成并执行数据库迁移文件,确保实体变更同步到数据库:
php bin/console doctrine:migrations:diff php bin/console doctrine:migrations:migrate
额外说明
如果你的业务需要在Dagrooster中存储用户名称而非关联关系,可将表单中的EntityType替换为TextType,并手动处理用户名称的赋值,但这种方式会丢失数据关联的优势,不推荐使用。
内容的提问来源于stack exchange,提问作者bulent
相关产品推荐
相关产品推荐

