Bagaimana saya bisa mengirim respon JSON di kontroler symfony2

90

Saya menggunakan jQueryuntuk mengedit formulir saya yang sudah ada di dalamnya Symfony.

Saya menunjukkan formulir dalam jQuerydialog dan kemudian mengirimkannya.

Data dimasukkan dengan benar dalam database.

Tapi saya tidak tahu apakah saya perlu mengirim JSONkembali ke jQuery. Sebenarnya saya agak bingung dengan JSONhal itu.

Misalkan saya telah menambahkan baris di tabel saya dengan `` jQuery dan ketika saya mengirimkan formulir maka setelah data dikirimkan saya ingin mengirim kembali data baris tersebut sehingga saya dapat menambahkan baris tabel secara dinamis untuk menampilkan data yang ditambahkan.

Saya bingung bagaimana bisa mendapatkan data itu kembali.

Ini adalah kode saya saat ini:

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

Ini hanya template dengan pesan sukses.

Mirage
sumber

Jawaban:

187

Symfony 2.1

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

return $response;

Symfony 2.2 dan lebih tinggi

Anda memiliki kelas JsonResponse khusus , yang mengatur array ke JSON:

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

Tetapi jika masalah Anda adalah Bagaimana membuat serialisasi entitas maka Anda harus melihat JMSSerializerBundle

Dengan asumsi Anda telah menginstalnya, Anda hanya perlu melakukannya

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

return new Response($serializedEntity);

Anda juga harus memeriksa masalah serupa di StackOverflow:

Vitalii Zurian
sumber
1
Jadi bagaimana kita membuat serial entitas DAN mengirimkannya sebagai Respons JSON? Saya telah mencarinya selama seminggu .. stackoverflow.com/questions/14798532/…
George Katsanos
Anda juga dapat menggunakan symfony JsonResponse (Symfony \ Component \ HttpFoundation \ JsonResponse)
Kiddo
5
Lebih baik untuk mengatur header tipe konten mengembalikan Respon baru ($ serializedEntity, 200, array ('Content-Type' => 'application / json'));
Sergii Smirnov
Saran Sergii adalah yang terbaik (setidaknya untuk saya), jika saya tidak menyetel Jenis Konten, pada klien saya akan menerima jenis konten teks / html. Jika saya menggunakan JsonResponse, untuk beberapa alasan aneh saya mendapatkan satu string dengan konten di dalamnya
LuisF
56

Symfony 2.1 memiliki kelas JsonResponse .

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

Array yang diteruskan akan menjadi JSON yang dikodekan, kode status akan default ke 200 dan tipe konten akan disetel ke application / json.

Ada juga setCallbackfungsi praktis untuk JSONP.

omong kosong
sumber
16

Sejak Symfony 3.1 Anda dapat menggunakan 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());
}
Bettinz
sumber
10

Untuk melengkapi jawaban @thecatontheflat, saya akan merekomendasikan untuk juga membungkus tindakan Anda di dalam satu try … catchblok. Ini akan mencegah titik akhir JSON Anda melanggar pengecualian. Inilah kerangka yang saya gunakan:

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

    }
}

Dengan cara ini, titik akhir Anda akan berperilaku secara konsisten bahkan jika terjadi kesalahan dan Anda akan dapat menanganinya tepat di sisi klien.

Slava Fomin II
sumber
8

Jika data Anda sudah berseri:

a) mengirim tanggapan 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) mengirim tanggapan JSONP (dengan panggilan balik)

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

Jika data Anda perlu diserialkan:

c) mengirim tanggapan JSON

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

d) mengirim tanggapan JSONP (dengan panggilan balik)

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

e) menggunakan grup di Symfony 3.xx

Buat grup di dalam Entitas Anda

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

    // ...
}

Normalisasikan Objek Doktrin Anda di dalam logika aplikasi Anda

<?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;
Avram Cosmin
sumber