Skip to content

1. Introduction

Le PDF du document est |ICI|.

Les codes du document sont |ICI|.

Ce document est un produit de l'IA Claude d'Anthropic. Il fait suite au document Introduction étape par étape au framework web [Laravel] (2026), qui faisait lui-même suite aux documents Introduction étape par étape au framework web [Flask], Introduction étape par étape au framework web [Spring MVC], Introduction étape par étape au framework web [ASP.NET Core MVC] et Introduction étape par étape au framework web [NestJS] (2026). Le présent document reste dans le monde [PHP], mais change de framework :

  • le framework [Laravel] est remplacé par le framework [Symfony] 8.1, toujours avec le langage [PHP] (version 8.4 ou plus récente) ;
  • les vues [Blade] sont remplacées par des vues [Twig], le moteur de vues de [Symfony] ;
  • la validation par les règles de [Laravel] et les requêtes de formulaire ([FormRequest]) est remplacée par le composant Validator de [Symfony] (des contraintes, écrites comme des attributs [PHP]) et par son composant Form, qui décrit les formulaires par des classes ;
  • les gardes, les middlewares et les [Gate] de [Laravel] sont remplacés par le composant Security de [Symfony] : pare-feu, authentificateurs, rôles, hachage des mots de passe, limiteur de tentatives, complété par la bibliothèque [firebase/php-jwt] pour les jetons JWT ;
  • les middlewares, eux, n'existent pas dans [Symfony] : on intervient dans le traitement des requêtes par des écouteurs d'événements ;
  • l'ORM [Eloquent] est remplacé par [Doctrine], l'ORM de [Symfony], toujours avec une base [MySQL].

Le document suit exactement la progression du cours [Laravel] : d'abord de nombreux petits projets, chacun centré sur une notion, puis une étude de cas complète, une application web de prise de rendez-vous pour un cabinet de médecins, dont tous les fichiers sont commentés. Les exemples portent les mêmes numéros et traitent les mêmes sujets que dans les cours [Laravel], [Flask], [Spring MVC] et [ASP.NET Core MVC] : un lecteur qui connaît l'un de ces cours peut comparer les frameworks exemple par exemple. Ce n'est pourtant pas nécessaire : ce document se lit seul, et ne suppose aucune connaissance de ces frameworks. On suppose seulement connues les bases de la programmation web (le protocole HTTP, le langage HTML) et celles du langage [PHP] (variables, tableaux, fonctions, classes). Le cours Introduction au langage PHP7 par l'exemple (2019) présente le langage lui-même, pour qui aurait besoin de le découvrir d'abord ; les nouveautés de [PHP] 8 utilisées ici (propriétés promues, classes [readonly], attributs, énumérations, arguments nommés, opérateur nullsafe...) sont expliquées à leur première apparition.

1.1. La place de Symfony dans une application web

Une application web est souvent construite en couches, chaque couche ne parlant qu'à ses voisines :

Image

  • la couche web reçoit les requêtes HTTP du navigateur et lui renvoie des pages HTML. C'est elle que [Symfony] nous aide à écrire ;
  • la couche métier contient les règles de gestion de l'application (« un patient ne peut avoir qu'un rendez-vous à venir », par exemple). Elle ignore tout du web : elle pourrait aussi bien servir une application en ligne de commande ;
  • la couche d'accès aux données (couche DAO, pour Data Access Object) lit et écrit dans la base de données. Nous utiliserons [Doctrine], l'ORM (Object Relational Mapper) associé à [Symfony], qui fait correspondre les lignes des tables et des objets [PHP].

La couche web suit elle-même le modèle MVC (Model - View - Controller) :

  • le contrôleur (C) est une classe [PHP] dont les méthodes, appelées actions, traitent chacune un type de requête (par exemple [GET /agenda]). Une action lit les paramètres de la requête, fait travailler la couche métier, puis choisit la vue à afficher ;
  • le modèle (M) est l'ensemble des données que l'action transmet à la vue ;
  • la vue (V) est un fichier [Twig] (extension [.html.twig]) : une page HTML qui contient des expressions [{{ ... }}] et des instructions [{% if %}], [{% for %}]..., que le moteur [Twig] remplace par les données du modèle.

