Updated on
TP d'introduction à Symfony
Symfony est entre autres un framework Web. Il contient un ensemble de ressources qui facilitent la création d’applications Web utilisant le design pattern MVC (Model View Controller).
TP + Questions
Il y a 2 choses à faire dans ce TP :
- Suivre les étapes afin de réaliser le TP.
- Répondre en parallèle aux questions qui sont posées tout au long de l’énoncé. Les réponses sont à écrire dans le questionnaire Eureka se trouvant sur la page du cours.
Il est possible de travailler en binôme pour ce TP. En revanche, les réponses aux questions dans Eureka doivent être répondues par tout le monde.
Ce TP doit être versionné avec GIT et être partagé en utilisant la forge de l’université. Ne pas oublier d’ajouter les enseignants (pigne
et fournied
) au projet avec le status developper.
Une fois le projet créé sur la forge, envoyer un mail à Dominique Fournier dominique.fournier@univ-lehavre.fr et Yoann Pigné yoann.pigne@univ-lehavre.fr avec le titre “[L3 InfoWeb] TP intro Symfony
”. Ce mail indiquera les nom et prénom de chaque membre du groupe ainsi que l’URL du projet.
Installations préalables
Pour commencer à utiliser Symfony il faut installer composer
ainsi que le client symfony
.
Composer
Pour installer Composer on peut suivre les instructions en fonction de l’OS utilisé : https://getcomposer.org
Composer sur les machine de TP de l’UFR
- On télécharge composer avec la commande :
mkdir -p ${HOME}/.composer/bin wget https://raw.githubusercontent.com/composer/getcomposer.org/76a7060ccb93902cd7576b67264ad91c8a2700e2/web/installer -O - -q | php -- --install-dir=${HOME}/.composer/bin --filename=composer
- On ajoute la ligne suivante au fichier
${HOME}/.profile
:export PATH="$HOME/.composer/bin:$PATH"
- Enfin, on recharge l’environnement :
source ${HOME}/.profile
En ouvrant un autre terminal on risque de ne plus avoir accès à composer
. Il suffit de refaire la dernière commande : source ${HOME}/.profile
ou bien de redémarrer sa session.
Symfony
Pour installer Symfony on suit les instructions en fonction de l’OS utilisé : https://symfony.com/download
Symfony sur les machine de TP de l’UFR
- On télécharge la version binaire de symfony avec la commande :
wget https://get.symfony.com/cli/installer -O - | bash
- On ajoute la ligne suivante au fichier
${HOME}/.profile
:export PATH="$HOME/.symfony5/bin:$PATH"
- Enfin, on recharge l’environnement :
source ${HOME}/.profile
En ouvrant un autre terminal on risque de ne plus avoir accès à symfony
. Il suffit de refaire la dernière commande : source ${HOME}/.profile
ou bien de redémarrer sa session.
Création d’un premier projet
On crée de nouveaux projets Symfony avec la commande symfony
.
symfony new projet_hello --version=lts --webapp
cd projet_hello
GIT
Un git init
ainci que quelques commits ont été fait pour vous dans le projet. À vous d’ajouter ce projet dans la forge en ajoutant un remote
:
- Créer un projet sur la forge avec ajoutant les enseignants comme développeurs.
- Ajouter un
remote
dans le projet pour le connecter à un projet sur la forge:git remote add origin https://www-apps.univ-lehavre.fr/<utilisateur>/<projet>.git
où
<utilisateur>
est votre nom d’utilisateur de la forge et<projet>
est le nom de votre projet créé sur la forge. - Puis on pousse le projet sur la forge avec la commande :
git push -u origin master
Analyse du projet de base
Examiner attentivement le contenu du projet (dossier projet_hello
). les dossiers et sous-dossiers sont organisés de sorte à ne pas mélanger les choses qui n’ont rien à voir ensemble.
./
├── .env
├── .env.test
├── .git/
├── .gitignore
├── bin/
├── composer.json
├── composer.lock
├── config/
├── docker-compose.override.yml
├── docker-compose.yml
├── migrations/
├── phpunit.xml.dist
├── public/
├── src/
├── symfony.lock
├── templates/
├── tests/
├── translations/
├── var/
└── vendor/
Le dossier config/
contient les paramètres de l’application. On modifiera ce dossier pour configurer l’application ou changer son comportement par défaut (e.g.: chargement de modules complémentaires).
Le dossier src/
contient les sources de notre application. C’est le dossier qui nous intéresse le plus ici.
Le dossier templates
contient les fichiers templates (les patrons) TWIG pour faciliter la génération de pages Web.
Le dossier tests/
contient comme on s’en doute, les tests.
Questions 1, 2, 3 et 4
Répondre aux questions suivantes sur le questionnaire se trouvant sur Eureka :
- En examinant le contenu des fichiers et en cherchant sur le site de Symfony, expliquer l’utilité du dossier
vendor/
. - En examinant le contenu des fichiers et en cherchant sur le site de Symfony, expliquer l’utilité du dossier
public/
. - En examinant le contenu des fichiers et en cherchant sur le site de Symfony, expliquer l’utilité du dossier
assets/
. - Quel fichier dois-je modifier pour configurer les identifiants de bases de données afin que Symfony puisse accéder à la Base de données ?
Démarrer l’application
L’étape suivante est de démarrer l’application. On utilise le serveur web interne de PHP plutôt qu’Apache pour le développement.
symfony server:start
On peut voir le site dans un navigateur, à l’adresse http://localhost:8000.
Contrôleur Action et Route
La page visible a l’adresse http://localhost:8000/
est une page par défaut, elle correspond à une route et à une action dans le contrôleur par défaut.
Ces 3 termes sont importants :
- Un contrôleur est la classe principale qui gère un ensemble d’actions.
- Une action est une méthode de classe du contrôleur, c’est un peu comme un des services possibles proposés par le contrôleur.
- Une route est la partie qui vient après le nom de domaine dans une URL au sens de HTTP. Par exemple dans l’URL
https://www.example.com/truc/machin
, la route est/truc/machin
.
Il faut configurer le contrôleur pour que ses actions soient liées à des routes.
Création d’un contrôleur
Nous allons créer un contrôleur des actions et des routes associées.
Créer un nouveaux fichier "src/Controller/HelloController.php"
avec le contenu suivant :
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
class HelloController extends AbstractController
{
#[Route("/helloRandom")]
public function randomNameAction(): Response
{
return new Response(
"<html><body><h1>Hello " .
self::generateRandomName() .
"</h1></body></html>"
);
}
static function generateRandomName(): string
{
$nouns = [
"Circle", "Cone", "Cylinder", "Ellipse", "Hexagon",
"Irregular Shape", "Octagon", "Oval", "Parallelogram",
"Pentagon", "Pyramid", "Rectangle", "Semicircle", "Sphere",
"Square", "Star", "Trapezoid", "Triangle", "Wedge", "Whorl",
];
$adjectives = [
"Amusing", "Athletic", "Beautiful", "Brave", "Careless",
"Clever", "Crafty", "Creative", "Cute", "Dependable",
"Energetic", "Famous", "Friendly", "Graceful", "Helpful",
"Humble", "Inconsiderate", "Likable", "Mid Class", "Outgoing",
"Poor", "Practical", "Rich", "Sad", "Skinny", "Successful", "Thin",
"Ugly", "Wealth",
];
return $adjectives[array_rand($adjectives)] .
" " .
$nouns[array_rand($nouns)];
}
}
On peut voir fonctionner ce nouveau contrôleur avec l’URL : http://localhost:8000/helloRandom et recharger la page plusieurs fois…
Question 5
Comment fait-on le lien entre une route (URL) de l’application et une action d’un contrôleur ?
Lancer les tests
Il faut maintenant tester ce contrôleur. Écrire le fichier de test tests/Controller/HelloControllerTest.php
(il faut créer le dossier Controlleur/
dans tests/
s’il n’existe pas):
<?php
namespace App\Tests\Controller;
use App\Controller\HelloController;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class HelloControllerTest extends WebTestCase
{
public function testHelloRandomRoute()
{
$client = static::createClient();
$crawler = $client->request("GET", "/helloRandom");
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertStringContainsString("Hello ", $crawler->filter("h1")->text());
}
function testRandomNameGenerator()
{
$rdName = HelloController::generateRandomName();
$this->assertGreaterThan(1, strlen($rdName));
}
}
On exécute les tests avec PHPUnit
(l’équivalent du JUnit
de Java
pour PHP
):
php bin/phpunit
On devrait avoir :
OK (2 tests, 3 assertions)
Questions 6
Dans la classe de test HelloControllerTest
expliquer ce que fait la méthode testHelloRandomRoute
.
Questions 7
Dans la classe de test HelloControllerTest
expliquer ce que fait la méthode testRandomNameGenerator
.
Route et action paramétriques
On souhaite créer une action qui dépende des paramètres de la route (une route paramétrique).
Ajouter la méthode suivante à la classe HelloController
:
#[Route("/hello/{name}", defaults: ["name" => ""])]
public function nameAction($name): Response
{
if ($name == "") {
$name = self::generateRandomName();
}
return new Response("<html><body><h1>Hello $name</h1></body></html>");
}
Exécuter cette méthode avec la route : http://localhost:8000/hello/Albus Perceval Wulfric Brian Dumbledore
Tester la route
Écrire un test dans la classe HelloControllerTest
qui vérifie que la méthode fonctionne comme prévu. Vérifier que la page web générée salue bien le Professeur Dumbledore quand son nom est passé dans l’URL. Vérifier aussi que le nom est aléatoire quand aucun paramètre n’est donné (http://localhost:8000/hello).
Questions 8
Coller votre classe de test HelloControllerTest
dans le questionnaire Eureka (Question 8).
Création d’une vue
On souhaite maintenant générer des pages Web complètes et pas seulement une chaîne de caractères passée dans l’objet Response
.
Symfony utilise le langage de template twig
.
la méthode render()
du contrôleur permet d’utiliser un template twig
pour fabriquer une réponse et retourner un objet Response
.
Ouvrir et lire les fichiers templates/base.html.twig
.
Créer un template pour le contrôleur Hello dans le fichier templates/hello.html.twig
:
{% extends 'base.html.twig' %}
{% block title %}Hello!{% endblock %}
{% block body %}
<div id="container">
<div id="hello">
<h1> Hello <i>{{ name }}</i>!</h1>
</div>
</div>
{% endblock %}
{% block stylesheets %}
<style>
body { background: #F5F5F5; font: 18px/1.5 sans-serif; }
h1, h2 { line-height: 1.2; margin: 0 0 .5em; color: #4343AA;}
h1 { font-size: 36px; }
#container { background: #FFF; margin: 1em auto; max-width: 800px; width: 98%; padding: 2em; box-sizing: border-box;}
@media (min-width: 768px) {
#container { margin: 2em auto; }
}
</style>
{% endblock %}
Modifier l’action nameAction
du contrôleur HelloController
afin d’utiliser le template qui vient d’être créé. On s’inspirera de la documentation en ligne.
Questions 9
Copier le code de l’action nameAction
dans la question 9 du questionnaire Eureka.
Sessions
On souhaite que l’application se souvienne de nous. À chaque fois que l’action nameAction
est appelée avec un paramètre (avec un nom), on veut qu’il soit sauvegardé dans une session (en remplaçant éventuellement celui qui existait déjà). À chaque fois que l’action nameAction
est appelée sans paramètre, alors on veut retrouver le paramètre précédemment enregistré dans la session. Finalement si nameAction
est appelé sans paramètre pour la première fois (rien d’existe dans la session), alors on génère un nom aléatoirement, que l’on sauvegarde dans la session.
Par exemple, si j’appelle une fois (http://localhost:8000/hello/You) cela va afficher "Hello You!"
. Si ensuite j’appelle (dans le même navigateur) (http://localhost:8000/hello) cela doit également afficher "Hello You!"
. En revanche si j’appelle pour la première fois l’action sans paramètres (http://localhost:8000/hello), alors on obtient un nom aléatoire qui va être stocké pour les appels futurs.
Modifier l’action nameAction
pour qu’elle se comporte comme décrit ci-dessus, en utilisant la documentation Symfony sur les sessions.
Question 10
A quoi sert le fichier composer.json
qui se trouve à la racine du projet ?
Questions 11
Copier le code de nameAction
dans Eureka (Question 11).
Écrire de nouveaux tests (en ajoutant des méthodes dans la classe tests/Controller/HelloControllerTest.php
) pour vérifier le nouveau fonctionnement.
Questions 12
Copier le code de ces tests dans Eureka (Question 12).