2012-07-30 27 views
81

Sto usando jQuery per modificare il mio modulo che è costruito in Symfony.Come posso inviare una risposta json nel controller symfony2

Sto visualizzando il modulo nella finestra di dialogo jQuery e quindi lo invio.

I dati sono inseriti correttamente nel database.

Ma non so se è necessario inviare un po 'di JSON a jQuery. In realtà sono un po 'confuso con la cosa JSON.

Supponiamo di aver aggiunto una riga nella mia tabella con jQuery e quando invio il modulo, quindi dopo che i dati sono stati inviati, voglio restituire quei dati di riga in modo da poter aggiungere dinamicamente la riga della tabella per mostrare i dati aggiunti.

Sono confuso come può ottenere che i dati indietro

Questo è il mio codice corrente

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

Questo è solo il modello con il messaggio di successo

risposta

167

Symfony 2,1

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

return $response; 

Symfony 2.2 e superiori

Hai classe speciale JsonResponse, che serialises array JSON:

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

Ma se il tuo problema è come serializzare entità allora si dovrebbe avere un'occhiata a JMSSerializerBundle

Supponendo di averlo installato, avrai sim ply fare

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

return new Response($serializedEntity); 

Si dovrebbe anche verificare la presenza di problemi simili su StackOverflow:

+1

Quindi, come possiamo serializzare entità e inviarlo come una risposta JSON? L'ho cercato per una settimana .. http://stackoverflow.com/questions/14798532/symfony2-json-response-returns-weird-utf-characters –

+0

Puoi anche usare symfony JsonResponse (Symfony \ Component \ HttpFoundation \ JsonResponse) – Kiddo

+0

@Kiddo - c'è già un collegamento al doc nella risposta;) –

53

Symfony 2.1 ha una classe JsonResponse.

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

La passata matrice sarà JSON codificato il codice di stato imposterà 200 e il tipo di contenuto sarà impostato su application/json.

C'è anche una comoda funzione setCallback per JSONP.

9

Per completare @thecatinquesta risposta si consiglia di includere l'azione all'interno di un blocco try ... catch. Ciò impedirà l'interruzione dell'eccezione dell'endpoint JSON alle eccezioni.Ecco lo scheletro che uso:

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

    } 
} 

In questo modo il punto finale si comporterà in modo coerente, anche in caso di errori e si sarà in grado di trattare nel modo giusto su un lato client.

7

Se i dati sono già serializzato:

a) inviare una risposta 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) inviare una risposta JSONP (con callback)

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

Se le vostre esigenze di dati siano serializzato:

c) inviare una risposta JSON

public function someAction() 
{ 
    $response = new JsonResponse(); 
    $response->setData([some array]); 
    return $response; 
} 

d) inviare una risposta JSONP (con callback)

public function someAction() 
{ 
    $response = new JsonResponse(); 
    $response->setData([some array]); 
    $response->setCallback('FUNCTION_CALLBACK_NAME'); 
    return $response; 
} 

e) utilizzare i gruppi in Symfony 3.xx

Crea gruppi all'interno della vostra Entità

<?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; 
    } 

    // ... 
} 

Normalizza il tuo oggetto Doctrine nella logica della tua applicazione

<?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; 
12

Dal Symfony 3.1 è possibile utilizzare 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()); 
} 
Problemi correlati