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

时间:2014-04-14 03:38:25

标签: php json symfony deserialization jmsserializerbundle

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

这里输出:

{
    "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中的Serializer给我一个错误......

我的错误:

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

我如何反序列化:

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

如何反序列化数据数组...拥有一个Postes数组。我想给我的观点.twig一个数组Poste ...我在反序列化时做了精确的类型......所以我找不到问题所在......

感谢。

6 个答案:

答案 0 :(得分:17)

我认为这里最好的解决方案是创建新的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 and setters here...
}

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

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

这样就可以了,并且它并不需要你手动解码和编码你的json,这在我看来很荒谬。

答案 1 :(得分:12)

我发现一个不太理想的解决方案是首先解码然后在表示数据阵列的节点处再次编码json数据。例如,在您的情况下:

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

必须有一个比这个更好的解决方案,但这似乎比上面的反序列化json解决方案更优雅。

答案 2 :(得分:8)

错误很清楚。你的字符串与任何现有的类都不匹配。

The example in official documentation says:

$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);

然后您可以使用

访问每个'data'数组
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. */
}

答案 3 :(得分:4)

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

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

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

答案 4 :(得分:1)

我会做这样的事情

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,其中将包含您的实体数组

答案 5 :(得分:0)

如果有人要搜索如何使用 Symfony Serializer 解码一组对象:

use Moodress\Bundle\PosteBundle\Entity\Poste;

// your json data 
$data = '{
  "total":2,
  "data":[
    {...},
    {...}
  ]
}';

$lastPosts = $serializer->deserialize(
    $data['data'],
    'Poste[]', // or Poste::class.'[]',
    'json'
);

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