2014-04-14 20 views
7

Tôi có một đối tượng json mà tôi nhận được bằng cách thực hiện cuộc gọi API. Tôi thực hiện cuộc gọi này để nhận danh sách các đối tượng. Đó là danh sách bài đăng ... Vì vậy, tôi có một mảng các đối tượng bài đăng.Symfony - Deserialize json vào một mảng các thực thể

Ở đây, đầu ra:

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

Tôi muốn deserialize phần dữ liệu ... Vấn đề là các Serializer trong Symfony mang lại cho tôi một lỗi ...

Các lỗi mà tôi có:

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

làm thế nào tôi deserialize:

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

Làm cách nào để loại bỏ mảng dữ liệu ... Để có một mảng Bài đăng. Tôi muốn cung cấp cho tôi xem .twig một mảng Poste ... Tôi đã làm chính xác loại khi tôi deserialize ... Vì vậy, tôi không thể tìm thấy những gì là vấn đề ...

Cảm ơn.

+0

Bạn có nhận được bất kỳ xa hơn với giải pháp của bạn? Tôi tự hỏi làm thế nào để có được JMS để phù hợp với một đối tượng 'dữ liệu' trong json. – Malachi

+0

Tôi không có sự lựa chọn ... Tôi chỉ làm một cho mỗi mảng, và deserialize dữ liệu cho mỗi giá trị ... Tôi đã có thể ưa thích nó một cách khác, nhưng tôi không thể tìm thấy bất kỳ giải pháp khác. – manonthemoon

Trả lời

4

Lỗi này khá rõ ràng. Chuỗi của bạn không khớp với bất kỳ lớp tồn tại nào.

The example in official documentation says:

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

Trong trường hợp của bạn nên được nhiều hơn như:

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

Cập nhật:

Ok rồi.

Đầu tiên, tệp json của bạn có vẻ không hợp lệ (sử dụng http://jsonlint.com/ để kiểm tra). Hãy cẩn thận về điều đó.

Thứ hai, bạn sẽ phải lấy json bạn như là một mảng với

$data = json_decode($yourJsonFile, true); 

và sau đó bạn có thể truy cập đến từng mảng 'dữ liệu' với

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

Vấn đề là $ data ['data'] là một mảng của Postes ... Không chỉ là một ... Vì vậy, tôi phải hiểu cho serializer rằng tôi muốn deserialize một mảng của loại thực thể của tôi. Bạn biết ý tôi là gì không? – manonthemoon

+0

Tôi đã cập nhật câu trả lời của mình. Nên làm các trick. – Einenlum

+1

Vâng, tôi nghĩ về điều đó ... Như bạn đã nói, nó thực hiện thủ thuật, nhưng trong tài liệu, nó nói rằng có thể sắp xếp trực tiếp mảng ... Nếu tôi không tìm thấy giải pháp nào khác, tôi sẽ làm từng bước như bạn đã chứng minh. Tôi chỉ nghĩ rằng nó sẽ là tốt hơn để sử dụng các loại mảng ... Nhưng tôi không biết tại sao, JMSSerialize không giống như mã của tôi. – manonthemoon

12

Một ít hơn giải pháp lý tưởng mà tôi tìm thấy đầu tiên giải mã và sau đó mã hóa dữ liệu json một lần nữa tại nút đại diện cho mảng dữ liệu. Ví dụ: trong trường hợp của bạn:

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

Phải có giải pháp tốt hơn điều này nhưng điều này có vẻ thanh lịch hơn so với giải pháp không tuần tự hóa ở trên.

+0

Chính xác những gì tôi cần. Đây sẽ là câu trả lời được chấp nhận. –

15

Tôi nghĩ rằng giải pháp tốt nhất ở đây là tạo ra lớp PosteResponse mới, như thế này một:

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

và deserialize trả lời của bạn đến lớp rằng:

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

sẽ làm các trick, và nó không yêu cầu bạn giải mã và mã hóa json của bạn bằng tay mà là vô lý trong quan điểm của tôi.

Các vấn đề liên quan