Symfony-将json反序列化为实体数组


Symfony - Deserialize json to an array of entities

我有一个json对象,我通过执行get API调用接收到该对象。我打这个电话是为了接收对象列表。这是一个帖子列表。。。所以我有一个Post对象数组。

这里的输出:

{
    "total":2,
    "data":[
      {
        "id":2,
        "user":{
          "id":1,
          "username":"sandro.tchikovani"             
        },
        "description":"cool",
        "nb_comments":0,
        "nb_likes":0,
        "date_creation":"2014-04-13T20:07:34-0700"
      },
      {
        "id":1,
        "user":{
           "id":1,
           "username":"sandro.tchikovani",
         },
        "description":"Premier pooooste #lol",
        "nb_comments":0,
        "nb_likes":0,
        "date_creation":"2014-04-13T15:15:35-0700"
      }
    ]
 }

我想反序列化数据部分。。。问题是Symfony中的序列化程序给了我一个错误。。。

我的错误:

Class array<Moodress'Bundle'PosteBundle'Entity'Poste> does not exist

如何反序列化:

$lastPosts = $serializer->deserialize($data['data'], 'array<Moodress'Bundle'PosteBundle'Entity'Poste>', 'json');

如何取消数据数组的序列化。。。拥有一个Postes数组。我想给我的观点。树枝阵列Poste。。。我在反序列化时确实精确了类型。。。所以我找不到问题出在哪里。。。

谢谢。

由于Symfony Serializer Component 2.8要反序列化对象数组:

$persons = $serializer->deserialize($data, 'Acme'Person[]', 'json');

https://symfony.com/doc/master/components/serializer.html#handling-阵列

我认为这里最好的解决方案是创建新的PosteResponse类,比如这个:

namespace Moodress'Bundle'PosteBundle'Response;
use JMS'Serializer'Annotation'Type;
class PosteResponse
{
    /**
     * @Type("integer")
     */
    private $total;
    /**
     * @Type("array<Moodress'Bundle'PosteBundle'Entity'Poste>")
     */
    private $data;
    //getters here
}

并反序列化您对该类的响应:

$response = $serializer->deserialize(
    $json,
    'Moodress'Bundle'PosteBundle'Response'PosteResponse',
    'json'
);
$posts = $response->getData();

这样就可以了,而且它不需要你手动解码和编码json,在我看来这太无聊了。

我发现的一个不太理想的解决方案是首先对json数据进行解码,然后在表示数据数组的节点上再次对其进行编码。例如:

$json = json_decode($json);
$json = json_encode($json->data);
$serializer->deserialize($json, 'array<Moodress'Bundle'PosteBundle'Entity'Poste>', 'json');

肯定有比这更好的解决方案,但这似乎比上面的json去串行化解决方案更优雅。

错误非常明显。您的字符串与任何现有类都不匹配。

官方文件中的例子是:

$person = $serializer->deserialize($data,'Acme'Person','xml');

在您的情况下,它应该更像:

$person = $serializer->deserialize($data['data'],'Moodress'Bundle'PosteBundle'Entity'Poste','json');

更新:

好吧。

首先,您的json文件似乎无效(使用http://jsonlint.com/以测试它)。小心点。

其次,您必须使用将json作为数组获取

$data = json_decode($yourJsonFile, true);

然后您可以使用访问每个"数据"阵列

foreach($data['data'] as $result)
{
    /* Here you can hydrate your object manually like:
    $person = new Person();
    $person->setId($user['id']);
    $person->setDescription($user['description']);
    Or you can use a denormalizer. */
}

我会制作这样的

class PostsModel
{
    /**
     * @var int
     */
    private $total;
    /**
     * @var PostModel[]
     */
    private $data;
}
class PostModel
{
    /**
     * @var int
     */
    private $id;
    /**
     * @var UserModel
     */
    private $user;
    /**
     * @var string
     */
    private $description;
    /**
     * @var  int
     */
    private $nb_comments;
    /**
     * @var int
     */
    private $nb_likes;
    /**
     * @var 'DateTime
     */
    private $date_creation;
}
class UserModel
{
    /**
     * @var int
     */
    private $id;
    /**
     * @var string
     */
    private $username;
}

和在控制器

            $posts = $this->serializer->deserialize($data, PostsModel::class, 'json');

这将返回带有$data属性的$postsModel,该属性将具有实体数组

如果有人正在搜索如何使用Symfony Serializer:解码对象数组

use Moodress'Bundle'PosteBundle'Entity'Poste;
// your json data 
$data = '{
  "total":2,
  "data":[
    {...},
    {...}
  ]
}';
$lastPosts = $serializer->deserialize(
    $data['data'],
    'Moodress'Bundle'PosteBundle'Entity'Poste[]', // or Poste::class.'[]',
    'json'
);

注意,您需要在类名后添加[],这样Symfony就会将json数据识别为对象数组。