Return 来自 Symfony 控制器的 JSON 数组

Return a JSON array from a Controller in Symfony

我正在尝试 return 来自 Symfony 2 中控制器的 JSON 响应。表单示例,在 Spring MVC 中,我可以使用 @ResponseBody 获得 JSON 响应注释。我想要一个 JSON 响应,不管它是 JSON 数组还是 Json 对象,然后在视图中用 javascript 操作它。

我试试下一个代码:

/**
     * @Route(
     *      "/drop/getCategory/",
     *      name="getCategory"
     * )
     * @Method("GET")
     */
    public function getAllCategoryAction() {
        $categorias = $this->getDoctrine()
                           ->getRepository('AppBundle:Categoria')
                           ->findAll();

        $response = new JsonResponse();
        $response->setData($categorias);

        $response->headers->set('Content-Type', 'application/json');
        return $response;
    }

但我在浏览器中得到 [{},{}] 作为响应。我也尝试使用 $response = new Response(json_encode($categorias));,但我得到了相同的结果。

您需要这样更改代码:

/**
 * @Route(
 *      "/drop/getCategory/",
 *      name="getCategory"
 * )
 * @Method("GET")
 */
public function getAllCategoryAction() {
    $categorias = $this->getDoctrine()
                       ->getRepository('AppBundle:Categoria')
                       ->findAll();

    $categorias = $this->get('serializer')->serialize($categorias, 'json');

    $response = new Response($categorias);

    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

如果serializer服务没有启用,您必须在app/config/config.yml中启用它:

    framework:
        # ...
        serializer:
            enabled: true

如需更高级的序列化选项,您可以安装JMSSerializerBundle

我建议以下解决方案:

/**
     * @Route(
     *      "/drop/getCategory/",
     *      name="getCategory"
     * )
     * @Method("GET")
     */
    public function getAllCategoryAction() {
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQuery(
            'SELECT c
            FROM AppBundle:Categoria c'
        );
        $categorias = $query->getArrayResult();


        return new Response(json_encode($categorias), 200);
}

您似乎正试图将一个集合放入响应中。为此,您需要设置序列化程序(或将数据检索为数组)。

查看此文档页面:http://symfony.com/doc/current/components/http_foundation/introduction.html#creating-a-json-response

http://symfony.com/doc/current/cookbook/serializer.html.

您需要这样做(根据之前的回答):

public function getAllCategoryAction() {
    $em = $this->getDoctrine()->getManager();
    $query = $em->createQuery(
        'SELECT c
        FROM AppBundle:Categoria c'
    );
    $categorias = $query->getArrayResult();

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

    return $response;
}

它适用于任何将 Doctrine returns 作为数组的查询。

我认为@darkangelo 的回答需要解释。

findAll()方法return对象集合。

$categorias = $this->getDoctrine()
                   ->getRepository('AppBundle:Categoria')
                   ->findAll();

要构建您的响应,您必须将实体的所有 getter 添加到您的响应中,例如:

$arrayCollection = array();

foreach($categorias as $item) {
     $arrayCollection[] = array(
         'id' => $item->getId(),
         // ... Same for each property you want
     );
}

return new JsonResponse($arrayCollection);

使用 QueryBuilder 允许您 return 结果作为包含所有属性的数组:

$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
    'SELECT c
    FROM AppBundle:Categoria c'
);
$categorias = $query->getArrayResult();

return new JsonResponse($categorias);

getArrayResult() 避免了吸气剂的需要。

遵循最佳实践,我设法按照以下方式进行:

public function index(CityRepository $cityRepository,
                      SerializerInterface $serializer): Response 

正在注入存储库和序列化程序。

$cities = $cityRepository->findAll();

正在检索对象数组。

$data = $serializer->serialize($cities, 'json');

正在将数据序列化为 JSON 字符串。

return new JsonResponse($data, 200, [], true);

将 JSON 字符串传递给 JsonResponse

/**
 * @Route("/api/list", name="list")
 */
public function getList(SerializerInterface $serializer, SomeRepository $repo): JsonResponse
{
    $models = $repo->findAll();
    $data = $serializer->serialize($models, JsonEncoder::FORMAT);
    return new JsonResponse($data, Response::HTTP_OK, [], true);
}