Une remarque de vocabulaire, pour éviter une confusion : dans [Symfony], les classes qui représentent les tables d'une base de données s'appellent des entités (dossier [src/Entity]). Le mot modèle désignera donc toujours, dans ce document, le modèle de la vue (les données transmises à une vue), ou, au chapitre 2, le modèle de l'action (les données qu'elle reçoit). Le mot gabarit désigne la vue commune dont les autres pages héritent (chapitre sur les vues).

Le traitement d'une requête suit les étapes numérotées du schéma :

  • 1 : le navigateur envoie une requête HTTP, par exemple [GET /agenda?idMedecin=1&jour=2026-09-26] ;
  • 2 : le serveur web reçoit la requête et la confie à l'application [Symfony], par le fichier [public/index.php]. Pendant le développement, ce serveur est celui qu'intègre [PHP], lancé par la commande [php -S localhost:8000 -t public] ; en production, ce sera un serveur comme [nginx] ou [Apache], associé à [PHP-FPM]. Le fichier [public/index.php] confie la requête au noyau (kernel) de l'application, qui la fait passer par une suite d'événements : des classes de [Symfony] et de l'application, les écouteurs, y interviennent (la session, la sécurité, la langue...). L'un d'eux compare le chemin demandé aux routes de l'application et choisit l'action chargée de cette requête : c'est le routage ;
  • 3 : l'action demande à la couche métier les données dont elle a besoin ; la couche métier s'adresse, si nécessaire, à la couche DAO, qui interroge la base [MySQL] en SQL ;
  • 4 : l'action construit le modèle M de la vue et demande au moteur [Twig] de fabriquer la page (méthode [render]) ;
  • 5 : la page HTML fabriquée par la vue est la réponse de l'action, que [Symfony] renvoie au navigateur.

[Symfony] est, avec [Laravel], l'un des deux grands frameworks web du monde [PHP]. Gratuit et libre, créé en 2005 par Fabien Potencier (et la société française SensioLabs), il fonctionne partout où fonctionne [PHP] ([Windows], [Linux], [macOS]), et [PHP] fonctionne chez presque tous les hébergeurs web. [Symfony] est d'abord un ensemble d'une cinquantaine de composants, des bibliothèques indépendantes (les requêtes et réponses HTTP, le routage, la console, les formulaires, la validation, la sécurité...), si réputées que d'autres projets les utilisent : [Laravel] lui-même est bâti sur plusieurs d'entre eux, et le lecteur du cours précédent les a déjà croisés. Le framework [Symfony] assemble ces composants, grâce à des bundles (des paquets d'intégration) et à un conteneur de services qui fabrique les objets de l'application. Par rapport à [Laravel], [Symfony] fait des choix nets : pas de façades ni de fonctions globales, mais des services reçus par injection de dépendances ; une configuration explicite, dans des fichiers YAML ; des attributs [PHP] ([#[Route]], [#[Assert\NotBlank]]...) pour décrire le code ; un ORM, [Doctrine], qui sépare les objets de leur enregistrement. C'est un framework réputé pour sa rigueur, sa documentation, et sa politique de versions : une version mineure tous les six mois, une version « à support long » tous les deux ans, et la garantie qu'une application sans avertissement d'obsolescence passe sans modification à la version majeure suivante. [Symfony] sait fabriquer aussi bien des serveurs qui renvoient du JSON à un client [JavaScript] ([Angular], [React], [Vue.js], [Flutter]...) que des applications web classiques, où c'est le serveur qui fabrique les pages HTML, le navigateur se contentant de les afficher. C'est ce second usage qu'étudie ce document.

