Как я могу отправить ответ json в контроллере symfony2
Я использую 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');
}
Это всего лишь шаблон с сообщением об успехе
5 answers
Симфония 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:
Symfony 2.1 имеет класс JsonResponse.
return new JsonResponse(array('name' => $name));
Переданный массив будет закодирован в формате JSON, код состояния по умолчанию будет равен 200, а тип контента будет установлен в application/json.
Существует также удобная функция setCallback
для JSONP.
Начиная с Symfony 3.1, вы можете использовать помощник JSON 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());
}
Чтобы завершить ответ @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(),
]);
}
}
Таким образом, ваша конечная точка будет вести себя стабильно даже в случае ошибок, и вы сможете обрабатывать их прямо на стороне клиента.
Если ваши данные уже сериализованы:
A) отправить ответ в формате JSON
public function someAction()
{
$response = new Response();
$response->setContent(file_get_contents('path/to/file'));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
Б) отправить ответ 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;
}
Если ваши данные необходимо сериализовать:
C) отправить ответ в формате 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;
}
E) использовать группы в Symfony 3.x.x
Создавайте группы внутри своих сущностей
<?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;