Documentation officielle du framework PHP Symfony 3 - Partie 2

Partie 2 : Avantages de la programmation avec Symfony comparée à une programmation directe en PHP

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 deuxième partie, vous allez appendre les avantages à programmer avec Symfony, comparativement à programmer simplement en PHP.

Si vous avez des remarques concernant ce tutoriel, un espace de dialogue vous est proposé sur le forum. N'hésitez pas à apporter vos avis sur le lien ci-dessous.

Commentez

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

- Auteur : Symfony

- Traducteur : Christophe LOUVET

- Parution : 13 août 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 première partie : Apprendre comment Symfony 3 intègre les fondamentaux HTTP

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

- Voir les autres parties

Sommaire

- 1. Un blog simple en PHP à plat

- 2. Isoler la présentation

- 3. Isoler la logique de l'application (Domaine)

- 4. Isoler l'agencement

- 5. Ajouter au blog la page « afficher »

- 6. Un contrôleur frontal à la rescousse

- 7. Créer le contrôleur frontal

- 8. Ajouter une touche de Symfony

- 9. L'application d'exemple dans Symfony

- 10. Meilleurs templates

- 11. Ce qu'offre Symfony

- Notes de la rédaction Developpez.com

1 - Un blog simple en PHP à plat

Dans ce chapitre, vous allez construire une application de blog en utilisant seulement du PHP à plat. Pour commencer, créez une page qui affiche les données d'entrée du blog qui ont été enregistrées de façon persistante dans la base de données. L'écrire en PHP à plat est rapide et vous donnera ceci :

1. <?php

2. // index.php

3. $link = new PDO("mysql:host=localhost;dbname=blog_db", 'myuser', 'mypassword');

5. $result = $link->query('SELECT id, title FROM post');

6. ?>

8. <!DOCTYPE html>

9. <html>

10. <head>

11. <title>List of Posts</title>

12. </head>

13. <body>

14. <h1>List of Posts</h1>

15. <ul>

16. <?php while ($row = $result->fetch(PDO::FETCH_ASSOC)): ?>

17. <li>

18. <a href="/show.php?id=<?= $row['id'] ?>">

19. <?= $row['title'] ?>

20. </a>

21. </li>

22. <?php endwhile ?>

23. </ul>

24. </body>

25. </html>

27. <?php

28. $link = null;

29. ?>

Ceci est rapide à écrire et à exécuter, et votre application grandissant deviendra impossible à maintenir. Il y a plusieurs problèmes qui nécessitent d'être traités.

- Pas de traitement d'erreurs : qu'adviendra-t-il si la connexion à la base de données échoue ?

- Organisation pauvre : si l'application grossit, ce fichier unique deviendra de moins en moins maintenable. Où placer votre code qui va gérer la soumission d'un formulaire ? Comment pouvez-vous valider les données ? Où devrait se trouver le code pour l'envoi d'e-mail ?

- Code difficile à réutiliser : puisque tout est dans un seul fichier, il n'y a aucun moyen de réutiliser une partie de l'application pour les autres « pages » du blog.

Un autre problème non mentionné ici est le fait que la base de données est liée à MySQL. Bien que non couvert ici, Symfony intègre entièrement Doctrine, une bibliothèque dédiée à l'abstraction et au mappage de bases de données.

2 - Isoler la présentation

Le code peut immédiatement profiter de la séparation entre la logique de l'application et le code qui prépare la « présentation » HTML :

1. // index.php

2. $link = new PDO("mysql:host=localhost;dbname=blog_db", 'myuser', 'mypassword');

4. $result = $link->query('SELECT id, title FROM post');

6. $posts = array();

7. while ($row = $result->fetch(PDO::FETCH_ASSOC)) {

8. $posts[] = $row;

9. }

11. $link = null;

13. // include the HTML presentation code

14. require 'templates/list.php';

Le code HTML est maintenant stocké dans un fichier séparé (templates/list.php), lequel est principalement un fichier HTML qui utilise une syntaxe similaire à PHP  :

1. <!-- templates/list.php -->

2. <!DOCTYPE html>

3. <html>

4. <head>

5. <title>List of Posts</title>

6. </head>

7. <body>

8. <h1>List of Posts</h1>

9. <ul>

10. <?php foreach ($posts as $post): ?>

11. <li>

12. <a href="/show.php?id=<?= $post['id'] ?>">

13. <?= $post['title'] ?>

14. </a>

15. </li>

16. <?php endforeach ?>

17. </ul>

