You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 7.2.*表单调用User实体无法读取user_email属性求助

Symfony 7.2.x 表单读取User实体属性错误问题

开发Symfony 7.2.x版本表单时,调用User实体出现错误:无法读取类App\Entity\User中的user_email属性,但该属性确实存在于实体中。以下是相关代码,请求解决该问题。

User实体代码

<?php

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`')]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['user_email'])]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $user_id = null;

    #[ORM\Column(length: 180)]
    private ?string $user_email = null;

    /**
     * @var list<string> The user roles
     */
    #[ORM\Column]
    private array $user_roles = [];

    /**
     * @var ?string The hashed password
     */
    #[ORM\Column]
    private ?string $user_password = null;

    #[ORM\Column(length: 50, nullable: true)]
    private ?string $user_firstname = null;

    #[ORM\Column(length: 50, nullable: true)]
    private ?string $user_surname = null;

    #[ORM\Column(length: 15, nullable: true)]
    private ?string $user_phone = null;

    #[ORM\Column(length: 200, nullable: true)]
    private ?string $user_address = null;

    #[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
    private ?\DateTime $user_birthdate = null;

    #[ORM\Column(type: Types::BLOB, nullable: true)]
    private $user_photo = null;

    #[ORM\Column(length: 50)]
    private ?string $user_pseudo = null;

    public function getId(): ?int
    {
        return $this->user_id;
    }

    public function getEmail(): ?string
    {
        return $this->user_email;
    }

    public function setEmail(string $user_email): static
    {
        $this->user_email = $user_email;

        return $this;
    }

    /**
     * A visual identifier that represents this user.
     *
     * @see UserInterface
     */
    public function getUserIdentifier(): string
    {
        return (string) $this->user_email;
    }

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $user_roles = $this->user_roles;
        // guarantee every user at least has ROLE_USER
        $user_roles[] = 'ROLE_USER';

        return array_unique($user_roles);
    }

    /**
     * @param list<string> $user_roles
     */
    public function setRoles(array $user_roles): static
    {
        $this->user_roles = $user_roles;

        return $this;
    }

    /**
     * @see PasswordAuthenticatedUserInterface
     */
    public function getPassword(): ?string
    {
        return $this->user_password;
    }

    public function setPassword(string $user_password): static
    {
        $this->user_password = $user_password;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials(): void
    {
        // If you store any temporary, sensitive data on the user, clear it here
        // $this->plainPassword = null;
    }

    public function getUserFirstname(): ?string
    {
        return $this->user_firstname;
    }

    public function setUserFirstname(?string $user_firstname): static
    {
        $this->user_firstname = $user_firstname;

        return $this;
    }

    public function getUserSurname(): ?string
    {
        return $this->user_surname;
    }

    public function setUserSurname(?string $user_surname): static
    {
        $this->user_surname = $user_surname;

        return $this;
    }

    public function getUserPhone(): ?string
    {
        return $this->user_phone;
    }

    public function setUserPhone(?string $user_phone): static
    {
        $this->user_phone = $user_phone;

        return $this;
    }

    public function getUserAddress(): ?string
    {
        return $this->user_address;
    }

    public function setUserAddress(?string $user_address): static
    {
        $this->user_address = $user_address;

        return $this;
    }

    public function getUserBirthdate(): ?\DateTime
    {
        return $this->user_birthdate;
    }

    public function setUserBirthdate(?\DateTime $user_birthdate): static
    {
        $this->user_birthdate = $user_birthdate;

        return $this;
    }

    public function getUserPhoto()
    {
        return $this->user_photo;
    }

    public function setUserPhoto($user_photo): static
    {
        $this->user_photo = $user_photo;

        return $this;
    }

    public function getUserPseudo(): ?string
    {
        return $this->user_pseudo;
    }

    public function setUserPseudo(string $user_pseudo): static
    {
        $this->user_pseudo = $user_pseudo;

        return $this;
    }

}

RegisterUserTypeForm表单代码

<?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
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 RegisterUserTypeForm extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('user_email', EmailType::class, [
                'label' => 'Saisir une adresse mail valide',
                'attr' => [
                    'placeholder' => 'Adresse@mail.com'
                ]
            ])
            ->add('user_pseudo', TextType::class, [
                'label' => 'Saisir un nom d\'utilisateur',
                'attr' => [
                    'placeholder' => 'Pseudo-123'
                ]
            ])
            ->add('user_password', PasswordType::class, [
                'label' => 'Saisir un mot de passe',
                'attr' => [
                    'placeholder' => '************'
                ]
            ])
            ->add('submit', SubmitType::class, [
                'label' => 'Valider',
                'attr' => [
                    'class' => 'button'
                ]
            ]);

    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => User::class,
        ]);
    }
}

RegisterController控制器代码

<?php

namespace App\Controller;

use App\Entity\User;
use App\Form\RegisterUserTypeForm;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

final class RegisterController extends AbstractController
{
    #[Route('/Inscription', name: 'app_register')]
    public function index(Request $request, EntityManagerInterface $entityManager): Response
    {
        $user = new User();

        $form = $this->createForm(RegisterUserTypeForm::class, $user);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $entityManager->persist($user);
            $entityManager->flush();
        }

        return $this->render('register/index.html.twig', [
            'registerForm' => $form->createView(),
        ]);
    }
}

问题原因与解决方法

问题根源

Symfony表单默认通过字段名匹配对应的getter/setter方法:表单中使用user_email字段,会自动尝试调用getUserEmail()和setUserEmail()方法,但你的User实体中,该属性对应的方法是getEmail()和setEmail(),导致属性读取失败。同理,user_password字段也存在相同问题,实体中是getPassword()而非getUserPassword()。

解决方式一(推荐):修改表单字段的属性映射

在表单的字段配置中,添加property_path参数,指定实体中对应的方法名(去掉前缀get/set后的驼峰名):

$builder
    ->add('user_email', EmailType::class, [
        'label' => 'Saisir une adresse mail valide',
        'attr' => [
            'placeholder' => 'Adresse@mail.com'
        ],
        'property_path' => 'email' // 指定对应getEmail()/setEmail()
    ])
    ->add('user_pseudo', TextType::class, [
        'label' => 'Saisir un nom d\'utilisateur',
        'attr' => [
            'placeholder' => 'Pseudo-123'
        ]
    ])
    ->add('user_password', PasswordType::class, [
        'label' => 'Saisir un mot de passe',
        'attr' => [
            'placeholder' => '************'
        ],
        'property_path' => 'password' // 指定对应getPassword()/setPassword()
    ])
    // ... 其他字段

这种方式不需要修改实体方法,避免影响Symfony Security组件的默认约定(getEmail()、getPassword()是Security组件要求的标准方法)。

解决方式二:修改实体的getter/setter方法名

将实体中的getEmail()改为getUserEmail(),setEmail()改为setUserEmail();getPassword()改为getUserPassword(),setPassword()改为setUserPassword(),保持和表单字段名一致:

// 修改后的Email方法
public function getUserEmail(): ?string
{
    return $this->user_email;
}

public function setUserEmail(string $user_email): static
{
    $this->user_email = $user_email;

    return $this;
}

// 修改后的Password方法
public function getUserPassword(): ?string
{
    return $this->user_password;
}

public function setUserPassword(string $user_password): static
{
    $this->user_password = $user_password;

    return $this;
}

注意:此方式需要同时保留getEmail()和getPassword()方法(或者修改getUserIdentifier()和Security相关逻辑),否则会导致Symfony Security组件无法正常工作。

内容的提问来源于stack exchange,提问作者NoGrand6724

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 05:39:54