PHP Symfony flex - десериализовать JSON в класс - PullRequest
0 голосов
/ 22 января 2019

У меня проблема с Symfony / Flex, когда я хочу десериализовать json в классах.

Вот пример JSON:

{
   "name": "Name",
   "ip_address" : "10.0.10.10",
   "data" : [
      {
         "name" : "LINE IDENTIFIER",
         "data2" : [
            {
               "start_interval" : "2019-01-18T12:00:00Z",
               "end_interval" : "2019-01-18T12:05:00Z",
               "in_count" : 100,
               "out_count" : 25
            },
            {
               "start_interval" : "2019-01-18T12:05:00Z",
               "end_interval" : "2019-01-18T12:10:00Z",
               "in_count" : 10,
               "out_count" : 15
            }

         ]
      },
      {
         "name" : "LINE IDENTIFIER",
         "data2" : [
            {
               "start_interval" : "2019-01-18T12:00:00Z",
               "end_interval" : "2019-01-18T12:05:00Z",
               "in_count" : 10,
               "out_count" : 5
            }
         ]
      }
   ]
}

Существует первый класс «Данные1» (класс записи):

<?php

namespace App\Entity;

use App\Entity\Data2;

/**
 * Data1 test class
 */
class Data1
{
    /**
     * [$name description]
     *
     * @var string
     */
    public $name;

    /**
     * [$ipAddressdescription]
     *
     * @var string
     */
    public $ipAddress;

    /**
     * [$data description]
     *
     * @var Data2[]
     */
    public $data;

    public function __construct(){
        $this->data= [];
    }

    /**
     * @return string|null
     */
    public function getName(){
        return $this->name;
    }

    /**
     * @param string|null $name
     */
    public function setName($name){
        $this->name = $name;
    }

    /**
     * @return string|null
     */
    public function getIpAddress(){
        return $this->ipAddress;
    }

    /**
     * @param string|null $ipAddress
     */
    public function setIpAddress($ipAddress){
        $this->ipAddress= $ipAddress;
    }


    /**
     * @return Data2[]
     */
    public function getData(){
        return $this->data;
    }

    /**
     * @param Data2 $data
     */
    public function addData(\App\Entity\Data2 $data){
        $this->data[] = $data;
    }

    public function __toString(){
        return $this->name . ' ' .
            $this->ipAddress . ' '
    }
}

Есть второй класс:

<?php

namespace App\Entity;

use App\Entity\Data3;

/**
 * Data2 test class
 */
class Data2
{
    /**
     * [$name description]
     *
     * @var string
     */
    public $name;

    /**
     * [$data2 description]
     *
     * @var Data3[]
     */
    public $data2;

    public function __construct(){
        $this->data2 = [];
    }

    /**
     * @return string|null
     */
    public function getName(){
        return $this->name;
    }

    /**
     * @param string|null $name
     */
    public function setName($name){
        $this->name= $name;
    }

    /**
     * @return Data3[]
     */
    public function getData2(){
        return $this->data2;
    }

    /**
     * @param Data3 $data
     */
    public function addData2(Data3 $data){
        $this->data2[] = $data;
    }

    public function __toString(){
        return $this->name . ' ' .
            join(' , ', $this->data);
    }
}

И третий:

<?php

namespace App\Entity;

/**
 * Data3 test class
 */
class Data3
{
    /**
     * [$startInterval description]
     *
     * @var Datetime
     */
    public $startInterval;

    /**
     * [$endInterval description]
     *
     * @var Datetime
     */
    public $endInterval;

    /**
     * [$inCount description]
     *
     * @var integer
     */
    public $inCount;

    /**
     * [$outCount description]
     *
     * @var integer
     */
    public $outCount;

    public function __construct(){
        print_r($this);
    }

    /**
     * @return Datetime
     */
    public function getStartInterval(){
        return $this->startInterval;
    }

    /**
     * @param Datetime $startInterval
     */
    public function setStartInterval($startInterval){
        $this->startInterval = $startInterval;
    }

    /**
     * @return Datetime
     */
    public function getEndInterval(){
        return $this->endInterval;
    }

    /**
     * @param Datetime $endInterval
     */
    public function setEndInterval($endInterval){
        $this->endInterval = $endInterval;
    }

    /**
     * @return integer|null
     */
    public function getInCount(){
        return $this->inCount;
    }

    /**
     * @param integer|null $inCount
     */
    public function setInCount($inCount){
        $this->inCount = $inCount;
    }

    /**
     * @return integer|null
     */
    public function getOutCount(){
        return $this->outCount;
    }

    /**
     * @param integer|null $outCount
     */
    public function setOutCount($outCount){
        $this->outCount = $outCount;
    }

    public function __toString(){
        return $this->startInterval . ' ' .
            $this->endInterval . ' ' .
            $this->inCount . ' ' .
            $this->outCount;
    }
}

Я хочу иметь возможность анализировать мой json напрямую в класс Data1 и, таким образом, заполнить этот класс подпараграфами Data2 и Data3.

Но пока я могу помещать значения только в Data1, не заполняя массив $ data экземплярами Data2.

Я использую этот код для десериализации:

$objectNormalizer = new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter(), null, new ReflectionExtractor());
$jsonEncoder = new JsonEncoder();
$serializer = new Serializer([$objectNormalizer], [$jsonEncoder]);

$result = $serializer->deserialize($json, Data1::class, 'json');

Где $ json - это json в строке.

Но я получаю эту ошибку, когда запускаю свой код:

app.ERROR: Symfony\Component\Serializer\Exception\NotNormalizableValueException: 
The type of the "countLines" attribute for class "App\Entity\Data1" must be one of "App\Entity\Data2[]" ("array" given). in __PATH__\project\vendor\symfony\serializer\Normalizer\AbstractObjectNormalizer.php:357

Если у кого-то есть способ сделать это, я был бы рад.

Заранее спасибо.

...