Documentation officielle du framework PHP Symfony 3 - Partie 4

Partie 4 : Apprendre à créer des pages Web avec Symfony 3

Symfony

Traducteur

Christophe LOUVET

Il s'agit de la traduction française de la documentation officielle du framework PHP Symfony 3. Vous allez apprendre à programmer avec ce puissant framework, de plus en plus utilisé pour construire des applications d'envergure.

Dans cette quatrième partie, vous allez apprendre à créer et à gérer vos pages Web avec Symfony 3.

Un espace de dialogue vous est proposé sur le forum si vous avez des remarques sur ce tutoriel.

Commentez

- Titre : Documentation officielle du framework PHP Symfony 3 - Partie 4

- Auteur : Symfony

- Traducteur : Christophe LOUVET

- Parution : 4 octobre 2016

- Public visé :

- Licence : Le contenu de cet article est rédigé par symphony.com et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2013 Developpez.com.

Voir également :

- La troisième partie : Apprendre à installer et à configurer Symfony 3

- La cinquième partie : Apprendre le paramétrage des contrôleurs dans Symfony

- Voir les autres parties

Sommaire

- 1. Introduction

- 2. Créer une page : route et contrôleur

- 2-1. Présentation globale

- 2-2. Créer une réponse JSON

- 3. Modèle d'URL dynamique : /numero/magique/{compteur}

- 4. Outil de débogage : Web Debug Toolbar

- 5. Rendu d'un template (avec le Service Container)

- 5-1. Utiliser le service de Templating

- 5-2. Créer le Template

- 6. Explorer la structure du projet

- 7. Bundles et Configuration

- 8. Et ensuite ?

- Notes de la rédaction Developpez.com

1 - Introduction

Créer une nouvelle page, qu'elle soit une page HTML ou un point final JSON, est une opération simple en deux étapes :

1. Créer une route : une route est l'URL (ex : /a-propos) pour votre page et pointe sur un contrôleur ;

2. Créer un contrôleur : un contrôleur est une fonction PHP que vous écrivez pour construire votre page. Vous prenez les requêtes d'information entrantes et les utilisez pour créer un objet Symfony, lequel va prendre en charge le contenu HTML, une chaîne JSON ou autre.

Tout comme sur le Web, chaque interaction est initiée par une requête HTTP. Votre travail est simple : comprendre une requête et retourner une réponse.

Symfony suit la logique du cycle de vie HTTP : Requête - Réponse. Pour en savoir plus, allez sur la première partie : Symfony et les fondamentaux HTTP.

2 - Créer une page : route et contrôleur

Avant de continuer, assurez-vous d'avoir bien lu la troisième partie l'installation et la configuration et d'avoir réussi à accéder à votre nouvelle application Symfony depuis le navigateur.

2-1 - Présentation globale

Supposons que vous voulez créer une page /numero/magique, qui génère un numéro magique (au hasard) et l'imprime. Pour effectuer cela, créez une « classe contrôleur » et une méthode « contrôleur » dans celle-ci qui sera exécutée quand quelqu'un lancera la page /numero/magique :

1. // src/AppBundle/Controller/MagiqueController.php

2. namespace AppBundle\Controller;

4. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

5. use Symfony\Component\HttpFoundation\Response;

7. class MagiqueController

8. {

9. /**

10. * @Route("/numero/magique")

11. */

12. public function numeroAction()

13. {

14. $numero = mt_rand(0, 100);

16. return new Response(

17. '<html><body>Numero magique : '.$numero.'</body></html>'

18. );

19. }

20. }

Avant d'aller en profondeur dans la compréhension de ce code, testez-le ! Si vous utilisez le serveur Web interne de PHP, tapez dans votre navigateur, l'URL suivante :

1. http://localhost:8000/app_dev.php/numero/magique

Si vous configurez un VirtualHost dans Apache ou Nginx, remplacez http://localhost:8000 par votre nom d'hôte comme par exemple http://symfony.dev/app_dev.php/numero/magique.

Si vous utilisez le serveur Web intégré dans la nouvelle version de PHP, vous pouvez enlever la partie app_dev.php.

