Aller au menu - Aller au contenu

Icône Vous avez dit Symfony2 ?

Avatar
Mise à jour : 02/05/2012
Difficulté : Intermédiaire Intermédiaire Durée d'étude : 1 heure Creative Commons BY-NC-SA
20 752 visites depuis 7 jours, dont 1 032 sur ce chapitre classé 17/786
Dans ce chapitre, nous allons voir comment est organisé Symfony2 à l'intérieur. Nous n'entrerons pas dans les détails, c'est trop tôt, le but étant juste d'avoir une vision globale du processus d'exécution d'une page sous Symfony2. Ainsi, vous pourrez comprendre ce que vous faites. C'est mieux, non ? :)
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

L'architecture des fichiers

On vient d'extraire beaucoup de fichiers, mais sans savoir encore à quoi ils servent. C'est le moment d'éclaircir tout cela !

Liste des répertoires


Ouvrez donc le répertoire dans lequel vous avez extrait les fichiers. Vous pouvez voir qu'il n'y a pas beaucoup de fichier ici, seulement des répertoires. En effet tout est bien rangé dans chaque répertoire, il nous faut donc élucider ces répertoires. En voici la liste :
Code : Autre
1
2
3
4
5
app
bin
src
vendor
web

Le répertoire app/


Ce répertoire contient tout ce qui concerne votre site internet sauf... son code source. Assez étrange me direz vous :p . En fait c'est simplement pour séparer le code source qui fait la logique de votre site du reste. Le reste, c'est ce répertoire app. Et ce reste c'est : la configuration, le cache, les fichiers logs, etc. Ce sont des fichiers qui concernent l'entièreté de votre site, contrairement aux fichiers de code source qui seront découpés par fonctionnalités de votre site.
Dans Symfony2, un projet de site internet est une application, simple question de vocabulaire. Le répertoire app/ est donc le raccourci pour application.

Le répertoire bin/


Ce répertoire ne contient qu'un seul script pour mettre à jour les librairies tierces. C'est celui que vous avez exécuté au chapitre précédent si Git est installé sur votre ordinateur.

Si vous n'avez pas Git ou ne savez pas ce que c'est, ce répertoire ne vous est d'aucune utilité.

Le répertoire src/


Voilà enfin le répertoire dans lequel on mettra le code source ! C'est ici que l'on passera le plus clair de notre temps. Dans ce répertoire, nous organiserons notre code en "bundles", des briques de notre application, dont nous verrons la définition plus loin.

Vous pouvez voir qu'il n'est pas vide : il contient en effet quelques fichiers exemples, fournis par Symfony2. Nous les supprimerons plus tard dans ce tutoriel.

Le répertoire vendor/


Ce répertoire contient toutes les librairies externes à notre application. Dans ces librairies externes, j'inclue Symfony2 ! Vous pouvez parcourir ce répertoire, vous y trouverez des librairies comme Doctrine, Twig, SwiftMailer, etc.

Et une librairie, c'est quoi exactement ?

Une librairie est une sorte de boite noire qui remplit une fonction bien précise, et dont on peut se servir dans notre code. Par exemple, la librairie SwiftMailer permet d'envoyer des emails. On ne sait pas comment elle fonctionne (principe de la boite noire), mais on sait comment s'en servir : on pourra donc envoyer des emails très facilement, juste en apprenant rapidement à utiliser la librairie.

Le répertoire web/


Ce répertoire contient tous les fichiers destinés à vos visiteurs : images, fichiers CSS et JavaScript, etc. Il contient également le contrôleur frontal (app.php), dont nous parlerons juste après.

En fait c'est le seul répertoire qui devrait être accessible à vos visiteurs. Les autres répertoires ne sont pas censés être accessibles (ce sont vos classes, elles vous regardent vous, pas vos visiteurs), c'est pourquoi vous y trouverez des fichiers .htaccess interdisant l'accès depuis l'extérieur. On utilisera donc toujours des URL du type http://localhost/Symfony/web/... au lieu de simplement http://localhost/Symfony/....

Si vous le souhaitez, vous pouvez configurer votre Apache pour que l'URL http://localhost/Symfony pointe directement sur le répertoire web/. C'est en tout cas ce que vous devrez faire lorsque vous mettrez votre site en ligne (les hébergeurs le permettent). Pour cela, vous pouvez lire ce tutoriel qui explique comment configurer Apache.

A retenir


