Декодировать несколько моделей в PHP Symfony из JSON на объект

Я хотел бы преобразовать JSON в объект / модель. Если JSON только одномерный, он работает отлично.

Но если он многомерный, конвертируется только внешнее (пользователь), но не внутреннее (компания), это остается массивом. ты можешь помочь мне с этим?

Модели:

<?php
namespace AppBundle;

class Company {
    /**
     * @var string
     */
    protected $companyName = '';

    /**
     * @return string
     */
    public function getCompanyName()
    {
        return $this->companyName;
    }

    /**
     * @param string $companyName
     * @return void
     */
    public function setCompanyName($companyName)
    {
        $this->companyName = $companyName;
    }
}

class User {
    /**
     * @var \AppBundle\Company
     */
    protected $company = null;

    /**
     * @var string
     */
    protected $username = '';

    /**
     * @return \AppBundle\Company
     */
    public function getCompany() {
        return $this->company;
    }

    /**
     * @param \AppBundle\Company $company
     * @return void
     */
    public function setCompany($company) {
        $this->company = $company;
    }

    /**
     * @return string
     */
    public function getUsername() {
        return $this->username;
    }

    /**
     * @param string $username
     * @return void
     */
    public function setUsername($username) {
        $this->username = $username;
    }
}
?>

Конвертировать JSON в модель:

<?php
namespace AppBundle\Controller;

class DefaultController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{

    public function indexAction()
    {
        // Initialize serializer
        $objectNormalizer = new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer();
        $jsonEncoder = new \Symfony\Component\Serializer\Encoder\JsonEncoder();
        $serializer = new \Symfony\Component\Serializer\Serializer([$objectNormalizer], [$jsonEncoder]);

        // Set test model
        $company = new \AppBundle\Company();
        $company->setCompanyName('MyCompany');
        $user = new \AppBundle\User();
        $user->setCompany($company);
        $user->setUsername('MyUsername');

        // Serialize test model to json
        $json = $serializer->serialize($user, 'json');
        dump($user); // Model ok, Company is instance of \AppBundle\Company
        dump($json); // json ok + valide

        // Deserialize json to model
        $user = $serializer->deserialize($json, \AppBundle\User::class, 'json');
        dump($user); // Error: Company is now array instead instance of \AppBundle\Company

        // Denormalize json to model
        $userArray = $serializer->decode($json, 'json');
        $user = $serializer->denormalize($userArray, \AppBundle\User::class);
        dump($user); // Error: Company is now array instead instance of \AppBundle\Company
    }
}
?>

1 ответ

Я решил проблему.

С одной стороны вам нужен PHP 7. Аннотации я еще не тестировал.

Тогда переменная должна быть правильно установлена ​​в setCompany().

public function setCompany(Company $company) {
    $this->company = $company;
}

И ReflectionExtractor() должен быть использован.

$objectNormalizer = new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer(null, null, null, new \Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor());

Вам нужно только deserialize(), потому что он decode () и denormalize (). http://symfony.com/doc/current/components/serializer.html

Полный фиксированный код

class Company {
    /**
     * @var string
     */
    protected $companyName = '';

    /**
     * @return string
     */
    public function getCompanyName() {
        return $this->companyName;
    }

    /**
     * @param string $companyName
     * @return void
     */
    public function setCompanyName($companyName) {
        $this->companyName = $companyName;
    }
}

class User {
    /**
     * @var \AppBundle\Company
     */
    protected $company = null;

    /**
     * @var string
     */
    protected $username = '';

    /**
     * @return \AppBundle\Company
     */
    public function getCompany() {
        return $this->company;
    }

    /**
     * @param \AppBundle\Company $company
     * @return void
     */
    public function setCompany(Company $company) {
        $this->company = $company;
    }

    /**
     * @return string
     */
    public function getUsername() {
        return $this->username;
    }

    /**
     * @param string $username
     * @return void
     */
    public function setUsername($username) {
        $this->username = $username;
    }
}
?>

<?php
namespace AppBundle\Controller;

class DefaultController extends \Symfony\Bundle\FrameworkBundle\Controller\Controller {
    public function indexAction() {
        $objectNormalizer = new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer(null, null, null, new \Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor());
        $jsonEncoder = new \Symfony\Component\Serializer\Encoder\JsonEncoder();
        $serializer = new \Symfony\Component\Serializer\Serializer([$objectNormalizer], [$jsonEncoder]);

        $company = new \AppBundle\Company();
        $company->setCompanyName('MyCompany');

        $user = new \AppBundle\User();
        $user->setCompany($company);
        $user->setUsername('MyUsername');

        $json = $serializer->serialize($user, 'json');
        dump($user, $json);

        $user2 = $serializer->deserialize($json, \AppBundle\User::class, 'json');
        dump($user2);
    }
}
?>
Другие вопросы по тегам