Wie kann ich eine JSON-Antwort in symfony2 controller senden?


90

Ich verwende jQuery, um mein eingebautes Formular zu bearbeiten Symfony.

Ich zeige das Formular im jQueryDialog und sende es dann ab.

Die Daten werden korrekt in die Datenbank eingegeben.

Aber ich weiß nicht, ob ich etwas JSONzurückschicken muss jQuery. Eigentlich bin ich etwas verwirrt JSON.

Angenommen, ich habe meiner Tabelle mit `` jQuery eine Zeile hinzugefügt. Wenn ich das Formular sende, möchte ich diese Zeilendaten nach dem Senden der Daten zurücksenden, damit ich die Tabellenzeile dynamisch hinzufügen kann, um die hinzugefügten Daten anzuzeigen.

Ich bin verwirrt, wie ich diese Daten zurückbekommen kann.

Dies ist mein aktueller Code:

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

Dies ist nur die Vorlage mit der Erfolgsmeldung.

Antworten:


187

Symfony 2.1

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

return $response;

Symfony 2.2 und höher

Sie haben eine spezielle JsonResponse- Klasse, die das Array in JSON serialisiert:

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

Wenn Ihr Problem jedoch darin besteht, wie eine Entität serialisiert wird, sollten Sie sich JMSSerializerBundle ansehen

Angenommen, Sie haben es installiert, müssen Sie es einfach tun

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

return new Response($serializedEntity);

Sie sollten auch in StackOverflow nach ähnlichen Problemen suchen:


1
Wie serialisieren wir die Entität UND senden sie als JSON-Antwort? Ich habe seit einer Woche danach gesucht
George Katsanos

Sie können auch symfony JsonResponse (Symfony \ Component \ HttpFoundation \ JsonResponse)
Kiddo

5
Es ist besser, den Header für den Inhaltstyp so festzulegen, dass eine neue Antwort zurückgegeben wird ($ serializedEntity, 200, array ('Content-Type' => 'application / json')).
Sergii Smirnov

Sergiis Vorschlag ist der beste (zumindest für mich). Wenn ich den Inhaltstyp nicht einstelle, erhalte ich auf dem Client einen Text- / HTML-Inhaltstyp. Wenn ich JsonResponse benutze, bekomme ich aus irgendeinem seltsamen Grund eine einzelne Zeichenfolge mit dem Inhalt darin
LuisF

56

Symfony 2.1 verfügt über eine JsonResponse- Klasse.

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

Das übergebene Array wird JSON-codiert, der Statuscode wird standardmäßig auf 200 gesetzt und der Inhaltstyp wird auf application / json festgelegt.

Es gibt auch eine praktische setCallbackFunktion für JSONP.



10

Um die Antwort von @thecatontheflat zu vervollständigen, würde ich empfehlen, Ihre Aktion auch in einen try … catchBlock zu packen . Dadurch wird verhindert, dass Ihr JSON-Endpunkt bei Ausnahmen beschädigt wird. Hier ist das Skelett, das ich benutze:

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(),
        ]);

    }
}

Auf diese Weise verhält sich Ihr Endpunkt auch bei Fehlern konsistent und Sie können sie direkt auf Client-Seite behandeln.


8

Wenn Ihre Daten bereits serialisiert sind:

a) Senden Sie eine JSON-Antwort

public function someAction()
{
    $response = new Response();
    $response->setContent(file_get_contents('path/to/file'));
    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

b) Senden Sie eine JSONP-Antwort (mit Rückruf)

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

Wenn Ihre Daten serialisiert werden müssen:

c) Senden Sie eine JSON-Antwort

public function someAction()
{
    $response = new JsonResponse();
    $response->setData([some array]);
    return $response;
}

d) Senden einer JSONP-Antwort (mit Rückruf)

public function someAction()
{
    $response = new JsonResponse();
    $response->setData([some array]);
    $response->setCallback('FUNCTION_CALLBACK_NAME');
    return $response;
}

e) Verwenden Sie Gruppen in Symfony 3.xx

Erstellen Sie Gruppen in Ihren Entitäten

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

    // ...
}

Normalisieren Sie Ihr Doctrine-Objekt innerhalb der Logik Ihrer Anwendung

<?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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.