Retenez donc que nous passerons la plupart de notre temps dans le répertoire src/, à travailler sur nos bundles. On touchera également pas mal au répertoire app/ pour configurer notre application. Et lorsque nous installerons des bundles téléchargés, nous le ferons dans le répertoire vendor/.

Le contrôleur frontal


Définition


Le contrôleur frontal (front controller, en anglais) est le point d'entrée de votre application. C'est le fichier par lequel passent toutes vos pages. Vous devez surement connaitre le principe du index.php et des pseudo-frames (avec des URL du type index.php?page=blog), et bien ce index.php est un contrôleur frontal.

Dans Symfony2, le contrôleur frontal se situe dans le répertoire web/, il s'agit de app.php ou app_dev.php.

Pourquoi y a-t-il deux contrôleurs frontaux ? Normalement c'est un fichier unique qui gère toutes les pages non ?

Vous avez parfaitement raison... pour un code classique ! Nous travaillons maintenant avec Symfony2, et son objectif est de nous faciliter le développement. C'est pourquoi Symfony2 propose un contrôleur frontal pour nos visiteurs, app.php, et un contrôleur frontal lorsque nous développons, app_dev.php. Ces deux contrôleurs frontaux, fournis par Symfony2 et prêts à l'emploi, définissent en fait deux environnements de travail.

Deux environnements de travail


L'objectif est de répondre au mieux suivant la personne qui visite le site :
  • Un développeur a besoin d'informations sur la page afin de l'aider à développer. En cas d'erreur, il veut tous les détails pour pouvoir déboguer facilement. Il n'a pas besoin de rapidité.
  • Un visiteur normal n'a pas besoin d'informations particulières sur la page. En cas d'erreur, l'origine de celles-ci ne l'intéresse pas du tout, il veut juste retourner d'où il vient. Par contre, il veut que le site soit le plus rapide possible à charger.

Vous voyez la différence ? A chacun ses besoins, et Symfony2 compte bien tous les remplir. C'est pourquoi il offre plusieurs environnements de travail :
  • L'environnement de développement, appelé « dev », accessible en utilisant le contrôleur frontal app_dev.php. C'est l'environnement que l'on utilisera toujours pour développer.
  • L'environnement de production, appelé « prod », accessible en utilisant le contrôleur frontal app.php.

Essayez-les ! Allez sur http://localhost/Symfony/web/app_dev.php et vous verrez une barre d’outils en bas de votre écran, contenant nombre d’informations utiles au développement. Allez sur http://localhost/Symfony/web/app.php et vous obtiendrez... une erreur 404 :p . En effet, aucune page n'est définie par défaut pour le mode « prod ». Nous les définirons plus tard, mais notez que c'est une « belle » erreur 404, aucun terme barbare n'est employé pour la justifier ^^ .

Pour voir le comportement du mode « dev » en cas d'erreur, essayez aussi d'aller sur une page qui n'existe pas. Vous avez vu ce que donne une page introuvable en mode « prod », mais allez maintenant sur http://localhost/Symfony/web/app_dev.p [...] quinexistepas. La différence est claire : le mode « prod » nous dit juste « page introuvable » alors que le mode « dev » nous donne plein d'informations sur l'origine de l'erreur, indispensables pour la corriger.

C'est pourquoi, dans la suite du tutoriel, nous utiliserons toujours le mode « dev » en passant donc par app_dev.php. Bien sûr, lorsque votre site sera opérationnel et que des internautes pourront le visiter, il faudra leur faire utiliser le mode « prod ». Mais nous n'en sommes pas encore là.

Et comment savoir quelles erreurs surviennent en mode production si elles ne s'affichent pas ?
C'est une bonne question, en effet si par malheur une erreur intervient pour l'un de vos visiteurs, il ne verra aucun message et vous non plus, une vraie galère pour déboguer ! En réalité si les erreurs ne sont pas affichées, elles sont bien stockées dans un fichier. Allez jeter un oeil au fichier app/logs/prod.log qui contient plein d'informations sur les requêtes effectuées en mode production, dont les erreurs ;) .


Concrètement, qu'est-ce que contrôle le contrôleur frontal ?


Très bonne question. Pour cela, rien de tel que... d'ouvrir le fichier app.php. Ouvrez-le et vous constaterez qu'il ne fait pas grand chose. En effet, le but du contrôleur frontal n'est pas de faire quelque chose, mais d'être un point d'entrée de notre application. Il se limite donc à appeler le noyau (Kernel) de Symfony2 en disant "On vient de recevoir une requête, gère la s'il-te-plait".

