Symfony-десериализация json в массив сущностей

у меня есть объект 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<MoodressBundlePosteBundleEntityPoste> does not exist

как мне десериализовать :

$lastPosts = $serializer->deserialize($data['data'], 'array<MoodressBundlePosteBundleEntityPoste>', 'json');

как я могу deserialze массив данных... Иметь массив Postes. Я хочу дать свой взгляд .прутик массив посте... Я сделала точное типа когда я десериализации... Поэтому я не могу найти в чем проблема...

спасибо.

5 ответов


ошибка довольно ясно. Ваша строка не соответствует ни одному существующему классу.

пример в официальной документации написано:

$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. */
}

Я думаю, что лучшим решением здесь является создание нового класса 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 вручную, что, на мой взгляд, является загадочным.


менее идеальным решением, которое я нашел, было сначала декодировать, а затем снова кодировать данные json на узле, представляющем массив данных. Например в вашем случае:

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

должно быть лучшее решение, чем это, но это кажется более элегантным, чем вышеупомянутое решение де-сериализации json.


С Symfony Serializer Component 2.8 для десериализации массива объектов:

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

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


Я бы сделал что-то вроде этого

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

и это вернет $postsModel со свойством $data, которое будет иметь Ваш массив сущностей