18. </body>

19. </html>

Par convention, le fichier qui contient toute la logique de l'application, index.php, est désigné par « contrôleur ». Le terme contrôleur est un terme que vous entendrez beaucoup, indépendamment du langage ou du Framework que vous utilisez. Il se réfère simplement à la zone de votre code qui traite les entrées utilisateur et prépare les réponses.

Dans l'exemple ci-dessus, le contrôleur prépare les données depuis la base de données et inclut ensuite un template pour présenter ces données. Avec un contrôleur isolé, vous pourriez juste changer le fichier de template pour présenter les entrées du blog dans un autre format (ex. : list.json.php pour le format JSON).

3 - Isoler la logique de l'application (Domaine)

Jusqu'à maintenant, l'application contient uniquement une page. Mais qu'en sera-t-il si une seconde page est nécessaire pour utiliser la même connexion de base de données, ou encore la même rangée de posts du blog ? Réorganisons le code pour que le comportement principal de celui-ci et des fonctions d'accès aux données de l'application soit isolé dans un nouveau fichier nommé model.php :

1. // model.php

2. function open_database_connection()

3. {

4. $link = new PDO("mysql:host=localhost;dbname=blog_db", 'myuser', 'mypassword');

6. return $link;

7. }

9. function close_database_connection(&$link)

10. {

11. $link = null;

12. }

14. function get_all_posts()

15. {

16. $link = open_database_connection();

18. $result = $link->query('SELECT id, title FROM post');

20. $posts = array();

21. while ($row = $result->fetch(PDO::FETCH_ASSOC)) {

22. $posts[] = $row;

23. }

24. close_database_connection($link);

26. return $posts;

27. }

Le nom de fichier model.php est utilisé, car la logique et l'accès aux données d'une application sont traditionnellement connus sous le nom de couche « modèle ». Dans une application bien organisée, la majorité du code représentant votre « logique business » devrait résider dans le modèle (en opposition au placement dans le contrôleur). Et contrairement dans cet exemple, seule une portion (ou aucune) du modèle est actuellement concernée par l'accès à la base de données.

Le contrôleur (index.php) est maintenant très simple :

// index.php

require_once 'model.php';

$posts = get_all_posts();

require 'templates/list.php';

Maintenant, la seule tâche du contrôleur est de récupérer les données de la couche modèle de l'application (le modèle) et d'appeler un template pour présenter ces données. Voici un exemple vraiment très simple du modèle-vue-contrôleur.

4 - Isoler l'agencement

À ce point, l'application a été réagencée en trois parties distinctes offrant de multiples avantages et l'opportunité de réutiliser la plupart des éléments sur différentes pages.

La seule partie du code qui ne peut pas être réutilisée est la couche de l'agencement. Réglons cela en créant un nouveau fichier templates/layout.php :

1. <!-- templates/layout.php -->

2. <!DOCTYPE html>

3. <html>

4. <head>

5. <title><?= $title ?></title>

6. </head>

7. <body>

8. <?= $content ?>

9. </body>

10. </html>

Le template (templates/list.php) peut maintenant être simplifié pour « étendre » templates/layout.php :

1. <!-- templates/list.php -->

2. <?php $title = 'List of Posts' ?>

4. <?php ob_start() ?>

5. <h1>List of Posts</h1>

6. <ul>

7. <?php foreach ($posts as $post): ?>

8. <li>

9. <a href="/show.php?id=<?= $post['id'] ?>">

10. <?= $post['title'] ?>

11. </a>

12. </li>

13. <?php endforeach ?>

14. </ul>

15. <?php $content = ob_get_clean() ?>

17. <?php include 'layout.php' ?>

Vous avez maintenant une configuration qui vous permettra de réutiliser la disposition. Malheureusement, pour le faire, vous serez obligé d'utiliser quelques fonctions PHP laides (ob_start(), ob_get_clean()) dans le template. Symfony utilise un composant de templating qui permet d'effectuer cela proprement et facilement. Vous allez voir cela en action rapidement.

5 - Ajouter au blog la page « afficher »

La page « liste » du blog a maintenant été réagencée et le code est donc mieux organisé et réutilisable. Pour le prouver, ajoutez au blog une page « afficher », laquelle affiche un post individuel du blog identifié par un paramètre d'identification (id) dans la requête.

Pour commencer, créez une nouvelle fonction dans le fichier model.php qui récupère un résultat individuel du blog par l'id communiqué :

1. // model.php

2. function get_post_by_id($id)