Ici, voyez le contrôleur frontal comme un fichier à nous (il est dans notre répertoire web/), et le Kernel comme un composant Symfony2, une boite noire (il est dans le répertoire vendors/). Vous voyez comment on a utilisé notre premier composant Symfony2 : on a délégué la gestion de la requête au Kernel. Bien sûr ce Kernel aura besoin de nous pour savoir quoi exécuter comme code, mais il gère déjà plusieurs choses que nous avons vues : la gestion des erreurs, l'ajout de la toolbar en bas de l'écran, etc. On n'a encore rien fait, et pourtant on a déjà gagné du temps !

L'architecture conceptuelle

On vient de voir comment sont organisés les fichiers de Symfony2. Maintenant il s'agit de comprendre comment s'organise l'exécution du code au sein de Symfony2.

Architecture MVC


Architecture MVC... Vous avez certainement déjà entendu parler de ce concept. Sachez que Symfony2 respecte bien entendu cette architecture MVC. Je ne vais pas rentrer dans ses détails car il y a déjà un super tutoriel sur ce même site, mais en voici les grandes lignes.

MVC signifie Modèle / Vue / Contrôleur. C'est un découpage très répandu pour développer les sites Internet, car il sépare les couches selon leur logique propre :
  • le Contrôleur (ou Controller) : son rôle est de générer la réponse à la requête HTTP demandée par notre visiteur. Il est la couche qui se charge d'analyser et de traiter la requête de l'utilisateur. Le contrôleur contient la logique de notre site Internet et va se contenter « d'utiliser » les autres composants : les modèles et les vues. Concrètement un contrôleur va récupérer, par exemple, les informations sur l'utilisateur courant, vérifier qu'il a le droit de modifier tel article, récupérer cet article et demander la page du formulaire d'édition de l'article. C'est tout bête, avec quelques if(), on s'en sort très bien ;
  • le Modèle (ou Model) : son rôle est de gérer vos données et votre contenu. Reprenons l'exemple de l'article. Lorsque je dis « le contrôleur récupère l'article », il va en fait faire appel au modèle « article » et lui dire : « donne-moi l'article portant l'id 5 ». C'est le modèle qui sait comment récupérer cet article, généralement via une requête au serveur SQL, mais ça pourrait être depuis un fichier texte ou ce que vous voulez. Au final, il permet au contrôleur de manipuler les articles, mais sans savoir comment les articles sont stockés, gérés, etc. C'est une couche d'abstraction ;
  • la Vue (ou View) : son rôle est d'afficher les pages. Reprenons encore l'exemple de l'article. Ce n'est pas le contrôleur qui affiche le formulaire, il ne fait qu'appeler la bonne vue. Si nous avons une vue « formulaire », les balises HTML du formulaire d'édition de l'article y seront et au final, le contrôleur ne fera qu'afficher cette vue sans savoir vraiment ce qu'il y a dedans. En pratique, c'est le designer d'un projet qui travaille sur les vues. Séparer vues et contrôleurs permet aux designers et développeurs PHP de travailler ensemble sans se marcher dessus.

Au final, si vous avez bien compris, le contrôleur ne contient que du code très simple, car il se contente d'utiliser des modèles et des vues en leur attribuant des tâches précises. Il agit un peu comme un chef d'orchestre, qui n'agite qu'une baguette alors que ses musiciens jouent des instruments complexes.

Parcours d'une requête dans Symfony2


Afin de bien visualiser tous les acteurs que nous avons vu jusqu'à présent, je vous propose un schéma du parcours complet d'une requête dans Symfony2 :
Image utilisateur

En le parcourant avec des mots, voici ce que cela donne :
  1. Le visiteur demande la page /blog ;
  2. Le contrôleur frontal reçoit la requête, charge le Kernel et la lui transmet ;
  3. Le Kernel demande au Routeur quel contrôleur exécuter pour l'URL /blog. Ce Routeur est un composant Symfony2 qui fait la correspondance entre URLs et contrôleurs, nous l'étudierons bien sûr dans un prochain chapitre. Le Routeur fait donc son travail, et dit au Kernel qu'il faut exécuter le contrôleur SdzBlog ;
  4. Le Kernel exécute donc ce contrôleur. Le contrôleur demande au modèle Article la liste des articles, puis la donne à la vue ListeArticles pour qu'elle construise la page HTML et la lui retourne. Une fois fini, le contrôleur envoie au visiteur la page HTML complète.

