如何在 symfony2控制器中发送 JSON 响应

我使用 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');
}

这只是带有成功消息的模板。

187233 次浏览

Symfony 2.1

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


return $response;

Symfony 2.2 and higher

You have special JsonResponse class, which serialises array to JSON:

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

But if your problem is How to serialize entity then you should have a look at JMSSerializerBundle

Assuming that you have it installed, you'll have simply to do

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


return new Response($serializedEntity);

You should also check for similar problems on StackOverflow:

Symfony 2.1 has a JsonResponse class.

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

The passed in array will be JSON encoded the status code will default to 200 and the content type will be set to application/json.

There is also a handy setCallback function for JSONP.

To complete @thecatontheflat answer I would recommend to also wrap your action inside of a try … catch block. This will prevent your JSON endpoint from breaking on exceptions. Here's the skeleton I use:

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


}
}

This way your endpoint will behave consistently even in case of errors and you will be able to treat them right on a client side.

If your data is already serialized:

a) send a JSON response

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

b) send a JSONP response (with callback)

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

If your data needs be serialized:

c) send a JSON response

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

d) send a JSONP response (with callback)

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

e) use groups in Symfony 3.x.x

Create groups inside your Entities

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


// ...
}

Normalize your Doctrine Object inside the logic of your application

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

Since Symfony 3.1 you can use 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());
}

If you are using symfony 5 propably it will works.

$data = $serializer->serialize(array('key' => 'value'), JsonEncoder::FORMAT);


return new JsonResponse($data, Response::HTTP_OK, [], true);