3. {

4. $link = open_database_connection();

6. $query = 'SELECT created_at, title, body FROM post WHERE  id=:id';

7. $statement = $link->prepare($query);

8. $statement->bindValue(':id', $id, PDO::PARAM_INT);

9. $statement->execute();

11. $row = $statement->fetch(PDO::FETCH_ASSOC);

13. close_database_connection($link);

15. return $row;

16. }

Ensuite, créez un nouveau fichier nommé show.php - le contrôleur pour cette nouvelle page :

1. // show.php

2. require_once 'model.php';

4. $post = get_post_by_id($_GET['id']);

6. require 'templates/show.php';

Enfin, créez le nouveau fichier de template : templates/show.php, pour interpréter le post individuel du blog :

1. <!-- templates/show.php -->

2. <?php $title = $post['title'] ?>

4. <?php ob_start() ?>

5. <h1><?= $post['title'] ?></h1>

7. <div class="date"><?= $post['created_at'] ?></div>

8. <div class="body">

9. <?= $post['body'] ?>

10. </div>

11. <?php $content = ob_get_clean() ?>

13. <?php include 'layout.php' ?>

Créer la seconde page est maintenant très simple et aucun code n'est dupliqué. Cette page introduit également des problèmes persistants qu'un framework pourra résoudre pour vous. Par exemple un id de paramètre requête invalide ou manquant peut déclencher un crash de la page. Ce serait mieux si cela causait un rendu de page 404, mais cela ne peut pas vraiment être fait facilement actuellement. Pire, si vous avez oublié de nettoyer le paramètre id via la fonction intval(), votre base de données entière pourrait être exposée à une attaque par injection SQL.

Un autre problème majeur est que chaque fichier de contrôleur individuel doit inclure le fichier model.php. Qu'en sera-t-il si chaque fichier de contrôleur doit soudainement inclure un fichier additionnel pour effectuer d'autres tâches globales (ex. : renforcer la sécurité) ? À l'heure actuelle, ce code devait être ajouté à chaque fichier de contrôleur. Si vous oubliez d'inclure quelque chose dans un fichier, il faut espérer que ça ne se rapporte pas à la sécurité…

6 - Un contrôleur frontal à la rescousse

La solution est d'utiliser un contrôleur frontal : un unique fichier PHP à travers lequel toutes les requêtes sont traitées. Avec un contrôleur frontal, les URI pour les applications changent légèrement, mais commencent à être plus flexibles.

Sans contrôleur frontal :

/index.php => page de la liste des posts du blog (index.php exécuté) ;

/show.php => page d'affichage d'un post du blog (show.php exécuté).

Avec index.php comme contrôleur frontal :

/index.php => page de la liste des posts du blog (index.php exécuté) ;

/index.php/show => page d'affichage d'un post du blog (index .php exécuté).

En utilisant les règles de réécriture (rewrite) de la configuration du serveur Web, la partie index.php de l'URI n'est plus nécessaire et vous aurez des URL simples et propres (par exemple: /show ).

Lors de l'utilisation d'un contrôleur frontal, un seul fichier PHP (index.php dans ce cas) traite les requêtes. Pour la page d'affichage de post du blog, /index.php/show, c'est le fichier index.php qui sera exécuté, lequel est maintenant responsable des requêtes de routage interne, basé sur l'URI totale. Comme vous allez le voir, un contrôleur frontal est un outil vraiment puissant.

7 - Créer le contrôleur frontal

Vous êtes sur le point de passer une grande étape avec votre application. Avec un seul fichier gérant les requêtes, vous pouvez centraliser les choses telles que la gestion de la sécurité, le chargement de configuration, et le routage. Dans cette application, index.php doit maintenant être suffisamment intelligent pour traiter la page de liste (list) des posts du blog ou celle d'affichage de post individuel (show), basé sur l'URI demandée :

1. // index.php

3. // charge et initialise toutes les bibliothèques globales

4. require_once 'model.php';

5. require_once 'controllers.php';

7. // route les requêtes en interne

8. $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

9. if ('/index.php' === $uri) {

10. list_action();

11. } elseif ('/index.php/show' === $uri && isset($_GET['id'])) {

12. show_action($_GET['id']);

13. } else {

14. header('HTTP/1.1 404 Not Found');

15. echo '<html><body><h1>Page non trouvée</h1></body></html>';

16. }

Pour un souci d'organisation, les deux contrôleurs ( index.php et show.php) sont maintenant des fonctions PHP, et chacun a été déplacé dans un autre fichier : controllers.php :