J'ai mis des couleurs pour distinguer les points où on intervient des autres. En vert, donc le contrôleur, modèle et vue, c'est ce qu'on devra développer nous-mêmes. En orange, donc le Kernel et le Routeur, c'est ce qu'on devra configurer. On ne touchera pas au contrôleur frontal, en gris.

Maintenant, il ne nous reste plus qu'à voir comment organiser concrètement notre code à nous et sa configuration.

Symfony2 et ses bundles

La découpe en « bundles »


Le concept


Vous avez déjà croisé ce terme de bundle quelquefois depuis le début du tutoriel, mais qu'est-ce qui se cache derrière ce terme ?

Pour faire simple, un bundle est une brique de votre application. Evident non ? :D Plus sérieusement, il s'agit vraiment de ça. Symfony2 utilise ce concept innovant qui consiste à regrouper dans un même endroit, le bundle, tout ce qui concerne une même fonctionnalité. Par exemple, on peut imaginer un bundle Blog dans notre site, qui regrouperait les contrôleurs, les modèles, les vues, les fichiers CSS et Javascript, etc. Tout ce qui concerne directement la fonctionnalité blog de notre site.

Cette organisation permet de découper naturellement nos fonctionnalités, et ainsi de ranger chaque fichier à sa place. Un fichier javascript n'est utilisé que sur le bundle blog ? Mettez le dans le bundle blog ! Bien évidemment, au sein d'un bundle, il faut retrouver également une architecture bien définie, nous l'étudions juste après.

Des exemples


Pour mieux visualiser, je vous propose quelques bons exemples de bundles possibles :
  • Un bundle Utilisateur, qui va gérer les utilisateurs ainsi que les groupes, intégrer des pages d'administration de ces utilisateurs, et des pages classiques comme le formulaire d'inscription, de récupération de mot de passe, etc.
  • Un bundle Blog, qui va fournir une interface pour gérer un blog sur le site. Ce bundle peut utiliser le bundle Membre pour faire un lien vers les profils des auteurs des articles et des commentaires.
  • Un bundle Boutique, qui va fournir des outils pour gérer des produits et des commandes.
  • Un bundle Admin, qui va fournir uniquement une interface vers les outils d'administration des différents bundles utilisés (membre, blog, etc.). Attention il ne doit pas y avoir beaucoup de code dans ce bundle, ce n'est qu'un raccourci vers les fonctionnalités d'administration des autres bundles. La partie admin pour ajouter un article au blog doit se trouver dans le bundle blog.
Et ces bundles, parce qu'ils respectent des règles communes, vont fonctionner ensemble. Par exemple, un bundle « Forum » et un bundle « Utilisateur » devront s'entendre : dans un forum, ce sont des utilisateurs qui interagissent. ;)

L'intérêt


Une question à toujours se poser : quel est l'intérêt de ce que l'on est en train de faire ?

En plus d'organiser votre code par fonctionnalités, la découpe en bundles permet... l'échange de bundles entre applications ! Cela signifie que vous pouvez développer une fonctionnalité, puis la partager avec d'autres développeurs ou encore la réutiliser dans un de vos autres projets. Et bien entendu, cela marche dans l'autre sens : vous pouvez installer dans votre projet des bundles qui ont été développés par d'autres !

Le principe même des bundles offre donc des possibilités infinies ! Imaginez le nombre de fonctionnalités classiques sur un site internet, que vous n'aurez plus à développer vous-mêmes. Vous avez besoin d'un livre d'or ? Il existe sûrement un bundle. Vous avez besoin d'un blog ? Il existe sûrement un bundle. Etc.

Les bundles de la communauté


Presque tous les bundles de la communauté Symfony2 sont regroupés sur un même site : http://knpbundles.com/. Il en existe beaucoup, et pour n'en citer que quelques uns :
  • FOSUserBundle : c'est un bundle destiné à gérer les utilisateurs de votre site. Concrètement, il fournit le modèle « utilisateur » ainsi que le contrôleur pour accomplir les actions de base (connexion, inscription, déconnexion, édition d'un utilisateur, etc.) et fournit aussi les vues qui vont avec. Bref, il suffit d'installer le bundle et de le personnaliser un peu pour obtenir un espace membre !
  • FOSCommentBundle : c'est un bundle destiné à gérer des commentaires. Concrètement, il fourni le modèle « commentaire » (ainsi que son contrôleur) pour ajouter, modifier et supprimer les commentaires. Les vues sont fournies avec, évidemment. Bref, en installant ce bundle, vous pourrez ajouter un fil de commentaires à n'importe quelle page de votre site !
  • GravatarBundle : c'est un bundle destiné à gérer les avatars depuis le service web Gravatar. Concrètement, il fournit une extension à Twig pour pouvoir afficher un avatar issu de Gravatar via une simple fonction qui s'avère être très pratique ;
  • etc.

