Comment envoyer une réponse json dans le contrôleur symfony2
j'utilise jQuery pour éditer ma forme qui est construite en Symfony.
j'affiche le formulaire dans la boîte de dialogue jQuery et je le soumets.
les données sont entrées correctement dans la base de données.
mais je ne sais pas si j'ai besoin d'envoyer du JSON à jQuery. En fait, je suis un peu confuse avec le truc de JSON.
Suppose que j'ai ajouté une ligne dans ma table avec jQuery et quand je soumets le formulaire alors après les données est soumis je veux renvoyer ces données de ligne de sorte que je puisse ajouter dynamiquement la ligne de tableau pour montrer les données ajoutées.
Je ne comprends pas comment récupérer ces données
C'est mon code actuel
$editForm = $this->createForm(new StepsType(), $entity);
$request = $this->getRequest();
$editForm->bindRequest($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->render('::success.html.twig');
}
C'est juste le modèle avec le message de succès
5 réponses
Symfony 2.1
$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');
return $response;
Symfony 2.2 et plus
vous avez spécial JsonResponse classe, qui sérialise tableau à JSON:
return new JsonResponse(array('name' => $name));
mais si votre problème est comment sérialiser entité alors vous devriez avoir un oeil à JMSSerializerBundle
en supposant que vous l'avez installé, vous aurez tout simplement à faire
$serializedEntity = $this->container->get('serializer')->serialize($entity, 'json');
return new Response($serializedEntity);
vous devriez également vérifier pour des problèmes similaires sur StackOverflow:
Symfony 2.1 a une classe JsonResponse .
return new JsonResponse(array('name' => $name));
le contenu passé dans le tableau sera encodé JSON le code d'état sera par défaut à 200 et le type de contenu sera défini à application / json.
il y a aussi une fonction pratique setCallback
pour JSONP.
depuis Symfony 3.1, Vous pouvez utiliser JSON Helper http://symfony.com/doc/current/book/controller.html#json-helper
public function indexAction()
{
// returns '{"username":"jane.doe"}' and sets the proper Content-Type header
return $this->json(array('username' => 'jane.doe'));
// the shortcut defines three optional arguments
// return $this->json($data, $status = 200, $headers = array(), $context = array());
}
pour compléter la réponse @thecatontheflat je recommande d'envelopper également votre action à l'intérieur d'un bloc try ... catch
. Cela empêchera votre paramètre JSON de casser sur les exceptions. Voici le squelette que j'utilise:
public function someAction()
{
try {
// Your logic here...
return new JsonResponse([
'success' => true,
'data' => [] // Your data here
]);
} catch (\Exception $exception) {
return new JsonResponse([
'success' => false,
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
]);
}
}
de cette façon, votre paramètre se comportera de manière cohérente même en cas d'erreurs et vous serez en mesure de les traiter correctement du côté du client.
si vos données sont déjà sérialisées:
a) envoyer une réponse JSON
public function someAction()
{
$response = new Response();
$response->setContent(file_get_contents('path/to/file'));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
b) envoyer une réponse JSONP (avec rappel)
public function someAction()
{
$response = new Response();
$response->setContent('/**/FUNCTION_CALLBACK_NAME(' . file_get_contents('path/to/file') . ');');
$response->headers->set('Content-Type', 'text/javascript');
return $response;
}
si vos données doivent être sérialisées:
c) envoyer une réponse JSON
public function someAction()
{
$response = new JsonResponse();
$response->setData([some array]);
return $response;
}
d) envoyer une réponse JSONP (avec rappel)
public function someAction()
{
$response = new JsonResponse();
$response->setData([some array]);
$response->setCallback('FUNCTION_CALLBACK_NAME');
return $response;
}
e) utiliser des groupes dans Symfony 3.x.x
créer des groupes à l'intérieur de vos entités
<?php
namespace Mindlahus;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* Some Super Class Name
*
* @ORM able("table_name")
* @ORM\Entity(repositoryClass="SomeSuperClassNameRepository")
* @UniqueEntity(
* fields={"foo", "boo"},
* ignoreNull=false
* )
*/
class SomeSuperClassName
{
/**
* @Groups({"group1", "group2"})
*/
public $foo;
/**
* @Groups({"group1"})
*/
public $date;
/**
* @Groups({"group3"})
*/
public function getBar() // is* methods are also supported
{
return $this->bar;
}
// ...
}
normaliser votre objet de Doctrine dans la logique de votre application
<?php
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
// For annotations
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
...
$repository = $this->getDoctrine()->getRepository('Mindlahus:SomeSuperClassName');
$SomeSuperObject = $repository->findOneById($id);
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$encoder = new JsonEncoder();
$normalizer = new ObjectNormalizer($classMetadataFactory);
$callback = function ($dateTime) {
return $dateTime instanceof \DateTime
? $dateTime->format('m-d-Y')
: '';
};
$normalizer->setCallbacks(array('date' => $callback));
$serializer = new Serializer(array($normalizer), array($encoder));
$data = $serializer->normalize($SomeSuperObject, null, array('groups' => array('group1')));
$response = new Response();
$response->setContent($serializer->serialize($data, 'json'));
$response->headers->set('Content-Type', 'application/json');
return $response;