Symfony 6 仅序列化 Json Response 中第一次出现的连接对象

问题描述 投票:0回答:1

不确定标题是否有意义,但会尝试用示例进行解释:

例如,我有以下实体:

#[ORM\Entity(repositoryClass: Post::class)]
class Post
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

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

    #[ORM\ManyToOne(inversedBy: 'post')]
    private ?User $user = null;
}

还有

#[ORM\Entity(repositoryClass: User::class)]
#[UniqueEntity(fields: ['email'], message: 'There is already an account with this email')]
class User
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 180, unique: true)]
    private ?string $email = null;

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

    #[ORM\OneToMany(mappedBy: 'posts', targetEntity: Post::class)]
    private Collection $posts;
}

联接是 OneToMany,其中每个用户可以有多个帖子,每个帖子只能有一个用户。

User::$summary 是数据库中的一个 blob,因此我有一个流标准化器,用于在通过 json 响应进行标准化时将 PHP 流资源转换为字符串。这只是通过调用 is_resource($data) 检查要求标准化的 $data 是否是流资源。如果为 true,则可以通过此类对其进行标准化。

class StreamNormalizer implements NormalizerInterface
{
    public function __construct(
    ) {
    }


    public function normalize( $topic, string $format = null, array $context = [])
    {

        $data = stream_get_contents($topic);

        return $data;
    }

    public function supportsNormalization($data, string $format = null, array $context = []): bool
    {
        return is_resource($data);
    }
}

我用来获取帖子数据的 Post 控制器中的路由是:

#[Route('/feed', name: 'app_post_feed', methods: 'GET')]
public function feed(EntityManagerInterface $entityManager): Response
{
    $posts = $entityManager->getRepository(Post::class)->findAll();
    
    return $this->json($posts);
}

这按预期工作,除非用户发布了多个帖子,然后该用户对象的所有后续出现的 $summary 为空:

[
    {
        "id": 1,
        "user": {
            "id": 1,
            "summary": "This is a summary",
            "email": "[email protected]",
            "userIdentifier": "[email protected]",
            "verified": false
        }
    },
    {
        "id": 2,
        "user": {
            "id": 1,
            "summary": "",
            "email": "[email protected]",
            "userIdentifier": "[email protected]",
            "verified": false
        }
    }
}

如您所见,我有 2 个帖子,都是同一用户的。但仅设置了第一个帖子的用户的摘要,第二个帖子的用户缺少其摘要值,即使他们是同一用户!

我猜这可能是有意的行为,为了性能而不多次重新规范化对象?但我希望同一实体的所有出现的数据都是相同的?

我尝试调整我的标准化器,以防它试图重新标准化已经标准化的对象,但这没有什么区别:

class StreamNormalizer implements NormalizerInterface
{
    public function __construct(
    ) {
    }


    public function normalize( $topic, string $format = null, array $context = [])
    {

        $data = is_resource($topic) ? stream_get_contents($topic) : $topic;

        return $data;
    }

    public function supportsNormalization($data, string $format = null, array $context = []): bool
    {
        return is_resource($data);
    }
}

根据@Dylan的建议,将吸气剂调整为以下内容仍然没有解决问题:

public function getSummary()
{
    return is_resource($this->summary) ? stream_get_contents($this->summary) : $this->summary;
}

我已经四处搜索,但由于我不确定如何表达这个问题,所以我没有找到与我面临的问题类似的内容。如果这个问题已经在某个地方得到了回答,那么我们将不胜感激!

如果有人知道如何调整它,以便它为所有重复对象的出现返回相同的结果,那将很有帮助!

symfony doctrine-orm doctrine symfony6 symfony-serializer
1个回答
0
投票

在另一个网站上的回答: https://github.com/symfony/symfony/discussions/51430

事实证明,我需要在获取流的内容后倒回流,否则指针(我假设?)仍然位于流的末尾,因此之后没有任何值。

我的新 StreamNormalizer:

class StreamNormalizer implements NormalizerInterface
{
    public function __construct(
    ) {
    }


    public function normalize( $topic, string $format = null, array $context = [])
    {
        //get stream contents
        $data = stream_get_contents($topic);

        //rewind stream to revert the pointer to the start when this stream is read again
        rewind($topic);

        return $data;
    }

    public function supportsNormalization($data, string $format = null, array $context = []): bool
    {
        return is_resource($data);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.