如何在 symfony2 控制器中发送 JSON 响应
Posted
技术标签:
【中文标题】如何在 symfony2 控制器中发送 JSON 响应【英文标题】:How can I send JSON response in symfony2 controller 【发布时间】:2012-07-27 17:36:47 【问题描述】:我正在使用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');
这只是带有成功消息的模板。
【问题讨论】:
【参考方案1】:要完成@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(),
]);
这样,即使出现错误,您的端点也会保持一致的行为,并且您将能够在客户端正确处理它们。
【讨论】:
【参考方案2】:从 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());
【讨论】:
【参考方案3】:如果您的数据已经序列化:
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;
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;
如果你的数据需要序列化:
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;
// ...
在应用程序逻辑中规范化 Doctrine 对象
<?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;
【讨论】:
【参考方案4】: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);
您还应该检查 *** 上的类似问题:
How to encode Doctrine entities to JSON in Symfony 2.0 AJAX application? Symfony 2 Doctrine export to JSON【讨论】:
那么我们如何序列化实体并将其作为 JSON 响应发送?我一直在寻找一个星期.. ***.com/questions/14798532/… 你也可以使用 symfony JsonResponse (Symfony\Component\HttpFoundation\JsonResponse) 最好设置content-type header return new Response($serializedEntity, 200, array('Content-Type' => 'application/json')); Sergii 的建议是最好的(至少对我而言),如果我不设置 Content-Type,在客户端我会收到一个 text/html 内容类型。如果我使用 JsonResponse,出于某种奇怪的原因,我会得到一个包含内容的单个字符串【参考方案5】:Symfony 2.1 有一个JsonResponse 类。
return new JsonResponse(array('name' => $name));
传入的数组将被 JSON 编码,状态码默认为 200,内容类型将设置为 application/json。
还有一个方便的 setCallback
函数用于 JSONP。
【讨论】:
以上是关于如何在 symfony2 控制器中发送 JSON 响应的主要内容,如果未能解决你的问题,请参考以下文章
json_encode 在我的 Symfony2 控制器中不起作用