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

85
demandé sur klipach 2012-07-30 07:03:19

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:

178
répondu Vitalii Zurian 2017-05-23 12:34:41

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.

55
répondu jmaloney 2012-12-11 17:34:39

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());
}
14
répondu Bettinz 2016-06-02 11:23:07

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.

9
répondu Slava Fomin II 2014-01-23 18:21:51

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;
7
répondu Avram Cosmin 2016-01-29 23:18:41