首页 文章

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

提问于
浏览
85

我正在使用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 回答

  • 179

    从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());
    }
    
  • 9

    Symfony 2.1有一个JsonResponse类 .

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

    传入的数组将采用JSON编码,状态代码默认为200,内容类型将设置为application / json .

    JSONP还有一个方便的 setCallback 功能 .

  • 55

    要完成@thecatontheflat的答案,我建议你也将你的动作包裹在 try ... catch 块中 . 这将阻止您的JSON endpoints 在异常中中断 . 这是我使用的骨架:

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

    这样,即使发生错误,您的 endpoints 也会始终如一地运行,并且您可以在客户端对其进行处理 .

  • 14

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

    但如果您的问题是 How to serialize entity 那么您应该看一下JMSSerializerBundle

    假设你安装了它,你就可以做到

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

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

  • 8

    如果您的数据已经序列化:

    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中使用组

    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;
    

相关问题