Une particularité de [PHP] explique beaucoup de choses dans [Symfony] : l'application est reconstruite à chaque requête, puis oubliée (exemple 01). [Symfony] compense ce coût en compilant sa configuration une fois pour toutes en code [PHP], rangé dans un cache (dossier [var/cache]). Nous y reviendrons souvent.

1.2. Les outils utilisés

Les exemples ont été écrits et testés avec les outils suivants (leur installation est décrite en annexe) :

  • [PHP] 8.4 (toute version 8.4 ou plus récente convient), avec les extensions [intl], [mbstring], [openssl] et [pdo_mysql] ;
  • [Composer] 2, le gestionnaire de bibliothèques de [PHP] ;
  • l'éditeur [Visual Studio Code], avec les extensions [PHP Intelephense] (l'analyse du code), [Twig Language 2] (les vues) et [YAML] (les fichiers de configuration) ;
  • un navigateur récent ([Chrome], [Firefox], [Edge]) ;
  • l'outil en ligne de commande [curl], qui affiche les réponses HTTP brutes (il est livré avec [Windows] 10 et 11) ;
  • le SGBD [MySQL] (ou [MariaDB]), par exemple celui de [Laragon] sous [Windows], à partir du chapitre sur l'accès aux données, et pour l'étude de cas. Sous [Windows], [Laragon] installe en une fois [PHP], [Composer] et [MySQL].

[Symfony] et les autres bibliothèques ne font pas partie de [PHP] : [Composer] les télécharge depuis le dépôt [Packagist] lors de l'installation (il faut donc être connecté à Internet ce jour-là), et les range dans un dossier [vendor]. Chaque projet décrit ses bibliothèques dans un fichier [composer.json]. Le tableau suivant présente les principales, avec les versions utilisées :

