Reputation: 385
I would like to convert a json into a object / model. If the json is only one-dimensional, it works perfectly.
But if it is multidimensional, only the outer (user) is converted, but not the inner (company), this remains an array. Can you help me with this?
The Models:
<?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;
}
}
?>
Convert json to model:
<?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
}
}
?>
Upvotes: 3
Views: 4641
Reputation: 385
I solved the problem.
On the one hand you need PHP 7. Annotations I have not yet tested.
Then the variable has to be set correctly in setCompany().
public function setCompany(Company $company) {
$this->company = $company;
}
And the ReflectionExtractor() must be used.
use Symfony\Component\Serializer\Normalizer;
use Symfony\Component\PropertyInfo\Extractor;
$objectNormalizer = new ObjectNormalizer(
null,
null,
null,
new ReflectionExtractor()
);
You only need deserialize()
, because it decode()
and denormalize()
.
http://symfony.com/doc/current/components/serializer.html
Full fixed code:
Company class:
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;
}
}
User class:
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;
}
}
?>
Controller class:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\Serializer\Normalizer;
use Symfony\Component\PropertyInfo\Extractor;
use Symfony\Component\Serializer;
class DefaultController extends Controller {
public function indexAction() {
$objectNormalizer = new ObjectNormalizer(
null,
null,
null,
new ReflectionExtractor()
);
$jsonEncoder = new JsonEncoder();
$serializer = new 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);
}
}
?>
Upvotes: 6