webentwicklung-frage-antwort-db.com.de

Symfony - Deserialisierung von Json in ein Array von Entitäten

Ich habe ein Json-Objekt, das ich durch einen get-API-Aufruf erhalten habe. Ich mache diesen Anruf, um eine Liste von Objekten zu erhalten. Es ist eine Liste von Posts. Ich habe also eine Reihe von Post-Objekten. 

Hier die Ausgabe:

{
    "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"
      }
    ]
 }

Ich möchte den Datenteil deserialisieren ... Das Problem ist, dass der Serializer in Symfony einen Fehler ausgibt ...

Der Fehler, den ich habe:

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

Wie ich deserialiere:

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

Wie kann ich das Datenarray deserialze ... Um ein Array von Postes zu haben. Ich möchte meiner Ansicht nach .twig eine Array-Poste geben ... Ich habe den Typ bei der Deserialisierung genau festgelegt ... Also kann ich nicht finden, was das Problem ist ... 

Vielen Dank.

12
manonthemoon

Der Fehler ist ziemlich klar. Ihre Zeichenfolge stimmt mit keiner vorhandenen Klasse überein.

Das Beispiel in der offiziellen Dokumentation sagt:

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

In Ihrem Fall sollte es eher so sein:

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

Update:

OK dann.

Erstens scheint Ihre Json-Datei nicht gültig zu sein (verwenden Sie http://jsonlint.com/ , um sie zu testen). Seien Sie vorsichtig.

Zweitens müssen Sie Ihren Json als Array mit abholen

$data = json_decode($yourJsonFile, true);

und dann können Sie mit auf jedes Datenarray zugreifen

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

Ich denke, dass die beste Lösung hier ist, eine neue PosteResponse-Klasse wie diese zu erstellen:

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...
}

und deserialisieren Sie Ihre Antwort auf diese Klasse:

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

Das wird den Trick tun, und Sie müssen Ihren Json nicht manuell decodieren und codieren, was meiner Meinung nach rätselhaft ist.

17
Mikz

Eine weniger als ideale Lösung, die ich fand, war, zuerst die Json-Daten an dem Knoten zu codieren, der das Datenarray darstellt. Zum Beispiel in Ihrem Fall:

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

Es muss eine bessere Lösung als diese geben, diese scheint jedoch eleganter als die obige Lösung zur Deserialisierung von Json.

12
Malachi

Da Symfony Serializer Component 2.8 ein Array von Objekten deserialisiert:

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

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

2
user6863579

Ich würde so etwas machen

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;
}

Und im Controller 

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

Und dies gibt $ postsModel mit der $ data -Eigenschaft zurück, die Ihr Array von Entitäten enthält

1
Ruslan Kovalov