1. // controllers.php

2. function list_action()

3. {

4. $posts = get_all_posts();

5. require 'templates/list.php';

6. }

8. function show_action($id)

9. {

10. $post = get_post_by_id($id);

11. require 'templates/show.php';

12. }

Comme contrôleur frontal, index.php a pris un rôle entièrement nouveau, qui inclut le chargement de bibliothèques de noyau et de routage de l'application, de sorte qu'un contrôleur ou un autre (les fonctions list_action() et show_action()) est appelé. En réalité, le contrôleur frontal commence à ressembler et agir comme le mécanisme de Symfony pour gérer et router les requêtes.

Mais faites attention à ne pas confondre les termes « contrôleur frontal » et « contrôleur ». En temps normal, votre application n'utilisera que seulement le contrôleur frontal pour démarrer votre code. Vous aurez plusieurs fonctions qui serviront de contrôleurs : une pour chaque page.

Un autre avantage d'un contrôleur frontal est la flexibilité des URL. Notez que l'URL de la page d'affichage de post du blog pourrait être changée de /show en /read en modifiant le code à un seul endroit. Auparavant, un fichier entier aurait dû être renommé. Dans Symfony, les URL sont encore plus flexibles.

Maintenant, l'application a évolué depuis un unique fichier PHP vers une structure qui est organisée et permet la réutilisation de code. Vous devriez être plus heureux, mais loin d'être satisfait. Par exemple, le système de « routage » est inconstant, et ne devrait pas reconnaître que la page de liste des posts du blog (index.php) devrait être accessible aussi via « / » (si les règles de rewrite Apache ont été ajoutées). Aussi, plutôt que de développer le blog, beaucoup de ce temps a été passé à travailler sur l'architecture du code (ex. : routage, appel des contrôleurs, templates, etc.). Plus de temps devrait encore être passé pour la soumission des formulaires, la validation des entrées, le logging, et la sécurité. Pourquoi devriez-vous réinventer des solutions à tous ces problèmes routiniers ?

8 - Ajouter une touche de Symfony

Symfony arrive à la rescousse. Avant d'utiliser Symfony, vous devez le télécharger. Ceci peut être effectué via Composer, qui s'occupe de télécharger la version stable et toutes ses dépendances et fournit un autoloader. Un autoloader est un outil qui permet de démarrer l'utilisation de classes PHP sans inclure explicitement le ou les fichiers les contenant.

Dans votre dossier racine, créez un fichier composer.json avec le contenu suivant :

1. {

2. "require": {

3. "symfony/symfony": "3.1.*"

4. },

5. "autoload": {

6. "files": ["model.php","controllers.php"]

7. }

8. }

Ensuite, téléchargez Composer et lancez-le avec la commande suivante, laquelle va télécharger Symfony dans un dossier vendor/ :

1. $ composer install

En plus du téléchargement de vos dépendances, Composer génère un fichier PHP vendor/autoload.php, qui effectue le chargement automatique de tous les fichiers du framework Symfony aussi bien que les fichiers mentionnés dans la section autoload de votre fichier composer.json.

Le cœur de la philosophie de Symfony est basé sur le principe que le travail principal d'une application est d'interpréter chaque requête et retourner une réponse. À cette fin, Symfony fournit deux classes : une classe Request et une classe Response. Ces classes sont une représentation orientée objet des requêtes et réponses HTTP brutes retournées. Utilisez-les pour améliorer le blog :

1. // index.php

2. require_once 'vendor/autoload.php';

4. use Symfony\Component\HttpFoundation\Request;

5. use Symfony\Component\HttpFoundation\Response;

7. $request = Request::createFromGlobals();

9. $uri = $request->getPathInfo();

10. if ('/' === $uri) {

11. $response = list_action();

12. } elseif ('/show' === $uri && $request->query->has('id')) {

13. $response = show_action($request->query->get('id'));

14. } else {

15. $html = '<html><body><h1>Page Not Found</h1></body></html>';

16. $response = new Response($html, Response::HTTP_NOT_FOUND);

17. }

19. // echo the headers and send the response

20. $response->send();

Les contrôleurs sont maintenant capables de retourner un objet Response. Pour rendre cela plus facile, vous pouvez ajouter une nouvelle fonction render_template(), laquelle agit un peu plus rapidement que le moteur de Templating Symfony :

1. // controllers.php

2. use Symfony\Component\HttpFoundation\Response;

4. function list_action()

