【问题标题】:How can I send JSON response in symfony2 controller如何在 symfony2 控制器中发送 JSON 响应
【发布时间】: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');               
}

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

【问题讨论】:

    标签: php javascript json symfony


    【解决方案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);
          

          您还应该检查 StackOverflow 上的类似问题:

          【讨论】:

          • 那么我们如何序列化实体并将其作为 JSON 响应发送?我一直在寻找一个星期.. stackoverflow.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。

          【讨论】:

            猜你喜欢
            • 2015-10-19
            • 1970-01-01
            • 2014-09-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多