Je vous conseille vivement de passer sur http://knpbundles.com/ avant de commencer à développer un bundle. S'il en existe déjà un et qu'il vous convient, il serait trop bête de réinventer la roue ;) . Bien sûr, il faut d'abord apprendre à installer un bundle externe, patience !

La structure d'un bundle


Un bundle contient tout : routes, contrôleurs, vues, modèles, classes personnelles, etc. Bref, tout ce qu'il faut pour remplir la fonction du bundle. Évidemment, tout cela est organisé en dossiers afin que tout le monde s'y retrouve. Voici la structure d'un bundle à partir de son répertoire de base, vous pouvez en voir l'illustration grâce au bundle exemple fourni par défaut dans src/Acme/DemoBundle/ :

Code : Autre
1
2
3
4
5
6
7
8
9
Controller/          | Contient vos contrôleurs.
DependencyInjection/ | Contient des informations sur votre bundle (chargement automatique de la configuration par exemple).
Entity/              | Contient vos modèles.
Form/                | Contient vos éventuels formulaires.
Resources/
-- config/             | Contient les fichiers de configuration de votre bundle (nous placerons les routes ici, par exemple).
-- public/             | Contient les fichiers publics de votre bundle : fichiers CSS et JavaScript, images, etc.
-- views/              | Contient les vues de notre bundle, les templates Twig.
Tests/               | Contient vos éventuels tests unitaires et fonctionnels. Nous développerons sans faire de tests au début.

La structure est assez simple au final, retenez la bien. Sachez qu'elle n'est pas du tout fixe, vous pouvez créer tous les dossiers que vous voulez pour mieux organiser votre code. Mais cette structure conventionnelle permet à d'autres développeurs de comprendre rapidement votre bundle. Bien entendu je vous guiderai pour chaque création de fichier ;) .
Vous connaissez maintenant les grands principes de Symfony2, et c'est déjà beaucoup !

Dans le prochain chapitre, nous allons créer notre première page. Cela nous permettra de manipuler bundles, routes, contrôleurs et vues. Bref, nous mettrons en pratique tout ce que nous venons de voir en théorie.

Rendez-vous au prochain chapitre.
Chapitre précédent Sommaire Chapitre suivant

Partager

7 commentaires pour "Vous avez dit Symfony2 ?"
Note moyenne : 3.75 / 4 (245 votes)
Pseudo Commentaire
Hors ligne Lookman Design # Posté le 30/07/2011 à 09:52:30
Webdesigner et joomla
Avatar

Joli tuto, je continue.
Merci pour cetravail
 
Hors ligne kraddle # Posté le 25/02/2012 à 15:51:45
Rire c'est pas sérieux
Avatar

Avis : Très bon

Bonjour Winzou,
Tout d'abord félicitations pour cet excellent travail. :)

Une question concernant les bundles :
Quelle est la procédure pour utiliser un bundle commun à d'autres bundles ?

Exemple: je crée un bundle "Commentaire" que je souhaite utiliser avec mes bundles blog et forum.

Dois-je nécessaire le basculer dans vendor/bundles/ ??

Merci pour ce tutoriel.
 
Hors ligne babasss # Posté le 03/03/2012 à 06:38:32

Avis : Très bon

je bossais sur la version 1.4 depuis un moment je vais me mettre à la version 2 en suivant ton tuto merci.
Hors ligne molinadiaz # Posté le 04/03/2012 à 05:19:06

Avis : Très bon

Merci pour ce tutoriel, winzou, qui se révèle très bien rédigé :)
 
Hors ligne Quadra # Posté le 11/03/2012 à 19:20:19
Avatar

Avis : Bon

Ville : Quessoy
Pays : France métropolitaine
Études : ESIR

Je viens de télécharger la version 2.0.11, et je ne vois pas de repertoire src, app et bin. C'est normal?

Voir tous les commentaires