web-dev-qa-db-ja.com

Symfony-JSONをエンティティの配列にデシリアライズします

Get API呼び出しを行って受け取ったjsonオブジェクトがあります。この呼び出しを行って、オブジェクトのリストを受け取ります。これは投稿のリストです...だから私は投稿オブジェクトの配列を持っています。

ここでの出力:

{
    "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の配列を取得するには。私はビューに.twig配列を与えたい...私はデシリアライズするときにタイプを正確にした...それで私は問題が何であるかを見つけることができません...

ありがとう。

16
manonthemoon

エラーはかなり明確です。文字列が既存のクラスと一致しません。

公式ドキュメントの例では次のように書かれています:

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

ここでの最善の解決策は、次のような新しい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を手動でデコードおよびエンコードする必要はありませんが、これはばかげています。

19
Mikz

私が見つけた理想的ではない解決策は、最初にデータ配列を表すノードでjsonデータを最初にデコードしてからエンコードすることでした。あなたの場合の例:

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

これよりも良い解決策がなければなりませんが、これはjsonを逆シリアル化する上記の解決策よりもエレガントに見えます。

12
Malachi

Symfony Serializer Component 2.8オブジェクトの配列をデシリアライズするには:

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

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

6
user6863579

私はこのようなものを作ります

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を返します

1
Ruslan Kovalov