Vue au format JSON sous Symfony
Contrairement à ce que son nom indique, l'AJAX utilise de plus en plus le format JSON pour échanger des données entre le navigateur et le serveur. Le framework PHP Symfony se déclare "Easy AJAX", il l'est pour l'intégration de JavaScript, mais la création de vues non-HTML n'est pas toujours évidente. Cet article propose deux méthodes pour générer du code JSON depuis Symfony avec ou sans aide au débuggage.
Les usages sont multiples, par exemple :
- Auto-complétion d'un champ avec le plugin sfFormExtraPlugin,
- les événements issus de la base de données à afficher dans un calendrier FullCalendar,
- ou une galerie photos AJAX avec minishowcase.
1. JSON simplement mais sans débuggage
Le plus simple pour envoyer du code JSON depuis Symfony est d'inclure les lignes suivantes à la fin du contrôleur :
function executeAction() {
$data = array();
// ... Création du tableau $data ...
// Indispensable : définie le l'en-tête HTTP correspondant au format JSON.
$this->getResponse()->setHttpHeader('Content-type', 'application/json');
// Contenu transmis.
$this->getResponse()->setContent(json_encode($data));
// N'affiche aucune vue.
return return sfView::NONE;
}
Simple à mettre en œuvre, cette méthode peut poser problème pour le débuggage de l'application.
- Le contenu JSON transmis n'est pas visualisable dans le navigateur à cause du content-type non reconnu.
- Si l'on laisse le content-type par défaut, le texte JSON transmis est parasité par la debug toolbar.
2. JSON avec débuggage
Pour rendre visible le format JSON au développeur, il faut adapter la réponse au contexte d'exécution de la page. Les données ne doivent être affichées lisiblement que lorsque le développeur affiche la page en mode débug, mais pas lorsqu'elle est appelée depuis JavaScript, même en mode débug. Pour cela, la méthode sfWebRequest::isXmlHttpRequest() est bien pratique.
Un petit aperçu du rendu dans le navigateur en mode débug, lorsque la page est appelée directement depuis la barre d'adresse du navigateur.
1/3 Créez le composant JSON. Fichier app/app_name/modules/module_name/actions/jsonComponent.class.php
class jsonComponent extends sfComponent
{
function execute($request)
{
if (sfConfig::get('sf_debug') && !$this->getRequest()->isXmlHttpRequest())
{
$this->setVar('data', $this->data);
}
else
{
$this->getResponse()->setHttpHeader('Content-type', 'application/json');
$this->getResponse()->setContent(json_encode($this->data));
return sfView::NONE;
}
}
}
2/3 Créez ensuite la vue associée. Fichier app/app_name/modules/module_name/templates/_json.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>JSON response</title></head>
<body>
<h2>JSON</h2>
<?php echo json_encode($sf_data->getRaw('data')); ?>
<h2>Data structure</h2>
<pre><?php print_r($sf_data->getRaw('data')); ?></pre>
</body>
</html>
3/3 Enfin appelez le composant depuis votre contrôleur. Fichier app/app_name/modules/module_name/actions/actions.class.php
function executeAction() {
$data = array();
// ... Création du tableau $data ...
// Transmet la responsabilité de l'affichage au composant JSON
return $this->renderComponent('module_name', 'json', array('data'=>$data));
}
Le composant peut être créé dans un module spécifique et appelé depuis un autre module.
Reste plus qu'à en faire un plugin ...
Deux articles pour aller plus loin :
Aucun trackbacks pour l'instant

5 janvier 2010 - 09:41
Salut, tout d’abord merci pour ce post et bon courage pour ton blog tout frais.
A tu un compte twitter depuis lequel on puisse être tenu au courant de tes nouvelles publications ?
A.
5 janvier 2010 - 09:53
Merci Amo,
Je n’ai pas encore de compte Twitter mais je vais voir comment relayer mes articles par ce canal. Il y a toujours les flux RSS sinon.
30 mars 2010 - 01:00
Ahhh enfin ! Je cherchais depuis des heures comment générer du contenu JSON à partir de symfony.