Як я можу надіслати відповідь JSON у контролері symfony2


90

Я використовую jQueryдля редагування моєї вбудованої форми Symfony.

Я показую форму у jQueryдіалоговому вікні, а потім надсилаю її.

Дані правильно вводяться в базу даних.

Але я не знаю, чи потрібно мені надсилати їх JSONназад jQuery. Насправді я трохи плутаюся з цим JSON.

Припустимо, я додав у свою таблицю рядок з `` jQuery, і коли я подаю форму, то після надсилання даних я хочу відправити назад ці дані рядка, щоб я міг динамічно додати рядок таблиці, щоб показати додані дані.

Мене бентежить, як можна повернути ці дані назад.

Це мій поточний код:

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

Це лише шаблон із повідомленням про успіх.

Відповіді:


187

Symfony 2.1

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

return $response;

Symfony 2.2 і вище

У вас є спеціальний клас JsonResponse , який серіалізує масив до JSON:

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

Але якщо ваша проблема полягає в тому, як серіалізувати сутність, тоді вам слід поглянути на JMSSerializerBundle

Якщо припустити, що у вас він встановлений, вам доведеться просто це зробити

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

return new Response($serializedEntity);

Вам також слід перевірити наявність подібних проблем на StackOverflow:


1
То як ми серіалізуємо сутність І надсилаємо її як відповідь JSON? Я шукав , що в протягом тижня .. stackoverflow.com/questions/14798532 / ...
Джордж Katsanos

Ви також можете використовувати symfony JsonResponse (Symfony \ Component \ HttpFoundation \ JsonResponse)
Kiddo

5
Краще встановити заголовок типу вмісту return new Response ($ serializedEntity, 200, array ('Content-Type' => 'application / json'));
Сергій Смірнов

Пропозиція Сергія найкраща (принаймні для мене), якщо я не встановлю Content-Type, на клієнті я отримаю text / html content-type. Якщо я використовую JsonResponse, з якихось дивних причин я отримую один рядок із вмістом всередині
LuisF

56

Symfony 2.1 має клас JsonResponse .

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

Переданий масив буде закодований у форматі JSON, код стану за замовчуванням буде 200, а тип вмісту встановлений у application / json.

Також є зручна setCallbackфункція для JSONP.


16

З Symfony 3.1 ви можете використовувати 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());
}

10

Щоб завершити відповідь @thecatontheflat, я б рекомендував також обернути свою дію всередині try … catchблоку. Це не дозволить вашій кінцевій точці JSON порушити винятки. Ось скелет, який я використовую:

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

    }
}

Таким чином ваша кінцева точка буде поводитися послідовно, навіть у разі помилок, і ви зможете лікувати їх прямо на стороні клієнта.


8

Якщо ваші дані вже серіалізовані:

а) надішліть відповідь 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) надіслати відповідь JSONP (із зворотним викликом)

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

Якщо ваші дані потрібно серіалізувати:

в) надіслати відповідь JSON

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

d) надіслати відповідь JSONP (із зворотним викликом)

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

д) використовувати групи в Symfony 3.xx

Створіть групи всередині своїх сутностей

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

    // ...
}

Нормалізуйте свій об’єкт доктрини всередині логіки вашої програми

<?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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.