Si vous voyez un numero magique apparaître, félicitations ! Mais avant de lancer une loterie, regardons comment ce code fonctionne. Vous souvenez-vous des deux étapes pour créer une page ?

1. Créer la route. L'élément @Route au-dessus de numeroAction(), c'est la route : elle est une annotation et définit le modèle d'URL. Vous pouvez aussi écrire les routes en YAML (ou en d'autres formats). Pour plus de détails, voir le chapitre sur le routage.

2. Créer le contrôleur. La méthode en dessous de la route - numeroAction - est appelée le contrôleur. C'est une fonction où vous créez la page qui va retourner un objet Response. La seule règle est que le contrôleur doit retourner un objet Response Symfony. Pour plus de détails, voir le chapitre sur les contrôleurs.

2-2 - Créer une réponse JSON

L'objet Response que vous retournez à votre contrôleur peut contenir du HTML, du JSON, ou encore un fichier binaire comme une image ou un PDF. Vous pouvez facilement fixer des headers HTTP ou le code de statut.

Supposez que vous voulez créer un point final JSON qui retourne le numero magique, ajoutez juste une seconde méthode au MagiqueController :

1. // src/AppBundle/Controller/MagiqueController.php

3. // ...

4. class MagiqueController

5. {

6. // ...

8. /**

9. * @Route("/api/numero/magique")

10. */

11. public function apiNumeroAction()

12. {

13. $data = array(

14. 'numero_magique' => rand(0, 100),

15. );

17. return new Response(

18. json_encode($data),

19. 200,

20. array('Content-Type' => 'application/json')

21. );

22. }

23. }

Essayez cela dans votre navigateur :

1. http://localhost:8000/app_dev.php/api/numero/magique

Vous pouvez encore raccourcir cela avec le pratique JsonResponse :

1. // src/AppBundle/Controller/MagiqueController.php

3. // ...

4. // --> ne pas oublier ce nouvel énoncé de l'utilisation

5. use Symfony\Component\HttpFoundation\JsonResponse;

7. class MagiqueController

8. {

9. // ...

11. /**

12. * @Route("/api/numero/magique")

13. */

14. public function apiNumeroAction()

15. {

16. $data = array(

17. 'numero_magique' => rand(0, 100),

18. );

20. // appele l'encodeur json fixe le header Content-Type

21. return new JsonResponse($data);

22. }

23. }

3 - Modèle d'URL dynamique : /numero/magique/{compteur}

Le routage Symfony peut faire encore plus de choses. Supposez que vous voulez maintenant qu'un utilisateur puisse aller à la page /numero/magique/5 pour générer un numéro magique immédiatement. Mettez à jour la route pour avoir une partie {joker}, à la fin.

Annotation :

1. // src/AppBundle/Controller/MagiqueController.php

3. // ...

4. class MagiqueController

5. {

6. /**

7. * @Route("/numero/magique/{count}")

8. */

9. public function numeroAction()

10. {

11. // ...

12. }

14. // ...

15. }

YAML :

1. # app/config/routing.yml

2. numero_magique:

3. path:     /numero/magique/{count}

4. defaults: { _controller: AppBundle:Magique:Numero }

XML :

1. <!-- app/config/routing.xml -->

2. <?xml version="1.0" encoding="UTF-8" ?>

3. <routes xmlns="http://symfony.com/schema/routing"

4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

5. xsi:schemaLocation="http://symfony.com/schema/routing

6. http://symfony.com/schema/routing/routing-1.0.xsd">

8. <route id="numero_magique" path="/numero/magique/{count}">

9. <default key="_controller">AppBundle:numero:magique</default>

10. </route>

11. </routes>

PHP :

1. // app/config/routing.php

2. use Symfony\Component\Routing\RouteCollection;

3. use Symfony\Component\Routing\Route;

5. $collection = new RouteCollection();

6. $collection->add('numero magique', new Route('/numero/magique/{count}', array(

7. '_controller' => 'AppBundle:Nombre:Magique',

8. )));

10. return $collection;

À cause de « l'espace réservé » {compteur}, l'URL de la page est différente et fonctionne maintenant pour l'URL correspondant à /numero/magique/*, par exemple : /numero/magique/. La meilleure partie est que vous pouvez accéder à la valeur et l'utiliser dans votre contrôleur :

