我有这个实体
<?php
namespace App\Domain\Entity;
use App\Domain\ValueObject\Email;
use App\Domain\ValueObject\Name;
use App\Domain\ValueObject\Password;
use App\Domain\ValueObject\Surname;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
public function __construct(
private UuidInterface $id,
private Name $name,
private Surname $surname,
private Email $email,
private Password $password,
private array $roles = []
) {}
public function getId(): UuidInterface
{
return $this->id;
}
public function setId(UuidInterface $id): void
{
$this->$id = $id;
}
public function getName(): Name
{
return $this->name;
}
public function setName(Name $name): void
{
$this->name = $name;
}
public function getSurname(): Surname
{
return $this->surname;
}
public function setSurname(Surname $surname): void
{
$this->surname = $surname;
}
public function getEmail(): string
{
return $this->email->value();
}
public function setEmail(String $email): void
{
$this->$email = new Email($email);
}
public function getVOEmail(): Email
{
return $this->email;
}
public function setVOEmail(Email $email): void
{
$this->$email = $email;
}
public function getVOPassword(): Password
{
return $this->password;
}
public function setVOPassword(Password $password): void
{
$this->password = $password;
}
public function getPassword(): ?string
{
return $this->password->value();
}
public function setPassword(string $password): static
{
$this->password = $password;
return $this;
}
/**
* Get the roles granted to the user.
*/
public function getRoles(): array
{
// Garantizar que cada usuario tenga al menos el rol ROLE_USER
if (empty($this->roles)) {
$this->roles[] = 'ROLE_USER';
}
return array_unique($this->roles);
}
/**
* Set the roles for the user.
*/
public function setRoles(array $roles): static
{
$this->roles = $roles;
return $this;
}
/**
* Get the user identifier (e.g., email).
*/
public function getUserIdentifier(): string
{
return $this->email->value(); // O cualquier otro identificador único
}
/**
* Erase any sensitive information.
*/
public function eraseCredentials(): void
{
// Si hay información sensible que deseas eliminar, hazlo aquí.
// Por ejemplo, si usaste una contraseña sin encriptar durante la autenticación:
// $this->plainPassword = null; // O cualquier otro campo temporal.
}
}
这样映射
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.githubusercontent.com/doctrine/doctrine2/main/doctrine-mapping.xsd">
<!-- Definición de la entidad -->
<entity name="App\Domain\Entity\User" table="`user`" repository-class="App\Infrastructure\Service\UserRepository">
<!-- Identificador (ID) -->
<id name="id" type="uuid" column="id">
<generator strategy="NONE"/> <!-- Usamos un UUID generado manualmente -->
</id>
<!-- Definición de los campos -->
<embedded name="email" class="App\Domain\ValueObject\Email" use-column-prefix="false"/>
<embedded name="name" class="App\Domain\ValueObject\Name" use-column-prefix="false"/>
<embedded name="surname" class="App\Domain\ValueObject\Surname" use-column-prefix="false"/>
<embedded name="password" class="App\Domain\ValueObject\Password" use-column-prefix="false"/>
<!-- Definición de la columna JSON para los roles -->
<field name="roles" type="json" column="roles"/>
</entity>
</doctrine-mapping>
和可嵌入映射
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.githubusercontent.com/doctrine/doctrine2/main/doctrine-mapping.xsd">
<!-- Definición del objeto embebido -->
<embeddable name="App\Domain\ValueObject\Email">
<!-- Campo de la clase Email -->
<field name="value" column="email" type="string" length="255" nullable="false"/>
</embeddable>
</doctrine-mapping>
电子邮件是一个值对象(与属性上的其余部分一样),我使用了属性的嵌入式类,我的工作是将用户存储在数据库中,但不是使用
LexikJWTAuthenticationBundle
登录,问题是当我尝试登录用户我收到此错误Unrecognized field: App\Domain\Entity\User::$email
调试发现这段代码
$this->class->fieldMappings[$field]
不会将字段名称重新调整为电子邮件、姓名、姓氏...它会在类中返回 email.value 、name.value...,因为电子邮件值包含在名为
$value
的变量中
<?php
namespace App\Domain\ValueObject;
class Email
{
public function __construct(private string $value)
{}
public function value(): string
{
return $this->value;
}
}
我不知道如何在调用
name
时获取 name.value
而不是 $this->class->fieldMappings[$field]
,名称已在 xml 配置文件中设置
将用户名和电子邮件等数据保存为 VO 是非常非标准的方式。如果您放弃这个想法并重构您的实体以将此类数据保存为字符串(您始终可以创建专门的 getter 来设置和获取这些值作为 VO),您将从长远来看受益。
如果
LexikJWTAuthenticationBundle
仅限于使用 ORM 映射来获取这些属性,并且您无法覆盖此行为,那么不幸的是,我没有看到解决方案。作为最后的手段,您可以覆盖捆绑包本身中的这部分代码(如果可能的话,通过使用 symfony DI 覆盖服务),但我也不推荐这样做,因为它可能会导致更糟糕的情况和不可预测的情况未来(不提升级包后的问题)。
最后一件事,如果有办法以某种方式为
LexikJWTAuthenticationBundle
提供属性路径而不是映射字段,您可能可以创建一个单独的 getter (例如 getEmailValue
、getNameValue
),并使捆绑包使用 emailValue
和 nameValue
属性。但是,同样,这个捆绑包很可能无法开箱即用。