如何从序列化的 JSON 更新 Doctrine 实体? [英] How to update a Doctrine Entity from a serialized JSON?

查看:31
本文介绍了如何从序列化的 JSON 更新 Doctrine 实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用 Symfony2 来创建 API.更新记录时,我们希望 JSON 输入代表一个序列化的更新实体.JSON 数据将不包含某些字段(例如, CreatedAt 应仅在创建实体时设置一次 - 并且永不更新).例如,这是一个 JSON PUT 请求示例:

We are using Symfony2 to create an API. When updating a record, we expect the JSON input to represent a serialized updated entity. The JSON data will not contain some fields (for instance, CreatedAt should be set only once when the entity is created - and never updated). For instance, here is an example JSON PUT request:

{"id":"1","name":"anyname","description":"anydescription"}

这是控制器上的 PHP 代码,它应该根据上面的 JSON 更新实体(我们使用的是 JMS 序列化程序包):

Here is the PHP code on the Controller that should update the entity according to the JSON above (we are using JMS serializer Bundle):

$supplier = $serializer->deserialize(
    $this->get('request')->getContent(),
    'WhateverEntity',
    'json'
);

EntityManger 理解(正确)这是一个更新请求(实际上,一个 SELECT 查询是隐式触发的).EntityManager 还猜测(不正确) CreatedAt 属性应该是 NULLified - 它应该保留前一个.

The EntityManger understands (correctly) that this is an update request (in fact, a SELECT query is implicitly triggered). The EntityManager also guess (not correctly) that CreatedAt property should be NULLified - it should instead keep the previous one.

如何解决这个问题?

推荐答案

我会使用 DoctrineORMMappingClassMetadata API 来发现实体中的现有字段.您可以执行以下操作(我不知道 JMSSerializerBundle 是如何工作的):

I would use the DoctrineORMMappingClassMetadata API to discover existing fields in your entity. You can do following (I don't know how JMSSerializerBundle works):

//Unserialize data into $data
$metadata = $em->getMetadataFactory()->getMetadataFor($FQCN);
$id = array();
foreach ($metadata->getIdentifierFieldNames() as $identifier) {
    if (!isset($data[$identifier])) {
        throw new InvalidArgumentException('Missing identifier');
    }
    $id[$identifier] = $data[$identifier];
    unset($data[$identifier]);
}
$entity = $em->find($metadata->getName(), $id);
foreach ($metadata->getFieldNames() as $field) {
    //add necessary checks about field read/write operation feasibility here
    if (isset($data[$field])) {
        //careful! setters are not being called! Inflection is up to you if you need it!
        $metadata->setFieldValue($entity, $field, $data[$field]);
    }
}
$em->flush();

这篇关于如何从序列化的 JSON 更新 Doctrine 实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