Je développe une application de jeu et j'utilise Symfony 2.0. J'ai de nombreuses requêtes AJAX au backend. Et plus de réponses convertissent l'entité en JSON. Par exemple:
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');
}
}
Et tous mes contrôleurs font la même chose: obtenir une entité et encoder certains de ses champs en JSON. Je sais que je peux utiliser des normalisateurs et encoder tous les droits. Mais que se passe-t-il si une entité a cyclé des liens vers une autre entité? Ou le graphe d'entités est très grand? Avez-vous des suggestions?
Je pense à un schéma d'encodage pour les entités ... ou à l'utilisation NormalizableInterface
pour éviter le cyclisme ..,
la source
Avec php5.4, vous pouvez maintenant faire:
Et puis appelle
la source
OneToMany
relations)Vous pouvez encoder automatiquement dans Json, votre entité complexe avec:
la source
Pour compléter la réponse: Symfony2 est livré avec un wrapper autour de json_encode: Symfony / Component / HttpFoundation / JsonResponse
Utilisation typique dans vos contrôleurs:
J'espère que cela t'aides
J
la source
J'ai trouvé que la solution au problème de la sérialisation des entités était la suivante:
dans mon contrôleur:
autre exemple:
vous pouvez même le configurer pour désérialiser les tableaux dans http://api.symfony.com/2.0
la source
Je devais juste résoudre le même problème: encoder json une entité ("User") ayant une association bidirectionnelle un-à-plusieurs avec une autre entité ("Location").
J'ai essayé plusieurs choses et je pense que maintenant j'ai trouvé la meilleure solution acceptable. L'idée était d'utiliser le même code que celui écrit par David, mais d'intercepter d'une manière ou d'une autre la récursion infinie en disant au Normalizer de s'arrêter à un moment donné.
Je ne voulais pas implémenter de normalisateur personnalisé, car ce GetSetMethodNormalizer est une belle approche à mon avis (basée sur la réflexion, etc.). J'ai donc décidé de le sous-classer, ce qui n'est pas trivial à première vue, car la méthode pour dire s'il faut inclure une propriété (isGetMethod) est privée.
Mais, on pourrait remplacer la méthode de normalisation, donc j'ai intercepté à ce stade, en désactivant simplement la propriété qui fait référence à "Location" - donc la boucle inifinite est interrompue.
Dans le code, cela ressemble à ceci:
la source
J'ai eu le même problème et j'ai choisi de créer mon propre encodeur, qui se chargera tout seul de la récursivité.
J'ai créé des classes qui implémentent
Symfony\Component\Serializer\Normalizer\NormalizerInterface
, et un service qui contient toutNormalizerInterface
.Un exemple de normalisateur:
Dans un contrôleur:
Le code complet est ici: https://github.com/progracqteur/WikiPedale/tree/master/src/Progracqteur/WikipedaleBundle/Resources/Normalizer
la source
dans Symfony 2.3
/app/config/config.yml
et exemple pour votre contrôleur:
mais les problèmes avec le type de champ \ DateTime resteront.
la source
Ceci est plus une mise à jour (pour Symfony v: 2.7+ et JmsSerializer v: 0.13. * @ Dev) , donc pour éviter que Jms tente de charger et sérialiser l'ensemble du graphe d'objets (ou en cas de relation cyclique ..)
Modèle:
À l'intérieur d'une action:
la source
Si vous utilisez Symfony 2.7 ou supérieur et que vous ne souhaitez pas inclure de bundle supplémentaire pour la sérialisation, vous pouvez peut-être suivre cette méthode pour saisir les entités de doctrine en json -
Dans mon contrôleur (commun, parent), j'ai une fonction qui prépare le sérialiseur
Ensuite, utilisez-le pour sérialiser les entités en JSON
Terminé!
Mais vous aurez peut-être besoin de quelques ajustements. Par exemple -
la source
Lorsque vous devez créer de nombreux points de terminaison d'API REST sur Symfony, le meilleur moyen est d'utiliser la pile de bundles suivante:
Lorsque vous configurez tout correctement, votre code d'entité ressemblera à:
Ensuite, codez dans le contrôleur:
Les avantages d'une telle configuration sont:
la source
Désormais, vous pouvez également utiliser Doctrine ORM Transformations pour convertir des entités en tableaux imbriqués de scalaires et inversement.
la source