[symfony/framework-bundle]
le framework : noyau, routage, contrôleurs, conteneur de services, configuration, session, cache ; il installe les composants dont il a besoin ([symfony/http-foundation], [symfony/http-kernel], [symfony/routing], [symfony/dependency-injection]...)
8.1.7
[symfony/twig-bundle], [twig/twig]
les vues [Twig] (chapitre sur les vues)
8.1.7, 3.30.0
[symfony/validator], [symfony/form]
la validation (à partir de l'exemple 08) et les formulaires (à partir de l'exemple 17)
8.1.7
[symfony/security-bundle]
l'authentification et les autorisations (chapitre sur la sécurité)
8.1.7
[symfony/translation]
les traductions (exemples 09 et 22)
8.1.7
[doctrine/orm], [doctrine/dbal], [doctrine/doctrine-bundle]
l'accès aux bases de données (exemple 28 et étude de cas)
3.7.2, 4.5.0, 3.3.2
[firebase/php-jwt]
les jetons JWT (chapitre sur l'authentification)
7.2.0

[Symfony] s'installe d'ordinaire en créant un projet complet, par la commande :

composer create-project symfony/skeleton mon-projet

ou par l'outil en ligne de commande de [Symfony] (le programme [symfony], cf. annexes) : [symfony new mon-projet --webapp]. [Composer] télécharge alors le squelette d'une application [Symfony], puis ses bibliothèques. Le squelette contient aussi [Symfony Flex], un greffon de [Composer] qui, à chaque installation d'une bibliothèque ([composer require twig]), écrit lui-même ses fichiers de configuration à partir de recettes publiées en ligne. C'est ainsi que l'on commence un vrai projet. Pour apprendre, cette méthode a un inconvénient : les fichiers apparaissent d'eux-mêmes, sans que l'on sache à quoi ils servent. Les exemples de ce document partent donc de l'autre bout : l'exemple 01 est la plus petite application [Symfony] possible, et chaque exemple n'ajoute que les fichiers dont il a besoin, écrits et commentés à la main. L'étude de cas, à la fin, a la structure d'une application [Symfony] ordinaire.

1.3. Exécuter l'étude de cas

1.3.1. Installation de Laragon

L’étude de cas a besoin du SGBD MySQL, d’un interpréteur PHP, de l’installateur de packages PHP [composer]. Laragon peut apporter tout cela et plus. En septembre 2026, Laragon est disponible à l’URL [Download Laragon – Fast & Modern Dev Environment ]. Laragon amène avec lui des outils qui permettent d’installer un serveur PHP et le SGBD [MySQL] :

Image

  • en [1], un serveur web Apache ;
  • en [2], le SGBD [MySQL] ;
  • en [3], un outil de messagerie que nous n’utiliserons pas ;
  • en [4], lance tous les services (Apache, [MySQL], MailPit) ;
  • en [5], affiche la page web d’URL [http://localhost]. Par défaut, cette URL désigne le dossier <laragon-install>\www où <laragon-install> est le dossier d’installation de Laragon ;
  • en [6], lance l’Outil HeidiSQL qui permet de gérer des bases de données MySQL. C’est avec cet outil que nous créerons la base de données utilisée par le serveur de calcul de l’impôt ;
  • en [7], ouvre un terminal dans lequel tous les binaires utiles à Laragon sont dans le PATH ;
  • en [8], ouvre un explorateur windows dans le dossier associé à l’URL [http://localhost] ;

Le dossier d’installation de Laragon comporte les éléments suivants :

 
  • En [1], le dossier [bin] contient de nombreuses applications :
  • En [1], le serveur web Apache ;
  • en [2], un terminal de commandes ;
  • en [3], un client [git] permettant de versionner les différentes versions d’un projet ;
  • en [4], un gestionnaire de bases de données ;
  • en [5], un gestionnaire courrier ;
  • en [6], le SGBD [MySQL] ;
  • en [7], un autre serveur web ;
  • en [8], [node.js] pour exécuter des scripts Javascript ;
  • en [9], un éditeur de texte ;
  • en [10], l’interpréteur PHP ;
  • en [11], l’interpréteur [Python] ;
  • en [12], un serveur de cache ;

Laragon ramène avec lui un environnement de développement conséquent. Dans ce cours, nous utiliserons :

  • le SGBD [MySQL] [6] et l’outil [heidisql] pour le gérer graphiquement ;
  • l’interpréteur PHP 8.5 ;
  • l’installateur de packages [composer] ;

Le README de l’étude de cas indique qu’on doit taper dans un terminal les commandes suivantes :

composer install

pour installer les packages PHP nécessaires aux exemples et à l’étude de cas.

php -S localhost:8000 -t public

pour exécuter soit un des exemples, soit l’étude de cas. Si vous utilisez un terminal [PowerShell] dans VSCode vous rencontrerez le problème suivant : ni [composer], ni [php] ne sont dans le PATH de la machine Windows après l’installation de Laragon. Ces commandes ne seront donc pas reconnues dans un terminal VSCode.

Pour inclure [composer] et [php] dans le PATH de la machine Windows, ouvrez un terminal PowerShell en mode [administrateur] puis tapez les commandes suivantes :


[Environment]::SetEnvironmentVariable("Path",[Environment]::GetEnvironmentVariable("Path", "Machine") + ";C:\laragon\bin\composer","Machine")

[Environment]::SetEnvironmentVariable("Path",[Environment]::GetEnvironmentVariable("Path", "Machine") + ";C:\laragon\bin\php\php-8.5.11-nts-Win32-vs17-x64","Machine")

Adaptez les deux chemins surlignés à votre environnement.

Vous aurez à relancer VSCode pour que ces modifications soient prises en compte.

Pour créer la base de données [MySQL] nécessaire à l’étude de cas, nous procédons de la façon suivante :

 
  • En [1], tous les services doivent être lancés ;
  • en [2], l’option [Database] vous permet de gérer la base de données ;

L’option [Database] lance un utilitaire appelé HeidiSQL :

  • En [1], vous pouvez sélectionner divers SGBD. La valeur par défaut proposée est le SGBD MySQL. Cela convient ;
  • en [2], vous ouvrez une session de HeidiSQL ;
  • En [1-2], exécutez un fichier SQL puis choisissez le fichier [dbrdvmedecins2.sql] que vous trouverez dans le dossier [symfony-sept-202-] :

Image

L’exécution du fichier [3] va créer la base [dbrdvmedecins2] utilisée par l’étude de cas. Pour le voir, faites F5 dans HeidiSQL pour rafraîchir l’affichage :

Note du réviseur : les copies d’écran qui suivent montrent une base de données [dbrdvmedecins] alors que la base de données de l’étude de cas s’appelle [dbrdvmedecins2]. Les deux bases sont quasi identiques et on a donc estimé qu’il était inutile de refaire des copies d’écran.

Fin de note

Image

La base de données [dbrdvmedecins] a été créée. On peut en voir le contenu :

Image

  • en [1-3], la table [clients] ;
    • [id] est la clé primaire de la table ;
    • [version] est le numéro de version de la ligne. Ce numéro augmente à chaque modification de la ligne ;
    • [titre, nom, prenom] identifient la personne ;

Image

  • en [1-3], la table [medecins] ;
    • [id] est la clé primaire de la table ;
    • [version] est le numéro de version de la ligne ;
    • [titre, nom, prenom] identifient la personne ;

Image

  • en [1-3], la table des créneaux horaires de consultation des médecins :
    • [id] : clé primaire ;
    • [version] : numéro de version de la ligne ;
    • [id-medecin] : clé étrangère ciblée sur la clé primaire du médecin ;
    • [hdebut, mdebut] : heure et minutes de début de la consultation. Ainsi [8,20] signifie 8h20.
    • [hfin, mfin] : heure et minutes de fin de la consultation.

Image

  • En [1-3], la table [rv] des rendez-vous pris ;
    • [id] : clé primaire ;
    • [version] : numéro de version ;
    • [jour] : jour du rendez-vous ;
    • [id_creneau] : clé étrangère vers la clé primaire du créneau horaire du rendez-vous. Comme un créneau horaire est lié à un médecin, on sait quel médecin assure ce rendez-vous ;
    • [id_client] : clé étrangère vers le numéro (clé primaire) du client qui consulte ;

Image

  • en [1-3], la table [users] qui liste les utilisateurs autorisés à utiliser l’application [NestJS] ;
    • [id, version] : clé primaire, numéro de version ;
    • [login, password] : identifiants de l’utilisateur ;
    • [nom] : nom donné à l’utilisateur ;
    • [role] : son rôle. [ADMIN] a tous les droits. [USER] n’a que des droits de lecture. Il pourra consulter l’agenda d’un médecin mais pas prendre / annuler un rendez-vous ;

1.3.2. Exécution de l’étude de cas

Note du réviseur : je conseille au lecteur d'exécuter immédiatement l'étude de cas comme il est indiqué dans ce qui suit. Une fois bien compris le rôle de cette application de rendez-vous, demander à son IA favorite de modifier l'application dans le sens suivant : désormais chaque médecin pourra :

  • fixer lui-même les créneaux de consultation entre deux dates. Cela lui permettra de modifier ses horaires selon ses besoins ;
  • supprimer dans l'agenda d'un jour donné certains créneaux : indisponible pour raisons personnelles par exemple ;

La modification n'est pas simple parce qu'elle implique un changement de structure de la base de données. Demandez à l'IA de vous fournir le nouveau code de l'application et le script SQL pour créer la nouvelle base de données. Pour cela, vous aurez besoin de lui fournir le zip du projet complet ainsi que le script SQL de l'ancienne base de données.

Par ailleurs, je n'ai pas révisé le cours produit par Claude. Il avait déjà produit des cours [NestJS], [ASP.NET Core MVC], [Spring MVC] et [Flask] parfaits. J'ai supposé qu'il en était de même pour celui-ci. Si vous butez sur un obstacle de compréhension, la solution est toujours la même : demandez à votre IA favorite de vous expliquer ce que vous ne comprenez pas. Claude, par exemple, fait ça très bien. Vous aurez peut-être besoin de lui "uploader" l'exemple que vous ne comprenez pas.

Fin de note.

L'étude de cas qui termine ce document est une application complète. Le lecteur voudra sans doute la voir fonctionner avant d'entrer dans le détail du framework : voici comment l'exécuter. Elle se trouve dans le dossier [rdvmedecins2-symfony], à côté du dossier [exemples] :

1
2
3
symfony-sept-2026/
├── exemples/
└── rdvmedecins2-symfony/

Il faut avoir installé [PHP] (8.4 ou plus récent), [Composer], [Visual Studio Code] et [MySQL] (cf. annexes). Puis :

  • créer la base de données [dbrdvmedecins2], en exécutant le script [rdvmedecins2-symfony/database/dbrdvmedecins2.sql]. Avec [Laragon], on ouvre l'outil [HeidiSQL] (bouton Base de données), puis on exécute le script par le menu Fichier / Exécuter un fichier SQL. En ligne de commande, depuis le dossier [rdvmedecins2-symfony] :
mysql -u root < database/dbrdvmedecins2.sql
  • ouvrir le dossier [rdvmedecins2-symfony] dans [Visual Studio Code] (menu Fichier / Ouvrir le dossier), puis un terminal (menu Terminal / Nouveau terminal) ;
  • installer les bibliothèques de l'application : [Composer] lit le fichier [composer.json], télécharge [Symfony] et les autres bibliothèques, et les range dans le dossier [vendor] de l'application (quelques dizaines de secondes) :
composer install
  • vérifier la connexion à la base. L'application se connecte à [MySQL] sur [127.0.0.1], port 3306, avec l'utilisateur [root] sans mot de passe (les réglages par défaut de [Laragon]). Si votre compte [root] a un mot de passe, indiquez-le dans le fichier [.env] de l'application, dans la ligne [DATABASE_URL] : [mysql://root:monMotDePasse@127.0.0.1:3306/dbrdvmedecins2...] ;
  • lancer l'application :
php -S localhost:8081 -t public
  • [PHP] affiche :
[Sun Sep 27 18:40:12 2026] PHP 8.4.21 Development Server (http://localhost:8081) started

Le serveur de développement écoute sur le port 8081 de la machine ([localhost]). Chaque requête reçue sera signalée dans la console, ainsi que les messages de [Symfony] (la route choisie, les ordres SQL envoyés à la base) ;

  • ouvrir l'adresse [http://localhost:8081] dans un navigateur :

Image

  • se connecter avec l'un des comptes de démonstration, dont le mot de passe est le login : [admin] (administrateur), [pelissier], [tatou], [dupont] (médecins), [martin], [durand], [bistrou], [german] (patients). Il faut aussi recopier les caractères de l'image, en majuscules ou en minuscules.

Une application [PHP] ne lit pas la base à son démarrage : une erreur de connexion n'apparaît qu'à la première page qui interroge la base, c'est-à-dire à la connexion. [Symfony] affiche alors sa page d'erreur détaillée, et écrit l'erreur dans la console du serveur. Avec le message [SQLSTATE[HY000] [2002] Connection refused], c'est que [MySQL] n'est pas démarré ; avec [[1045] Access denied for user 'root'@'localhost'], que le mot de passe est incorrect ; avec [[1049] Unknown database 'dbrdvmedecins2'], que le script SQL n'a pas été exécuté ; avec [could not find driver], que l'extension [pdo_mysql] de [PHP] n'est pas activée. Si la page affiche [Failed opening required '.../vendor/autoload_runtime.php'], c'est que [composer install] n'a pas été exécuté ; si la commande [php -S] échoue avec le message [Failed to listen on localhost:8081 (reason: Address already in use)], c'est que le port 8081 est déjà occupé (par une autre version de l'application, par exemple). Le fichier [README.md] de l'application décrit d'autres cas. On arrête l'application par [Ctrl-C] dans le terminal.

L'étude de cas, à la fin du document, présente l'utilisation de l'application, puis commente chacun de ses fichiers.

1.4. Les exemples

Les exemples sont rangés dans le dossier [exemples], un sous-dossier par exemple :

exemples/
├── 01-structure/
├── 02-routage/
├── ...
├── 28-couches/
├── commun/
│   ├── bootstrap/
│   ├── BootstrapController.php
│   └── README.md
└── composer.json

Chaque exemple est une petite application [Symfony], que l'on exécute seule. Tous les exemples utilisent les mêmes bibliothèques, décrites par le fichier [exemples/composer.json] :

{
    "name": "cours/symfony-exemples",
    "description": "Les 28 exemples du cours [Introduction étape par étape au framework web Symfony] : un seul dossier vendor, partagé par tous les exemples",
    "type": "project",
    "license": "MIT",
    "require": {
        "php": ">=8.4",
        "ext-intl": "*",
        "ext-pdo_mysql": "*",
        "doctrine/doctrine-bundle": "^3.3",
        "doctrine/orm": "^3.7",
        "firebase/php-jwt": "^7.2",
        "symfony/asset": "^8.1",
        "symfony/console": "^8.1",
        "symfony/dotenv": "^8.1",
        "symfony/form": "^8.1",
        "symfony/framework-bundle": "^8.1",
        "symfony/intl": "^8.1",
        "symfony/lock": "^8.1",
        "symfony/rate-limiter": "^8.1",
        "symfony/security-bundle": "^8.1",
        "symfony/serializer": "^8.1",
        "symfony/translation": "^8.1",
        "symfony/twig-bundle": "^8.1",
        "symfony/validator": "^8.1",
        "symfony/yaml": "^8.1",
        "twig/intl-extra": "^3.30",
        "twig/twig": "^3.30"
    },
    "autoload": {
        "psr-4": {
            "Commun\\": "commun/"
        }
    },
    "config": {
        "optimize-autoloader": true,
        "sort-packages": true
    },
    "minimum-stability": "stable",
    "prefer-stable": true
}
  • lignes 6-29 : ce dont les exemples ont besoin : [PHP] 8.4 ou plus récent, les extensions [intl] (la mise en forme des nombres et des dates selon la langue, exemple 16) et [pdo_mysql] (l'accès à [MySQL], exemple 28), puis les bibliothèques, par ordre alphabétique : [Doctrine] (exemple 28), [firebase/php-jwt] (les jetons JWT, exemple 25), et les composants et bundles de [Symfony] dont les exemples se servent. [^8.1] se lit « la version 8.1, ou une version plus récente de la version majeure 8 » ;
  • lignes 30-34 : les classes de l'espace de noms [Commun] sont dans le dossier [commun] (la règle PSR-4, présentée à l'exemple 01) : c'est le contrôleur partagé qui sert [Bootstrap] (exemple 15) ;
  • les autres lignes règlent le comportement de [Composer] : le chargeur de classes est optimisé, les bibliothèques sont triées par nom, et seules les versions stables sont acceptées.

Pour exécuter les exemples, on installe d'abord leurs bibliothèques, une fois pour toutes, dans un terminal ouvert sur le dossier [exemples] :

composer install

[Composer] crée le dossier [exemples/vendor], partagé par les 28 exemples, et le fichier [composer.lock], qui note les versions exactes installées (cf. étude de cas). Le dossier [commun] contient le framework CSS [Bootstrap] ([commun/bootstrap]), partagé par les exemples qui mettent leurs pages en forme (à partir de l'exemple 15), et le contrôleur qui le sert ([commun/BootstrapController.php], cf. exemple 15).

Les exemples ont presque tous la même structure, celle d'une application [Symfony] ordinaire, réduite à l'essentiel. Par exemple, celle de l'exemple 13 :

13-premiere-vue/
├── bin/
│   └── console
├── config/
│   ├── packages/
│   │   ├── framework.yaml
│   │   └── twig.yaml
│   ├── bundles.php
│   ├── routes.yaml
│   └── services.yaml
├── public/
│   └── index.php
├── src/
│   ├── Controller/
│   │   └── VuesController.php
│   ├── Modele/
│   │   └── PageModele.php
│   └── Kernel.php
├── templates/
│   └── vues/
│       ├── inconnu.html.twig
│       └── index.html.twig
├── var/
├── .env
└── composer.json
  • [public/index.php] : le point d'entrée de toutes les requêtes ; [src/Kernel.php] : le noyau de l'application ; [bin/console] : l'outil en ligne de commande de [Symfony] (exemple 01) ;
  • [config] : la configuration : les bundles de l'application ([bundles.php]), la configuration de chacun (dossier [packages]), les routes ([routes.yaml], exemple 02), les services ([services.yaml], exemple 06) ;
  • [src] : les classes de l'application : contrôleurs ([src/Controller]), modèles, services... ;
  • [templates] : les vues [Twig] (à partir du chapitre sur les vues) ;
  • [.env] : les réglages propres à l'exemple (exemple 01) ; [var] : les fichiers que [Symfony] écrit lui-même (le cache, la session).

Pour exécuter un exemple, on ouvre un terminal sur son dossier (dans [Visual Studio Code] : clic droit sur le dossier de l'exemple, puis Ouvrir dans le terminal intégré), et on tape :

php -S localhost:8000 -t public

Tous les exemples écoutent sur le port 8000 : on ne peut en exécuter qu'un à la fois (ou il faut changer le port : [php -S localhost:8001 -t public]). On arrête le serveur par [Ctrl-C] dans le terminal. Il n'est pas nécessaire de relancer le serveur après une modification d'un fichier [PHP], d'une vue ou de la configuration : elle est prise en compte à la requête suivante (exemple 01).

Quand on ouvre le dossier [exemples] dans [Visual Studio Code], l'extension [PHP Intelephense] analyse tous les fichiers, y compris ceux de [Symfony] dans le dossier [vendor] : on bénéficie, dans chaque fichier, de la complétion, de la navigation vers la définition d'une classe ou d'une méthode (touche [F12]), et du signalement des erreurs. Tous les exemples ayant leurs classes dans l'espace de noms [App], l'extension peut signaler des classes « en double » : c'est sans conséquence sur l'exécution, puisque chaque exemple est exécuté seul. Pour éviter ces signalements, il suffit d'ouvrir le dossier de l'exemple lui-même.

1.5. Contenu du document

Le document progresse ainsi :

Actions, routage, réponses
de la requête à l'action : routes, contrôleurs, réponses, redirections, services partagés
01 à 06
Le modèle d'une action
les paramètres de la requête : liaison, conversion, validation, requêtes POST
07 à 12
La vue et son modèle
[Twig], gabarit, macros, formulaires [Symfony], validation, PRG, protection anti-CSRF
13 à 21
Internationalisation
une application en français et en anglais
22
Portées des données
requête, session, cache, cookies
23
Le cycle de vie d'une requête
les événements du noyau, les résolveurs d'arguments, la gestion des exceptions
24
Authentification et autorisation
pare-feu, authentificateur JWT dans un cookie, rôles, captcha, limitation des tentatives
25 à 27
Architecture en couches et accès aux données
web / métier / DAO avec [Doctrine] et [MySQL]
28
Étude de cas
l'application RdvMedecins, commentée fichier par fichier
-

Chaque exemple introduit peu de nouveautés, et les chapitres s'appuient les uns sur les autres : il est préférable de les lire dans l'ordre. L'étude de cas, elle, réutilise toutes les notions des chapitres précédents : chaque fois que c'est utile, son commentaire renvoie à l'exemple où la notion a été présentée. Les annexes décrivent l'installation des outils : [PHP], [Composer], [Visual Studio Code] et ses extensions, [MySQL] avec [Laragon], [curl], et l'outil [symfony].