symfony2コントローラーでJSON応答を送信するにはどうすればよいですか?


90

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

これは成功メッセージを含むテンプレートです。

回答:


187

symfony 2.1

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

return $response;

symfony 2.2以降

配列をJSONにシリアル化する特別なJsonResponseクラスがあります。

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

しかし、問題がエンティティのシリアル化方法である場合は、JMSSerializerBundleを確認する必要があります

あなたがそれをインストールしていると仮定すると、あなたは単に行う必要があります

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

return new Response($serializedEntity);

StackOverflowでも同様の問題を確認する必要があります。


1
では、エンティティをシリアル化してJSON応答として送信するにはどうすればよいでしょうか。私は一週間のためにそのために検索してきた。.. stackoverflow.com/questions/14798532/...
ジョージKatsanos

symfony JsonResponse(Symfony \ Component \ HttpFoundation \ JsonResponse)を使用することもできます
キッド

5
content-typeヘッダーを設定することをお勧めしますnew Response($ serializedEntity、200、array( 'Content-Type' => 'application / json'));
Sergii Smirnov

Sergiiの提案は最高です(少なくとも私にとって)。Content-Typeを設定しない場合、クライアントでtext / html content-typeを受け取ります。JsonResponseを使用する場合、奇妙な理由により、コンテンツが含まれた単一の文字列を取得します
LuisF

56

symfony 2.1にはJsonResponseクラスがあります。

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

渡された配列はJSONエンコードされ、ステータスコードはデフォルトで200になり、コンテンツタイプはapplication / jsonに設定されます。

setCallbackJSONPには便利な関数もあります。



10

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

    }
}

このようにして、エンドポイントはエラーが発生した場合でも一貫して動作し、クライアント側で正しく処理することができます。


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.xxでグループを使用する

エンティティ内にグループを作成する

<?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;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.