Symfony2 denetleyicide JSON yanıtını nasıl gönderebilirim


90

Yerleşik formumu jQuerydüzenlemek için kullanıyorum Symfony.

Formu jQueryiletişim kutusunda gösteriyorum ve gönderiyorum.

Veri, veri tabanına doğru giriyor.

Ama JSONgeri göndermem gerekip gerekmediğini bilmiyorum jQuery. Aslında biraz kafam karıştı JSON.

Tabloma `` jQuery '' ile bir satır eklediğimi ve formu gönderdikten sonra veriler gönderildikten sonra bu satır verilerini geri göndermek istiyorum, böylece eklenen verileri göstermek için tablo satırını dinamik olarak ekleyebiliyorum.

Bu verileri nasıl geri alabileceğim konusunda kafam karıştı.

Bu benim şu anki kodum:

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

Bu sadece başarı mesajı içeren şablondur.

Yanıtlar:


187

Symfony 2.1

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

return $response;

Symfony 2.2 ve üstü

Diziyi JSON'a serileştiren özel JsonResponse sınıfınız var :

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

Ancak sorununuz nasıl varlık seri hale getirilirse , JMSSerializerBundle'a bir göz atmalısınız.

Yüklemiş olduğunuzu varsayarsak, yapmanız gereken

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

return new Response($serializedEntity);

StackOverflow'da da benzer sorunları kontrol etmelisiniz:


1
Peki varlığı nasıl seri hale getirip JSON Yanıtı olarak gönderebiliriz? Bunu bir haftadır arıyordum .. stackoverflow.com/questions/14798532/…
George Katsanos

Ayrıca symfony JsonResponse'yi de kullanabilirsiniz (Symfony \ Component \ HttpFoundation \ JsonResponse)
Kiddo

5
Yeni Yanıtı döndüren içerik türü başlığını ayarlamak daha iyidir ($ serializedEntity, 200, array ('Content-Type' => 'application / json'));
Sergii Smirnov

Sergii'nin önerisi en iyisidir (en azından benim için), eğer Content-Type'ı ayarlamazsam, istemcide bir text / html içerik-tipi alacağım. JsonResponse kullanırsam, tuhaf bir nedenden ötürü içeriğin bulunduğu tek bir dize elde ederim
LuisF

56

Symfony 2.1, JsonResponse sınıfına sahiptir.

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

Aktarılan dizide JSON kodlanmış olacak, durum kodu varsayılan olarak 200 olacak ve içerik türü application / json olarak ayarlanacaktır.

setCallbackJSONP için kullanışlı bir işlev de vardır.


16

Symfony 3.1'den beri JSON Helper'ı kullanabilirsiniz 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());
}

10

@Thecatontheflat cevabını tamamlamak için eyleminizi bir try … catchbloğun içine de yerleştirmenizi tavsiye ederim . Bu, JSON uç noktanızın istisnaları ihlal etmesini önleyecektir. İşte kullandığım iskelet:

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

    }
}

Bu şekilde, uç noktanız hata durumunda bile tutarlı davranacak ve bunları doğrudan bir istemci tarafında ele alabileceksiniz.


8

Verileriniz zaten serileştirilmişse:

a) JSON yanıtı gönder

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

b) bir JSONP yanıtı gönderin (geri arama ile)

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

Verilerinizin serileştirilmesi gerekiyorsa:

c) JSON yanıtı gönder

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

d) bir JSONP yanıtı gönderin (geri arama ile)

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

e) Symfony 3.xx'deki grupları kullanın

Varlıklarınız içinde gruplar oluşturun

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

    // ...
}

Doktrin Nesnenizi uygulamanızın mantığı içinde normalleştirin

<?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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.