1. // src/AppBundle/Controller/MagiqueController.php

2. // ...

4. class MagiqueController

5. {

7. /**

8. * @Route("/numero/magique/{count}")

9. */

10. public function numeroAction($count)

11. {

12. $numeros = array();

13. for ($i = 0; $i < $count; $i++) {

14. $numeros[] = rand(0, 100);

15. }

16. $listeNumeros = implode(', ', $numeros);

18. return new Response(

19. '<html><body>Numeros magiques: '.$listeNumeros.'</body></html>'

20. );

21. }

23. // ...

24. }

Essayez ceci pour aller à l'adresse /numero/magique/XX en remplaçant XX avec n'importe quel numero :

1. http://localhost:8000/app_dev.php/numero//7

Le système de routage peut faire encore plus, comme supporter les multiples espaces réservés (ex : /blog/{catégorie}/{page}), rendant les espaces réservés optionnels ou obligatoires pour correspondre à une expression régulière (ex. : {compteur} doit être un numero).

4 - Outil de débogage : Web Debug Toolbar

Si votre page fonctionne, alors vous pourrez voir une nouvelle barre de menus au milieu de votre navigateur. Cette barre s'appelle le Web Debug Toolbar et c'est votre meilleure amie pour faire le débogage. Vous en aurez davantage sur cet outil en survolant les différents boutons : soyez libres de faire votre propre expérience. N'hésitez pas à parcourir les différentes icônes relatives au routage, à la performance, à la journalisation et bien plus encore.

5 - Rendu d'un template (avec le Service Container)

Si vous retournez du HTML depuis votre contrôleur, vous allez probablement vouloir interpréter un template. Heureusement, Symfony est fourni avec Twig : un langage de template qui est facile, puissant, et assez amusant.

Premièrement, assurez-vous que MagiqueController n'étend que la classe de base Controller. Le plus simple moyen d'utiliser Twig, ou n'importe quel autre outil de Symfony, est d'étendre la classe Symfony de base Controller :

1. // src/AppBundle/Controller/MagiqueController.php

3. // ...

4. // --> ajoutez cette nouvelle déclaration use

5. use Symfony\Bundle\FrameworkBundle\Controller\Controller;

7. class MagiqueController extends Controller

8. {

9. // ...

10. }

Maintenant, utiliser la fonction pratique render() pour obtenir le rendu du template. Passez-lui la variable de notre numéro, on peut donc avoir le rendu comme suit :

1. // src/AppBundle/Controller/MagiqueController.php

3. // ...

4. class MagiqueController extends Controller

5. {

6. /**

7. * @Route("/numero/magique")

8. */

9. public function numeroAction()

10. {

11. $numero = mt_rand(0, 100);

13. return $this->render('magique/numero.html.twig', array(

14. 'numero' => $numero,

15. ));

16. }

17. }

Et enfin, sachez que les fichiers de template sont localisés dans le répertoire app/Resources/view. Créez un nouveau répertoire app/Resources/views/magique avec un nouveau fichier numero.html.twig à l'intérieur :