5. {

6. $posts = get_all_posts();

7. $html = render_template('templates/list.php', array('posts' => $posts));

9. return new Response($html);

10. }

12. function show_action($id)

13. {

14. $post = get_post_by_id($id);

15. $html = render_template('templates/show.php', array('post' => $post));

17. return new Response($html);

18. }

20. // helper function to render templates

21. function render_template($path, array $args)

22. {

23. extract($args);

24. ob_start();

25. require $path;

26. $html = ob_get_clean();

28. return $html;

29. }

En apportant une petite partie de Symfony, l'application est plus flexible et fiable. L'objet Request fournit un moyen sûr pour accéder à des informations sur les requêtes HTTP. La méthode getPathInfo() retourne spécialement une URI nettoyée (retournant toujours /show et jamais /index.php/show). De sorte que même si l'utilisateur se rend sur la page /index.php/show, l'application est suffisamment intelligente pour router la requête via show_action().

L'objet Response donne de la flexibilité lors de la construction de la réponse HTTP, autorisant les headers HTTP et le contenu à être ajoutés via une interface orientée objet. Et bien que la réponse de cette application soit simple, cette flexibilité sera coûteuse quand l'application va commencer à grossir.

9 - L'application d'exemple dans Symfony

Le blog a parcouru un long chemin, mais il contient encore  beaucoup de code pour une application aussi simple. Le long du chemin, vous avez fait un système simple de routage et une méthode utilisant ob_start() et ob_clean() pour interpréter les templates. Si pour une quelconque raison, vous voulez construire ce « framework » from scratch, vous pouvez au moins utiliser les composants Routing et Templating de Symfony en standalone, lesquelles règlent toujours ces problèmes.

Plutôt que de resolutionner des problèmes communs, vous pouvez laisser Symfony s'en charger pour vous. Voici la même application exemple, construite maintenant avec Symfony :

1. // src/AppBundle/Controller/BlogController.php

2. namespace AppBundle\Controller;

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

6. class BlogController extends Controller

7. {

8. public function listAction()

9. {

10. $posts = $this->get('doctrine')

11. ->getManager()

12. ->createQuery('SELECT p FROM AcmeBlogBundle:Post p')

13. ->execute();

15. return $this->render('Blog/list.html.php', array('posts' => $posts));

16. }

18. public function showAction($id)

19. {

20. $post = $this->get('doctrine')

21. ->getManager()

22. ->getRepository('AppBundle:Post')

23. ->find($id);

25. if (!$post) {

26. // provoque l'affichage la la page 404 page not found

27. throw $this->createNotFoundException();

28. }

30. return $this->render('Blog/show.html.php', array('post' => $post));

31. }

32. }

Notez que les deux fonctions contrôleurs sont maintenant dans la « classe contrôleur' ». C'est un excellent moyen de regrouper les pages de même contexte. Les fonctions contrôleurs sont souvent aussi désignées par « actions ».

Les deux contrôleurs (ou actions) sont toujours légers. Ils utilisent chacun la bibliothèque doctrine pour récupérer les objets depuis la base de données et les composants de templating pour interpréter un template et retourner un objet Response. Le template list.php est maintenant plus simple :

1. <!-- app/Resources/views/Blog/list.html.php -->

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

4. <?php $view['slots']->set('title', 'List of Posts') ?>

6. <h1>Liste des Posts</h1>

7. <ul>

8. <?php foreach ($posts as $post): ?>

9. <li>

10. <a href="<?php echo $view['router']->path(

11. 'blog_show',

12. array('id' => $post->getId())

13. ) ?>">

14. <?php echo $post->getTitle() ?>

15. </a>

16. </li>

17. <?php endforeach ?>

18. </ul>

Le layout est quasiment identique :

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

2. <!DOCTYPE html>

3. <html>

4. <head>

5. <title><?php echo $view['slots']->output(

6. 'title',

7. 'Default title'

8. ) ?></title>

9. </head>

10. <body>

11. <?php echo $view['slots']->output('_content') ?>

12. </body>

13. </html>

Le template show show.php vous est laissé en exercice. Il devrait être facile à mettre à jour en se basant sur ce qui a été fait pour le template list.php.

Quand le moteur Symfony (appelé le noyau) démarre, il a besoin d'une carte pour savoir quels sont les contrôleurs à exécuter en fonction de l'information demandée. Une carte de configuration de routage - app/config/routing.yml - fournit cette information dans un format lisible :

1. # app/config/routing.yml

