ฉันจะส่งการตอบสนอง JSON ในคอนโทรลเลอร์ symfony2 ได้อย่างไร


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

นี่เป็นเพียงเทมเพลตที่มีข้อความแสดงความสำเร็จ

คำตอบ:


188

Symfony 2.1.0

$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:


1
แล้วเราจะทำให้เป็นอนุกรมเอนทิตีและส่งเป็น JSON Response ได้อย่างไร? ฉันค้นหาสิ่งนั้นมาหนึ่งสัปดาห์แล้ว .. stackoverflow.com/questions/14798532/…
George Katsanos

คุณยังสามารถใช้ symfony JsonResponse (Symfony \ Component \ HttpFoundation \ JsonResponse)
Kiddo

5
เป็นการดีกว่าที่จะตั้งค่าส่วนหัวประเภทเนื้อหาที่ส่งคืน Response ใหม่ ($ serializedEntity, 200, array ('Content-Type' => 'application / json'));
Serhii Smirnov

ข้อเสนอแนะของ Sergii ดีที่สุด (อย่างน้อยสำหรับฉัน) ถ้าฉันไม่ได้ตั้งค่า Content-Type บนไคลเอนต์ฉันจะได้รับประเภทเนื้อหาข้อความ / html ถ้าฉันใช้ JsonResponse ด้วยเหตุผลแปลก ๆ ฉันจะได้สตริงเดี่ยวที่มีเนื้อหาอยู่ข้างใน
LuisF

56

Symfony 2.1 มีคลาสJsonResponse

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

อาร์เรย์ที่ส่งผ่านจะเข้ารหัส JSON รหัสสถานะจะเริ่มต้นเป็น 200 และประเภทเนื้อหาจะถูกตั้งค่าเป็น application / json

นอกจากนี้ยังมีsetCallbackฟังก์ชันที่มีประโยชน์สำหรับ JSONP



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

หากข้อมูลของคุณเป็นซีเรียลแล้ว:

ก) ส่งการตอบกลับ 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;
}

จ) ใช้กลุ่มใน 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;
    }

    // ...
}

ทำให้วัตถุหลักคำสอนของคุณเป็นปกติภายในตรรกะของแอปพลิเคชันของคุณ

<?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.