web-dev-qa-db-ja.com

symfonyのコントローラーからJSON配列を返します

Symfony 2のコントローラーからJSON応答を返そうとしています。フォームの例では、Spring MVCで@ResponseBodyアノテーションを使用してJSON応答を取得できます。私はJSON応答を取得したいのですが、JSON配列またはJsonオブジェクトの場合はmtterを取得しないで、それをビュー内の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));を試してみましたが、同じ結果が得られます。

これを行う必要があります(前の回答に基づく):

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が配列として返すすべてのクエリで完璧に機能します。

16
darkangelo

@darkangeloの回答には説明が必要だと思います。

findAll()メソッドは、オブジェクトのコレクションを返します。

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

応答を作成するには、次のようにエンティティのすべてのゲッターを応答に追加する必要があります。

_$arrayCollection = array();

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

return new JsonResponse($arrayCollection);
_

QueryBuilderを使用すると、すべてのプロパティを含む配列として結果を返すことができます。

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

return new JsonResponse($categorias);
_

getArrayResult()はゲッターの必要性を回避します。

20
chalasr

次のようにコードを変更する必要があります。

/**
 * @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

1

コレクションに応答しようとしているようです。そのためには、シリアライザーをセットアップする(またはデータを配列として取得する)必要があります。

このドキュメントページを見てください。 http://symfony.com/doc/current/components/http_foundation/introduction.html#creating-a-json-response

そして

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

1
Alex

私は次の解決策を提案します:

/**
     * @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);
}