1. {# app/Resources/views/magique/numero.html.twig #}

3. <h1>Votre numero magique est {{ numero }}</h1>

La syntaxe {{ numero }} est utilisée pour représenter les variables dans Twig. Actualisez votre page pour obtenir un nouveau numéro magique !

1. http://localhost:8000/magique/numero

5-1 - Utiliser le service de Templating

Cela ne change rien, mais vous donne accès au conteneur Symfony, un objet comme un tableau qui vous donne accès à tout objet utile du système. Ces objets utiles sont appelés services, et Symfony navigue avec un objet service qui peut interpréter des templates Twig, un autre qui peut logger les messages et pleins d'autres.

Pour interpréter un template Twig, utilisez un service nommé templating :

1. // src/AppBundle/Controller/MagiqueController.php

3. // ...

4. class MagiqueController extends Controller

5. {

6. /**

7. * @Route("/numero/magique/{count}")

8. */

9. public function numeroAction($count)

10. {

11. // ...

12. $listeNumeros = implode(', ', $numeros);

14. $html = $this->container->get('templating')->render(

15. 'magique/numero.html.twig',

16. array('listeNumerosMagiques' => $listeNumeros

17. );

19. return new Response($html);

20. }

22. // ...

23. }

Vous allez en apprendre plus à propos d'un service important : le « service container », au fur et à mesure de votre lecture. Pour l'instant, vous avez juste besoin de savoir qu'il gère beaucoup d'objets, et que vous pouvez accéder à l'un d'eux (get()) en utilisant son surnom, comme templating ou logger. Le service de templating est une instance de TwigEngine et il a une méthode render().

Mais cela peut devenir plus facile. En étendant la classe Controller, vous pouvez aussi obtenir beaucoup de méthodes raccourcies, comme render() :

1. // src/AppBundle/Controller/MagiqueController.php

3. // ...

4. /**

5. * @Route("/numero/magique/{count}")

6. */

7. public function numeroAction($count)

8. {

9. // ...

11. /*

12. $html = $this->container->get('templating')->render(

13. 'magique/numero.html.twig',

14. array('listeNumerosMagiques' => $listeNumeros)

15. );

17. return new Response($html);

18. */

20. // render: un raccourci qui fait la même chose qu'au-dessus

21. return $this->render(

22. 'magique/nombre.html.twig',

23. array('listeNumerosMagiques' => $listeNumeros)

24. );

25. }

Apprenez-en plus à propos de ces méthodes raccourcies et comment elles fonctionnent dans le chapitre contrôleur.

5-2 - Créer le Template

Si vous rafraîchissez maintenant, vous aurez une erreur :

Impossible de trouver le template "magique/numero.html.twig"

Corrigez-la en créant un nouveau dossier app/Resources/views/magique et en mettant un fichier numero.html.twig dedans.

Twig :

1. {# app/Resources/views/magique/numero.html.twig #}

2. {% extends 'base.html.twig' %}

4. {% block body %}

5. <h1>Numeros magiques: {{ listeNumerosMagiques }}</h1>

6. {% endblock %}

PHP :

1. <!-- app/Resources/views/magique/numero.html.php -->

2. <?php $view->extend('base.html.php') ?>

4. <?php $view['slots']->start('body') ?>

5. <h1>Numéros magiques: <?php echo $view->escape($listeNumeroMagique) ?>

6. <?php $view['slots']->stop() ?>

Bienvenue à Twig ! Ce simple fichier montre déjà les bases : comme comment la syntaxe {{ variableName }} est utilisée pour imprimer quelque chose. La listeNumeroMagique est une variable que vous passez dans le template depuis l'appel render de votre contrôleur.

{% extends 'base.html.twig' %} pointe sur un fichier de disposition présent dans app/Resources/views/base.html.twig et venu avec votre nouveau projet. C'est vraiment basique (une structure HTML sans style) et c'est à vous de le customiser. La partie {% block body %} utilise un système d'héritage pour placer le contenu au milieu de la présentation base.html.twig.

Rafraîchissez pour voir votre template en action !

1. http://localhost:8000/app_dev.php/magique/numero/9

Si vous regardez votre code source, vous avez maintenant une structure HTML basique. Merci à base.html.twig.

Cela est juste la surface de la puissance de Twig. Quand vous serez prêt à maîtriser sa syntaxe, à boucler sur les tableaux, à interpréter des templates et d'autres choses cool, lisez le chapitre Templating.

6 - Explorer la structure du projet

Vous avez déjà créé une URL flexible, interprété un template qui utilise l'héritage et créé un point final JSON.

Il est temps d'explorer et de démystifier les fichiers de votre projet. Bonne nouvelle ! Vous avez déjà travaillé dans les deux plus importants dossiers :

app/

1. Contient les éléments tels que les fichiers de configuration et les templates. Basiquement, tout ce qui n'est pas du code PHP se place ici.

src/

1. Votre code PHP est logé ici.

99 % du temps, vous allez travailler dans le répertoire src/ (les fichiers PHP) ou app/ (tout le reste). Au fur et à mesure que vous serez plus avancé, vous apprendrez ce qui peut être fait dans chacun de ces dossiers.

Le dossier app/ contient aussi d'autres choses, comme app/AppKernel.php, que vous utiliserez pour activer de nouveaux bundles (c'est un des fichiers PHP de la courte liste de ceux présents dans app/).

Le dossier src/ contient seulement un dossier : src/AppBundle, et tout est dedans. Un bundle est comme un « plug-in » et vous pouvez trouver des bundles open sources et les installer dans votre projet. Mais même votre code est localisé dans un bundle, typiquement AppBundle (bien qu'il n'y ait rien de spécial à propos de AppBundle). Pour en découvrir plus à propos des bundles et pourquoi vous pourriez créer de multiples bundles (ex. : partager du code entre projets), consultez le chapitre sur les Bundles.

Et donc qu'en est-il des autres dossiers dans le projet ?

web/

1. C'est le « document racine » de votre projet et il contient tous les fichiers accessibles publiquement, comme les fichiers CSS, les images et les contrôleurs frontaux de Symfony qui exécutent l'application (app_dev.php et app.php).

tests/

1. Les tests automatiques (ex. : tests unitaires) de votre application sont localisés ici.

bin/

1. Les fichiers « binaires » sont logés ici. Le plus important est le fichier console qui est utilisé pour exécuter les commandes Symfony via la console : bin/console.

var/

1. C'est ici que sont stockés les fichiers créés automatiquement, comme les fichiers de cache (var/cache/), les logs (var/logs/) et les sessions (var/sessions/).

vendor/

1. les bibliothèques tierces, les packages et les bundles sont téléchargés ici par le manager de package Composer. Vous ne devriez jamais éditer un fichier contenu dans ce dossier.

Symfony est flexible. Si vous avez besoin de le faire, vous pouvez facilement passer outre la structure de dossier par défaut. Consultez Comment surcharger la structure de dossier par défaut de Symfony.

7 - Bundles et Configuration

Votre application Symfony vient avec une collection de bundles préinstallés, comme FrameworkBundle et TwigBundle. Les bundles sont similaires aux plug-ins avec une différence importante : toutes les fonctionnalités d'une application Symfony viennent des bundles.

Symfony est fourni avec plusieurs bundles intégrés (ouvrez votre fichier app/AppKernel.php) et vous allez probablement en installer plus. Le fichier principal de configuration de bundles est app/config/config.yml :

YAML :

1. # app/config/config.yml

3. # ...

4. framework:

5. secret: '%secret%'

6. router:

7. resource: '%kernel.root_dir%/config/routing.yml'

8. # ...

10. twig:

11. debug:            '%kernel.debug%'

12. strict_variables: '%kernel.debug%'

14. # ...

PHP :

1. // app/config/config.php

2. // ...

4. $container->loadFromExtension('framework', array(

5. 'secret' => '%secret%',

6. 'router' => array(

7. 'resource' => '%kernel.root_dir%/config/routing.php',

8. ),

9. // ...

10. ));

12. // Twig Configuration

13. $container->loadFromExtension('twig', array(

14. 'debug'            => '%kernel.debug%',

15. 'strict_variables' => '%kernel.debug%',

16. ));

18. // ...

La clé Framework configure le FrameworkBundle, la clé twig configure le TwigBundle, etc. Beaucoup de comportements dans Symfony peuvent être contrôlés juste en changeant une option dans ce fichier de configuration.

Pour obtenir un gros dump d'exemple de toutes les configurations valides sous une clé, utilisez la commande bin/console :

php bin/console config:dump-reference framework

Il y a beaucoup plus de puissance derrière le système de configuration de Symfony, incluant les environnements, les imports, et les paramètres. Le chapitre sur la configuration aborde ces points en détail.

8 - Et ensuite ?

Félicitations ! Vous avez déjà commencé à maîtriser Symfony et à apprendre un ensemble de nouvelles façons de construire de jolies applications, fonctionnelles, rapides, et maintenables.

Les prochaines parties porteront sur les contrôleurs, le routage, la gestion des templates et bien d'autres aspects.

Notes de la rédaction Developpez.com

Nous tenons à remercier Sensiolabs pour la mise à disposition de cette documentation, Christophe Louvet pour la traduction et Malick Seck pour sa relecture orthographique.