Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encode Doctrine entities to JSON in Symfony 2.0 AJAX application?

I'm developing game app and using Symfony 2.0. I have many AJAX requests to the backend. And more responses is converting entity to JSON. For example:

class DefaultController extends Controller
{           
    public function launchAction()
    {   
        $user = $this->getDoctrine()
                     ->getRepository('UserBundle:User')                
                     ->find($id);

        // encode user to json format
        $userDataAsJson = $this->encodeUserDataToJson($user);
        return array(
            'userDataAsJson' => $userDataAsJson
        );            
    }

    private function encodeUserDataToJson(User $user)
    {
        $userData = array(
            'id' => $user->getId(),
            'profile' => array(
                'nickname' => $user->getProfile()->getNickname()
            )
        );

        $jsonEncoder = new JsonEncoder();        
        return $jsonEncoder->encode($userData, $format = 'json');
    }
}

And all my controllers do the same thing: get an entity and encode some of its fields to JSON. I know that I can use normalizers and encode all entitities. But what if an entity has cycled links to other entity? Or the entities graph is very big? Do you have any suggestions?

I think about some encoding schema for entities... or using NormalizableInterface to avoid cycling..,

like image 246
Dmytro Krasun Avatar asked Jul 15 '11 11:07

Dmytro Krasun


3 Answers

With php5.4 now you can do :

use JsonSerializable;

/**
* @Entity(repositoryClass="App\Entity\User")
* @Table(name="user")
*/
class MyUserEntity implements JsonSerializable
{
    /** @Column(length=50) */
    private $name;

    /** @Column(length=50) */
    private $login;

    public function jsonSerialize()
    {
        return array(
            'name' => $this->name,
            'login'=> $this->login,
        );
    }
}

And then call

json_encode(MyUserEntity);
like image 124
SparSio Avatar answered Oct 23 '22 15:10

SparSio


Another option is to use the JMSSerializerBundle. In your controller you then do

$serializer = $this->container->get('serializer');
$reports = $serializer->serialize($doctrineobject, 'json');
return new Response($reports); // should be $reports as $doctrineobject is not serialized

You can configure how the serialization is done by using annotations in the entity class. See the documentation in the link above. For example, here's how you would exclude linked entities:

 /**
* Iddp\RorBundle\Entity\Report
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Iddp\RorBundle\Entity\ReportRepository")
* @ExclusionPolicy("None")
*/
....
/**
* @ORM\ManyToOne(targetEntity="Client", inversedBy="reports")
* @ORM\JoinColumn(name="client_id", referencedColumnName="id")
* @Exclude
*/
protected $client;
like image 85
scc Avatar answered Oct 23 '22 14:10

scc


You can automatically encode into Json, your complex entity with:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;

$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new 
JsonEncoder()));
$json = $serializer->serialize($entity, 'json');
like image 40
webda2l Avatar answered Oct 23 '22 15:10

webda2l