Symfony+JMS Serializer反序列化为现有对象

标签 symfony doctrine-orm jmsserializerbundle jms-serializer

我一直想知道是否可以使用 JMS Serializer 将 JSON 反序列化为现有对象。

通常,这对于使用 JSON 格式的新数据更新现有对象很有用。 Symfony 的标准反序列化器似乎提供了这一点,但我似乎无法通过 JMS 找到任何与此相关的信息。如果我想要序列化名称注释选项,则必须使用 JMS。

“解决方法”是反序列化,然后使用 Doctrine 的 EntityManager 进行合并,但效果有限,而且如果 JSON 不包含每个字段,您就无法轻松辨别哪些字段已更新。

最佳答案

我一直在努力寻找解决方案,但终于找到了,我们开始吧:

  • 您的services.yaml
    jms_serializer.object_constructor:
        alias: jms_serializer.initialized_object_constructor

    jms_serializer.initialized_object_constructor:
        class: App\Service\InitializedObjectConstructor
        arguments: ["@jms_serializer.unserialize_object_constructor"]
  • 创建类App\Service\InitializedObjectConstructor.php
<?php

declare(strict_types=1);

namespace App\Service;

use JMS\Serializer\Construction\ObjectConstructorInterface;
use JMS\Serializer\DeserializationContext;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\Visitor\DeserializationVisitorInterface;

class InitializedObjectConstructor implements ObjectConstructorInterface
{
    private $fallbackConstructor;

    /**
     * @param ObjectConstructorInterface $fallbackConstructor Fallback object constructor
     */
    public function __construct(ObjectConstructorInterface $fallbackConstructor)
    {
        $this->fallbackConstructor = $fallbackConstructor;
    }

    /**
     * {@inheritdoc}
     */
    public function construct(
        DeserializationVisitorInterface $visitor,
        ClassMetadata $metadata,
        $data,
        array $type,
        DeserializationContext $context
    ): ?object {
        if ($context->hasAttribute('target') && 1 === $context->getDepth()) {
            return $context->getAttribute('target');
        }

        return $this->fallbackConstructor->construct($visitor, $metadata, $data, $type, $context);
    }
}

  • 在您的 Controller 或服务文件中
        $object = $this->entityManager->find('YourEntityName', $id);

        $context = new DeserializationContext();
        $context->setAttribute('target', $object);

        $data = $this->serializer->deserialize($request->getContent(), 'YourEntityClassName', 'json', $context);

关于Symfony+JMS Serializer反序列化为现有对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52114926/

相关文章:

symfony - 如何从 JMS 序列化器获取始终数组?

php - Doctrine2 - 列在刷新之前更改为空

php - 在 Symfony2 中扩展超映射类不会在 MySQL 中添加列

php - Symfony 主义延迟加载属性

symfony - 使用 Symfony DI 容器的原则 2

jmsserializerbundle - JMS 序列化程序忽略 Knp 分页器的映射

php - Symfony2 - 显示动态可选角色

mongodb - Doctrine MongoDB 结果缓存

php - 如何在 Symfony2 中使用实体表单字段类型和 JUI 自动完成功能?

php - JMSSerializer 和 FOSRestBundle - 注释不起作用。 "Does not exist"