2. blog_list:

3. path:     /blog

4. defaults: { _controller: AppBundle:Blog:list }

6. blog_show:

7. path:     /blog/show/{id}

8. defaults: { _controller: AppBundle:Blog:show }

Maintenant que Symfony gère toutes les tâches banales, le contrôleur frontal web/app.php devient tout simplement inutile. Et puisqu'il ne fait que peu de chose, vous n'aurez plus besoin de le toucher une fois créé :

1. // web/app.php

2. require_once __DIR__.'/../app/bootstrap.php';

3. require_once __DIR__.'/../app/AppKernel.php';

5. use Symfony\Component\HttpFoundation\Request;

7. $kernel = new AppKernel('prod', false);

8. $kernel->handle(Request::createFromGlobals())->send();

Le travail du contrôleur frontal consiste uniquement à initialiser le moteur Symfony (appelé aussi le noyau) et lui passer un objet Request à gérer. Le noyau de Symfony demande au routeur d'inspecter la requête. Le routeur établit la correspondance entre l'URL entrant et la route spécifique, et retourne les informations relatives à la route, y inclus le contrôleur qui sera exécuté. Le bon contrôleur correspondant à la route est exécuté et votre code à l'intérieur du contrôleur crée et retourne l'objet Response associé. Les en-têtes HTTP et le contenu de l'objet Response sont envoyés au client.

C'est quelque chose de magnifique.

Diagramme des flux entre objets request et objets response

(cliquez ici pour aggrandir l'image)

10 - Meilleurs templates

Si vous optez pour l'utiliser, Symfony vient de base avec un moteur de templates appelé Twig qui permet de faire des templates très facilement et de les lire plus simplement. Cela signifie que l'application d'exemple pourrait contenir moins de code. Regardez ! Par exemple, réécrire le template list.html.php dans Twig pourrait ressembler à ceci :

1. {# app/Resources/views/blog/list.html.twig #}

2. {% extends "layout.html.twig" %}

4. {% block title %}List of Posts{% endblock %}

6. {% block body %}

7. <h1>List of Posts</h1>

8. <ul>

9. {% for post in posts %}

10. <li>

11. <a href="{{ path('blog_show', {'id': post.id}) }}">

12. {{ post.title }}

13. </a>

14. </li>

15. {% endfor %}

16. </ul>

17. {% endblock %}

Et la réécriture du template layout.html.php dans Twig ressemblera à ceci :

1. {# app/Resources/views/layout.html.twig #}

2. <!DOCTYPE html>

3. <html>

4. <head>

5. <title>{% block title %}Default title{% endblock %}</title>

6. </head>

7. <body>

8. {% block body %}{% endblock %}

9. </body>

10. </html>

Twig est très bien supporté par Symfony. Et bien que les templates PHP soient supportés dans Symfony, les avantages qu'offrent Twig sont nombreux. Pour plus de détails référez-vous au chapitre sur le Templating.

11 - Ce qu'offre Symfony

Dans les prochains chapitres, vous allez en apprendre plus sur comment chaque partie de Symfony fonctionne, et l'organisation recommandée d'un projet. Pour le moment, jetez un œil sur comment migrer un blog écrit en PHP à plat vers Symfony vous a amélioré la vie.

- Votre application a maintenant du code clair et toujours organisé (à travers Symfony qui ne vous force pas dans ce sens). Ceci favorise la réutilisabilité et permet à des nouveaux développeurs d'être productifs plus rapidement dans votre projet.

- 100 % du code que vous avez écrit est pour votre application. Vous n'avez pas à développer ou maintenir des utilitaires de bas niveau comme l'autoloading, le routage, ou le rendu des contrôleurs.

- Symfony vous donne accès à des outils open source comme Doctrine et le templating, la sécurité, les formulaires, la validation et la translation de composants (pour en nommer quelques-uns).

- L'application bénéficie maintenant d'URL complètement flexibles, merci au composant de routage.

- L'architecture centrée HTTP vous donne accès à de puissants outils tels que le caching HTTP, alimenté par le cache HTTP interne de Symfony ou des outils plus puissants tels que Varnish. Cela sera couvert dans un prochain chapitre à propos du cache.

Et peut-être le meilleur de tout, en utilisant Symfony, vous avez maintenant accès à tout un ensemble d'outils open source de qualité développés par la communauté Symfony. Une bonne sélection de ceux-ci peut être trouvée sur KnpBundles.com.

Notes de la rédaction Developpez.com

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

Retour à l'article