【问题标题】:What fields should be serialized for Symfony´s User and its related entities?Symfony 的用户及其相关实体应该序列化哪些字段?
【发布时间】:2020-11-15 08:12:19
【问题描述】:

我有我的 User 实体,它与另一个名为 Business 的实体相关

class User implements UserInterface, EquatableInterface
{
    // ...

    /**
     * @var Business
     * @ORM\ManyToOne(targetEntity="Business")
     * @ORM\JoinColumn(name="business_id", referencedColumnName="id", onDelete="CASCADE")
     */
    private $business;

    // ...

现在我注意到,Symfony\Component\Security\Core\Authentication\Token\AbstractToken 默认情况下每次更改都会序列化整个用户实体,包括相关业务。

现在我面临的第一个问题是为业务实体引入 $file 字段,其中一个字段未映射并存储无法序列化的 UploadedFile

/**
 * @var UploadedFile
 */
private $file;

现在每当我尝试上传文件时都会出错

不允许序列化“Symfony\Component\HttpFoundation\File\UploadedFile”

Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php抛出

当然我不需要序列化该字段,但我也不知道必须序列化哪些字段才能不丢失正确的 Symfony 逻辑。

到目前为止,我刚刚实现了 \Serializable 并仅序列化了业务实体的 id

class Business implements \Serializable
{
    // ...

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize([
            $this->id
        ]);
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list(
            $this->id
        ) = unserialize($serialized);
    }

现在我没有收到错误,但我不知道是否应该序列化除 $file 之外的所有字段或留下 $id 就好了。还有为什么会这样,为什么我们需要序列化用户关系?

【问题讨论】:

  • 序列化信息用于在请求开始时加载用户的当前副本。开箱即用,Doctrine UserProvider 仅使用 id 来说明其工作原理。但是,序列化信息可以选择用于确定自上次请求以来是否已更改任何与用户相关的数据库信息。特别是您可能想要检查密码是否已更改。这就是 EquatableInterface 的用武之地。查看 Symfony\Component\Security\Core\User::isEqualTo 以了解通常检查的内容。

标签: symfony doctrine-orm


【解决方案1】:

我在这里遇到了同样的问题。

我花了很多时间来寻找问题,解决方案是在 Serializable 上转换您的实体并创建方法。 但在此之前,您需要销毁/注销您已登录的会话。

在我的案例中,我正在实施 Serializable,但问题仍然存在,因为我没有退出旧会话,该会话不存在与此案例中的业务序列化相关的信息。

所以步骤是:

  1. 注销(如果您使用的表单引用了实体,则仅在用户已登录时才有效)
  2. 将实体转为可序列化
use Serializable;

class Business implements Serializable
{
    public function serialize()
    {
        return serialize(array(
            $this->id,
        ));
    }

    public function unserialize($serialized)
    {
        list (
            $this->id,
            ) = unserialize($serialized);
    }
}

它对我有用!

如果坚持,我在引发错误的字段上使用忽略注释找到了一些其他解决方案,它也可以工作。

class Business implements Serializable
{
    /**
     * @Vich\UploadableField(mapping="images", fileNameProperty="image")
     *
     * @Ignore()
     */
    private $imageFile;
}

【讨论】:

    猜你喜欢
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 2023-03-21
    • 1970-01-01
    • 2020-02-19
    相关资源
    最近更新 更多