web-dev-qa-db-fra.com

Comment puis-je envoyer une réponse json dans le contrôleur symfony2

J'utilise jQuery pour éditer mon formulaire qui est construit dans Symfony.

Je montre le formulaire dans la boîte de dialogue jQuery, puis je le soumets.

Les données entrent correctement dans la base de données.

Mais je ne sais pas si je dois renvoyer du JSON à jQuery. En fait, je suis un peu confus avec JSON.

Supposons que j’ai ajouté une ligne dans ma table avec jQuery et lorsque je soumets le formulaire, une fois les données soumises, je souhaite renvoyer ces données afin que je puisse ajouter de manière dynamique la ligne de la table pour afficher les données ajoutées.

Je suis confus, comment récupérer ces données

Ceci 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');               
}

Ceci est juste le modèle avec le message de réussite

87
user825904

Symfony 2.1

$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');

return $response;

Symfony 2.2 et supérieur

Vous avez la classe spéciale JsonResponse , qui sérialise un tableau en JSON:

return new JsonResponse(array('name' => $name));

Mais si votre problème est Comment sérialiser une entité , alors vous devriez jeter un œil à JMSSerializerBundle

En supposant que vous l'avez installé, vous devrez simplement faire

$serializedEntity = $this->container->get('serializer')->serialize($entity, 'json');

return new Response($serializedEntity);

Vous devriez également rechercher des problèmes similaires sur StackOverflow:

186
Vitalii Zurian

Symfony 2.1 a une classe JsonResponse .

return new JsonResponse(array('name' => $name));

Le tableau transmis sera codé en JSON, le code de statut par défaut sera 200 et le type de contenu sera défini sur application/json.

Il existe également une fonction pratique setCallback pour JSONP.

55
jmaloney

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());
}
15
Bettinz

Pour compléter la réponse @thecatontheflat, je recommanderais également de placer votre action dans un bloc try ... catch. Cela empêchera votre point de terminaison JSON de casser des 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 point de terminaison se comportera de manière cohérente, même en cas d'erreur, et vous pourrez les traiter directement du côté client.

9
Slava Fomin II

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 dans 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;
    }

    // ...
}

Normalisez votre Doctrine Objet 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;
8
Avram Cosmin