- Accueil
- Programmation Web S3
- Objectifs de la séance
- Introduction
- Quelques considérations liées à la configuration système de l'IUT
- Versionnage du projet
- Mise en place du projet
- Démarrage robuste de la session
- Contrôle du bon fonctionnement de la classe «
Session
» - Découverte du fonctionnement du stockage des données de session
- Choix d'un pays et mémorisation dans la session
- Sujet complémentaire
Objectifs de la séance ¶
- Configurer un projet
Composer
- Écrire une classe
PHP
permettant un démarrage robuste de la session - Découvrir le fonctionnement du stockage des données de session
- Utiliser les données de session pour mémoriser des informations
Introduction ¶
Le projet s'articule autour d'une table de base de données contenant la liste des pays du monde. L'objectif est de produire un composant logiciel permettant de sélectionner un pays dans une liste déroulante et de mémoriser ce choix dans les données de session.
Après l'initialisation du projet Composer
, vous écrirez des classes d'abstraction d'accès aux données de la base de données puis une classe permettant de gérer une liste déroulante. Vous poursuivrez vos développements en proposant une classe assurant la mémorisation du choix de l'utilisateur dans les données de session.
Quelques considérations liées à la configuration système de l'IUT ¶
Information
Si vous travaillez sur votre ordinateur personnel, sur Linux ou sur Windows, vous pouvez placer le répertoire « php-session
» du projet où bon vous semble. La partie qui suit concerne uniquement le travail sur les ordinateurs de l'IUT. Cela ne vous empêche pas d'en prendre connaissance.
Votre répertoire d'accueil « $HOME
» se trouve sur un emplacement réseau NFS
, ce qui vous permet de retrouver vos fichiers quel que soit le PC du département sur lequel vous vous connectez. PhpStorm
surveille en permanence les modifications des fichiers de votre projet et les enregistre automatiquement. Ce principe est très pratique mais fonctionne très mal sur un système de fichiers en NFS
. De plus, les outils d'analyse statique de code comme PHP CS Fixer
sont très gourmands en ressources et ne peuvent pas fonctionner correctement sur un système de fichiers en NFS
. Afin d'améliorer les performances de votre poste de travail et d'éviter de saturer le serveur de fichiers du département informatique, vous allez travailler dans le répertoire « /working/votre_login
» de la machine sur laquelle vous êtes connecté.
Versionnage du projet ¶
Pour ce sujet de TP, vous créerez un nouveau répertoire, vous initialiserez un dépôt Git dans ce répertoire et créerez un dépôt distant sur GitLab. Vous réaliserez une opération de validation avec git commit
au moins une fois par question du sujet.
Initialisation du dépôt ¶
- Ouvrez un terminal puis utilisez la commande
mkdir un_nom_de_répertoire
pour créer un nouveau répertoire «php-session
» dans «/working/votre_login
» suivie de la commandecd un_chemin_relatif_ou_absolu
pour vous placer dans le répertoire - Initialisez le dépôt Git du projet
git init
- Effectuez une première validation
git commit --allow-empty -m "Initial commit"
- Éditez le fichier «
.gitignore
» pour exclure les fichiers binaires inutiles à votre projet (fichierspptx
du cours, …), les fichiers qui contiennent des mots de passe ou, dans le cas des projets collaboratifs, les fichiers créés par votre éditeur de texte (répertoire «.idea
» pourPhpStorm
) - Éditez un fichier «
README.md
» dans lequel doivent figurer :- un titre de niveau 1 contenant le titre explicite du projet
- un titre de niveau 2 « Auteur(s) » vous permettant de préciser votre nom et votre prénom (ainsi que ceux de votre binôme, le cas échéant)
- un titre de niveau 2 « Installation / Configuration » précisant les points essentiels permettant d'installer, de configurer et de lancer le projet
- Ajoutez les fichiers au dépôt
git add .
- Effectuez une nouvelle validation
git commit -m "Repository setup"
- Si nécessaire, renommez la branche principale en «
main
» (une branche vide ne peut pas être renommée, c'est pourquoi ceci est fait après le premiercommit
)git branch -m main
Notez que vous pouvez le faire de façon définitive avec la commande suivante, à condition d'utilisergit
dans une version supérieure à2.28
git config --global init.defaultbranch main
- Connectez-vous à l'application GitLab et créez un dépôt portant le même nom que votre nouveau répertoire en pensant à décocher la case « Initialize repository with a README »
- Accordez la permission «
Reporter
» à votre enseignant de TP/TD - Associez le dépôt local et le dépôt distant
git remote add origin https://iut-info.univ-reims.fr/gitlab/votre_login/php-session.git
- Poussez le dépôt local vers le dépôt distant
git push -u origin main
Consignes ¶
- Vous effectuerez une validation après chaque question.
- À la fin de chaque séance, vous effectuerez une validation. Si cette validation contient du code incomplet ou ne fonctionnant pas, mentionnez-le dans le message de validation. Vous pousserez ensuite votre travail vers le dépôt distant.
- Ce dépôt sera utilisé par votre enseignant(e) de TP pour évaluer votre travail, que cela conduise à un note ou pas. Assurez-vous donc régulièrement que tous les fichiers que vous souhaitez lui rendre sont bien présents dans le dépôt. Respectez les noms des fichiers qui vous sont demandés si des consignes particulières vous sont données.
- Le dépôt lui-même sera évalué, soignez l'écriture de vos messages : clarté, pertinence, orthographe.
L'aide-mémoire Git et l'aide-mémoire GitLab de Monsieur Nourrit pourront vous être utiles.
Mise en place du projet ¶
À l'image des développements autour des morceaux de musique réalisés au semestre 2, vous allez mettre en place un projet Composer
et organiser vos fichiers selon la séparation classique entre les fichiers sources (classes contenues dans le répertoire « src/
» organisés selon la même sous-arborescence que les « namespace
» et les programmes (localisés dans « public/
» avec les ressources statiques comme les fichiers CSS
). Vous profiterez également de l'auto-chargement géré par Composer
.
Installer Composer
dans l'environnement de travail
¶
L'installation de Composer
consiste à télécharger le script PHP
qui le compose dans un répertoire référencé dans la variable d'environnement « PATH
». Puisque vous avez déjà effectué la configuration de votre environnement de travail l'an passé, vous allez vérifier que tout fonctionne correctement et corriger si nécessaire.
Travail à réaliser
- Testez le bon fonctionnement de
composer
en l'exécutant :composer --version
- Vérifiez que la commande s'exécute correctement en produisant une sortie semblable à la suivante :
Composer version 2.2.6 2022-02-04 17:00:38
InformationSi
Composer
ne s'exécute pas, suivez le tutoriel dédié à l'installation deComposer
dans un environnement Linux - Mettez à jour votre version de
Composer
avec la commande :composer self-update
Initialisation du projet ¶
L'initialisation d'un projet Composer
peut se faire avec une ligne de commande comportant des options ou en mode interactif. Vous allez procéder selon cette seconde méthode.
Travail à réaliser
Information
Le mode interactif de Composer
propose des valeurs par défaut entre crochets avant d'inviter à la saisie :
Package name (<vendor>/<name>) [cutron01/php-session]:
Lisez bien ces propositions par défaut afin d'éviter toute saisie inutile et surtout erronée. Les valeurs par défaut ne sont pas toujours celles qui vous conviennent !
- Lancez la commande dans le répertoire du projet et donnez les réponses conformément à l'exemple, «
cutron01
» étant à remplacer par « votre_login »composer init Welcome to the Composer config generator This command will guide you through creating your composer.json config. Package name (<vendor>/<name>) [cutron01/php-session]: Description []: Gestion des données de session : choix d'un pays Author [Jérôme Cutrona <jerome.cutrona@univ-reims.fr>, n to skip]: Minimum Stability []: Package Type (e.g. library, project, metapackage, composer-plugin) []: project License []: Copyleft Define your dependencies. Would you like to define your dependencies (require) interactively [yes]? no Would you like to define your dev dependencies (require-dev) interactively [yes]? Search for a package: cs-fixer Info from https://repo.packagist.org: #StandWithUkraine Found 15 packages matching cs-fixer [0] friendsofphp/php-cs-fixer [1] php-cs-fixer/diff [2] fabpot/php-cs-fixer Abandoned. Use friendsofphp/php-cs-fixer instead. [3] kubawerlos/php-cs-fixer-custom-fixers [4] matt-allan/laravel-code-style Abandoned. Use jubeki/laravel-code-style instead. [5] symplify/coding-standard [6] stechstudio/laravel-php-cs-fixer [7] slam/php-cs-fixer-extensions [8] ergebnis/php-cs-fixer-config [9] typo3/coding-standards [10] pedrotroller/php-cs-custom-fixer [11] nextcloud/coding-standard [12] codeigniter/coding-standard [13] vincentlanglet/twig-cs-fixer [14] adamwojs/php-cs-fixer-phpdoc-force-fqcn Enter package # to add, or the complete package name if it is not listed: 0 Enter the version constraint to require (or leave blank to use the latest version): Using version ^3.8 for friendsofphp/php-cs-fixer Search for a package: Add PSR-4 autoload mapping? Maps namespace "Cutron01\PhpSession" to the entered relative path. [src/, n to skip]: { "name": "cutron01/php-session", "description": "Gestion des données de session : choix d'un pays", "type": "project", "require-dev": { "friendsofphp/php-cs-fixer": "^3.8" }, "license": "Copyleft", "autoload": { "psr-4": { "Cutron01\PhpSession\": "src/" } }, "authors": [ { "name": "Jérôme Cutrona", "email": "jerome.cutrona@univ-reims.fr" } ], "require": {} } Do you confirm generation [yes]? Would you like the vendor directory added to your .gitignore [yes]? Would you like to install dependencies now [yes]? Loading composer repositories with package information Updating dependencies Lock file operations: 28 installs, 0 updates, 0 removals - Locking composer/pcre (3.0.0) - Locking composer/semver (3.3.2) - Locking composer/xdebug-handler (3.0.3) - Locking doctrine/annotations (1.13.2) - Locking doctrine/lexer (1.2.3) - Locking friendsofphp/php-cs-fixer (v3.8.0) - Locking php-cs-fixer/diff (v2.0.2) - Locking psr/cache (3.0.0) - Locking psr/container (2.0.2) - Locking psr/event-dispatcher (1.0.0) - Locking psr/log (3.0.0) - Locking symfony/console (v6.1.2) - Locking symfony/deprecation-contracts (v3.1.0) - Locking symfony/event-dispatcher (v6.1.0) - Locking symfony/event-dispatcher-contracts (v3.1.0) - Locking symfony/filesystem (v6.1.0) - Locking symfony/finder (v6.1.0) - Locking symfony/options-resolver (v6.1.0) - Locking symfony/polyfill-ctype (v1.26.0) - Locking symfony/polyfill-intl-grapheme (v1.26.0) - Locking symfony/polyfill-intl-normalizer (v1.26.0) - Locking symfony/polyfill-mbstring (v1.26.0) - Locking symfony/polyfill-php80 (v1.26.0) - Locking symfony/polyfill-php81 (v1.26.0) - Locking symfony/process (v6.1.0) - Locking symfony/service-contracts (v3.1.0) - Locking symfony/stopwatch (v6.1.0) - Locking symfony/string (v6.1.2) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 28 installs, 0 updates, 0 removals - Downloading symfony/string (v6.1.2) - Downloading symfony/console (v6.1.2) - Installing composer/pcre (3.0.0): Extracting archive - Installing doctrine/lexer (1.2.3): Extracting archive - Installing psr/container (2.0.2): Extracting archive - Installing symfony/service-contracts (v3.1.0): Extracting archive - Installing symfony/stopwatch (v6.1.0): Extracting archive - Installing symfony/process (v6.1.0): Extracting archive - Installing symfony/polyfill-php81 (v1.26.0): Extracting archive - Installing symfony/polyfill-php80 (v1.26.0): Extracting archive - Installing symfony/polyfill-mbstring (v1.26.0): Extracting archive - Installing symfony/deprecation-contracts (v3.1.0): Extracting archive - Installing symfony/options-resolver (v6.1.0): Extracting archive - Installing symfony/finder (v6.1.0): Extracting archive - Installing symfony/polyfill-ctype (v1.26.0): Extracting archive - Installing symfony/filesystem (v6.1.0): Extracting archive - Installing psr/event-dispatcher (1.0.0): Extracting archive - Installing symfony/event-dispatcher-contracts (v3.1.0): Extracting archive - Installing symfony/event-dispatcher (v6.1.0): Extracting archive - Installing symfony/polyfill-intl-normalizer (v1.26.0): Extracting archive - Installing symfony/polyfill-intl-grapheme (v1.26.0): Extracting archive - Installing symfony/string (v6.1.2): Extracting archive - Installing symfony/console (v6.1.2): Extracting archive - Installing php-cs-fixer/diff (v2.0.2): Extracting archive - Installing psr/cache (3.0.0): Extracting archive - Installing doctrine/annotations (1.13.2): Extracting archive - Installing psr/log (3.0.0): Extracting archive - Installing composer/xdebug-handler (3.0.3): Extracting archive - Installing composer/semver (3.3.2): Extracting archive - Installing friendsofphp/php-cs-fixer (v3.8.0): Extracting archive 4 package suggestions were added by new dependencies, use `composer suggest` to see details. Generating autoload files 22 packages you are using are looking for funding. Use the `composer fund` command to find out more! PSR-4 autoloading configured. Use "namespace Cutron01\PhpSession;" in src/ Include the Composer autoloader with: require 'vendor/autoload.php';
Remarque importanteNotez l'information concernant l'auto-chargement sur la dernière ligne de la sortie de la commande, vous allez bientôt l'utiliser.
- Créez un nouveau projet
PhpStorm
en lançant la commande suivante dans le répertoire du projet :phpstorm . &
InformationCette astuce vous permet de créer un projet
PhpStorm
en quelques secondes au lieu de nombreux clics avec la méthode traditionnelle utilisant les menus de l'interface graphique. Mémorisez-la ! - Vérifiez le contenu du fichier «
.gitignore
» qui doit comporter au minimum :/.idea /vendor/
- Éditez le fichier
composer.json
pour modifier l'auto-chargement généré par défaut en :"autoload": { "psr-4": { "": "src/" } },
Remarque importanteL'auto-chargement de
Composer
met en correspondance des espaces de noms (namespace) et des répertoires. À l'initialisation du projet, un auto-chargementPSR-4
fait correspondre l'espace de noms du projet «votre_login\CrudMusic\
» au répertoire «src/
».Afin de ne pas nous encombrer avec cet espace de noms long et fastidieux à lire, nous avons simplifié l'association à « tous les espaces de noms » se trouvent dans le répertoire «
src/
», c'est-à-dire"": "src/"
dans le fichier de configuration. - Mettez à jour l'auto-chargement de
Composer
en lançant la commande suivante :composer dump-autoload
InformationLa commande
composer dump-autoload
n'est nécessaire qu'en cas de modification des règles «autoload
» ou «autoload-dev
» dans le fichier «composer.json
». Toute nouvelle classePHP
introduite dans le projet sera immédiatement prise en compte sans qu'il soit nécessaire de relancer cette commande.Si vous clonez votre dépôt
Git
, l'auto-chargement ne sera pas à jour et vous devrez lancer la commandecomposer dump-autoload
.Composer
admet des noms de commandes courts, à condition qu'il n'y ait pas d'ambiguïté. Par exemple,composer du
est équivalent àcomposer dump-autoload
, alors quecomposer d
est ambigu puisque plusieurs commandes commencent par la lettre «d
». - Ajoutez les fichiers «
composer.json
» et «composer.lock
» à l'indexgit
puis effectuez un nouveaucommit
Configuration de PHP CS Fixer
¶
« PHP CS Fixer
» faisant partie des dépendances de développement de votre projet, vous allez le configurer pour pouvoir l'utiliser en ligne de commande et l'intégrer dans PhpStorm
.
Travail à réaliser
- Placez à la racine du projet le fichier de configuration de
PHP CS Fixer
(télécharger) pour respecter le jeu de règlesSymfony
Remarque importanteLe fichier à télécharger doit s'appeler «
.php-cs-fixer.php
», même si votre navigateur a décidé de supprimer le «.
» initial. Renommez le fichier si nécessaire. - Excluez le fichier «
.php-cs-fixer.cache
» de l'indexgit
en complétant le fichier «.gitignore
» - Créez le script
Composer
«test:cs
» qui déclenchera la vérification du codePHP
:php vendor/bin/php-cs-fixer fix --dry-run
- Créez le script
Composer
«fix:cs
» qui déclenchera la correction du codePHP
:php vendor/bin/php-cs-fixer fix
- Testez ces deux scripts
Composer
- Accédez aux préférences de
PhpStorm
(CTRL+ALT+S
) - Accédez à la configuration des outils de qualité de code dans le menu « PHP - Quality Tools » des préférences de
PhpStorm
: - Accédez à la configuration du chemin de
PHP CS Fixer
en appuyant sur le bouton « … » : - Localisez le programme «
php-cs-fixer
» dans le répertoire «vendor/bin
» du projet : - Après avoir validé le chemin dans la fenêtre précédente, appliquez les modifications dans la fenêtre des préférences de
PHP CS Fixer
- Fermez la fenêtre des préférences et accédez de nouveau aux préférences de
PhpStorm
(CTRL+ALT+S
) - Accédez à la configuration de
PHP CS Fixer
et constatez la mise à jour de la liste des jeux de règles disponibles : - Choisissez le jeu de règles « Custom », utilisez le bouton parcourir pour localiser le fichier «
.php-cs-fixer.php
» puis activez la validation parPHP CS Fixer
- Validez la configuration
Mise en place du serveur Web local ¶
Dans les projets Web, les ressources, au sens HTTP
du terme, sont séparées du reste du projet comme les classes ou les éléments de configuration. Ceci permet de rendre inaccessibles les autres fichiers que ceux des ressources en les maintenant dans des répertoires en amont de la racine des ressources du serveur Web. Concrètement, les ressources Web seront placées dans un répertoire « public
» qui constituera la racine du serveur Web.
Travail à réaliser
- Créez le répertoire «
public
» à la racine du projet - Désignez le répertoire «
public
» comme racine des ressources Web dansPhpStorm
: - Créez un fichier «
index.php
» dans ce répertoire et insérez-y le code suivant :<?php echo 'Hello Session!';
- Créez le répertoire «
bin
» à la racine du projet - Placez le fichier«
run-server.sh
» (télécharger) dans le répertoire «bin
» - Rendez le script «
run-server.sh
» exécutable :setfacl -m u::rwx bin/run-server.sh
- Placez le fichier «
run-server.bat
» (télécharger) dans le répertoire «bin
» - Ajoutez au fichier «
composer.json
» les scriptsComposer
«start:linux
» et «start:windows
» permettant de lancer respectivement les scripts «bin/run-server.sh
» et «bin/run-sever.bat
» - Faites en sorte que les scripts
Composer
«start:linux
» et «start:windows
» n'aient pas de limite de temps d'exécution - Lancez le script «
start:linux
» en utilisant une forme agrégée et vérifiez qu'il s'exécute correctement :composer start:l > Composer\Config::disableProcessTimeout > bin/run-server.sh [Wed Jun 29 10:59:35 2022] PHP 8.1.7 Development Server (http://localhost:8000) started
- Interrogez le serveur Web local en utilisant l'URL «
http://localhost:8000/
»InformationVous pouvez cliquer directement sur le texte «
http://localhost:8000/
» dans le terminal dePhpStorm
pour ouvrir l'URL dans le navigateur par défaut. - Vérifiez que la réponse reçue par le client est conforme aux attentes
- Définissez un nouveau script
Composer
«start
» qui référence le script «start:linux
» que vous utiliserez le plus souvent en TP - Documentez votre projet dans «
README.md
» en précisant comment lancer le serveur Web local dans une partie « Serveur Web local »
Intégration des composants logiciels ¶
Ce nouveau projet va s'appuyer sur les développements réalisés lors du semestre 2. Ainsi, vous allez reprendre les composants « MyPdo
», « WebPage
», « StringEscaper
» et « AppWebPage
».
Travail à réaliser
- Placez le fichier du trait «
StringEscaper
» (télécharger) dans le répertoire «src/Html
» du projet - Placez le fichier de la classe «
WebPage
» (télécharger) dans le répertoire «src/Html
» du projet - Placez le fichier de la classe «
AppWebPage
» (télécharger) dans le répertoire «src/Html
» du projet - Placez le fichier «
index.php
» (télécharger) dans le répertoire «public
», en remplacement du précédent fichier de même nom - Placez le fichier «
style.css
» (télécharger) dans le répertoire «public/css
» - Interrogez le serveur Web local en utilisant l'URL «
http://localhost:8000/
» - Vérifiez que la page Web générée s'affiche correctement :
Démarrage robuste de la session ¶
Vous avez découvert le principe des sessions lors de l'étude du protocole HTTP
. Pour gérer les données de session en PHP
, il faut préalablement « démarrer la session » avec la fonction session_start()
. Cette dernière va effectuer les opérations nécessaires côté serveur et maintenir l'identification du client à l'aide d'un cookie de session. L'étude du protocole HTTP
vous a démontré que, lors du dépôt du cookie par le serveur, le cookie va transiter vers le client dans les en-têtes de la réponse HTTP
et vous savez que la commande « echo
» remplit la charge utile de la réponse HTTP
. Il est donc impossible en PHP
de placer un cookie si « echo
» a été utilisée, et par conséquence il est tout aussi impossible de démarrer une session si « echo
» a été utilisée.
Information
La notion de « démarrage » de session recouvre deux aspects. Le premier est le démarrage initial de la session lorsque le client est initialement associé aux données de session. Vient ensuite ce qu'il conviendrait de qualifier « redémarrage de session » lors des accès suivants du même client et la ré-association entre le client et les précédentes données de session.
Une stratégie simple et naïve pour démarrer la session pourrait consister à faire appel à la fonction « session_start()
» au début de chaque programme. Cependant, la méthodologie de développement orienté objets, et en particulier le principe d'encapsulation, cache l'implémentation interne de chaque classe. Ainsi, l'utilisateur d'une classe faisant usage de la session devrait savoir qu'il doit démarrer la session pour que la classe fonctionne et ceci va à l'encontre du principe d'encapsulation. La classe doit elle-même démarrer la session. Dans ce cas, et si plusieurs classes démarrent la session, des erreurs ou avertissements apparaîtront. Une gestion avertie du démarrage de la session est nécessaire.
C'est pourquoi, afin de faciliter vos développements et répondre aux divers problèmes posés, vous écrirez une classe « Session
» dont l'unique méthode de classe « start()
» démarre la session de façon unique et robuste, et lève une exception en cas d'échec.
Travail à réaliser
- Écrivez la classe «
Service\Exception\SessionException
», héritant de «Exception
» - Définissez une classe «
Service\Session
» dans un nouveau ficher convenablement placé dans la sous-arborescence de «src
» - Implémentez son unique méthode de classe «
start()
» qui devra permettre de démarrer la session, uniquement lorsque cela est nécessaire, conformément à l'algorithme suivant :Selon l'état de la session :
- session déjà démarrée
- il n'y a rien de plus à faire
- session non démarrée
- lever une exception de type «
Service\Exception\SessionException
» s'il est impossible de modifier les entêtesHTTP
, sinon démarrer la session et lever une exception de type «Service\Exception\SessionException
» en cas d'échec - session désactivée
- lever une exception de type «
Service\Exception\SessionException
» - dans tous les autres cas (inconnus)
- lever une exception de type «
Service\Exception\SessionException
»
Contrôle du bon fonctionnement de la classe « Session
»
¶
Vous allez utiliser des programmes dont la seule utilité est de contrôler le bon fonctionnement de la classe « Session
».
Travail à réaliser
- Créez le répertoire «
public/demo
» et placez-y programmes suivants : - Lancez votre serveur Web local
- À l'aide de votre navigateur, accédez à la ressource «
/demo/
» de votre serveur Web local - Utilisez le lien « Démarrage de la session »
- Vérifiez que la session est correctement démarrée (🆗️ : il n'y a pas d'erreur, ⚠ : il y a une d'erreur)
- Utilisez le lien « Double démarrage de la session »
- Vérifiez que la session est correctement démarrée (🆗️ : il n'y a pas d'erreur, ⚠ : il y a une d'erreur)
- Utilisez le lien « Démarrage impossible de la session »
- Vérifiez que la session n'est pas démarrée et qu'il n'y a pas d'erreurs résiduelles (🆗️ : il n'y a pas d'erreur, ⚠ : il y a une d'erreur)
Découverte du fonctionnement du stockage des données de session ¶
Afin de clarifier le fonctionnement du stockage des données de session, vous allez utiliser des programmes manipulant les données de session et suivre les mécanismes impliqués dans des diagrammes de séquences détaillés.
Travail à réaliser
- Ajoutez au répertoire «
public/demo
» les programmes suivants : - À l'aide de votre navigateur, accédez à la ressource «
/demo/
» de votre serveur Web local - Ouvrez la barre de développement du navigateur
- Observez la présence d'un cookie associé au serveur Web local, créé par les précédentes opérations de contrôle du fonctionnement de la classe «
Session
» - Supprimez ce cookie Information
Vous pouvez facilement effacer le cookie de session «
PHPSESSID
» à l'aide de la barre développement de votre navigateur (onglet « Application » pour Chrome, onglet « Stockage » pour Firefox). - Cliquez sur le lien « Écriture de la donnée » correspondant au programme «
write.php
» - Observez l'apparition d'un cookie associé au serveur Web local
- Mettez le code source du programme en relation avec le diagramme d'échange suivant :
- Revenez à l'index de démonstration (ressource «
/demo/
») - Cliquez sur le lien « Lecture de la donnée » correspondant au programme «
read.php
» - Mettez le code source du programme en relation avec le diagramme d'échange suivant :
- Revenez à l'index de démonstration (ressource «
/demo/
») - Cliquez sur le lien « Effacement de la donnée » correspondant au programme «
delete.php
» - Mettez le code source du programme en relation avec le diagramme d'échange suivant :
- Revenez à l'index de démonstration (ressource «
/demo/
») - Cliquez sur le lien « Écriture de la donnée » correspondant au programme «
write.php
» - Mettez le programme en relation avec le diagramme d'échange suivant :
- Testez d'autres séquences d'interactions, par exemple en effaçant la donnée de session avant de tenter de la consulter et imaginez les échanges correspondants
Choix d'un pays et mémorisation dans la session ¶
Maintenant que le fonctionnement des sessions est clarifié, vous allez développer une liste de choix de pays qui permettra à l'utilisateur de mémoriser le pays qu'il a choisi dans les données de session.
Les pays sont stockés dans une base de données.
La structure du projet ainsi que la philosophie de développement seront identiques à celles utilisées au semestre 2 dans les TP consacrés au CRUD :
- La classe «
Entity\Country
» représente un pays, équivalent à une ligne de la table «country
» - La classe «
Entity\Collection\CountryCollection
» permet de récupérer l'ensemble des «Entity\Country
» depuis la base de données - La classe «
Html\Form\CountrySelect
» représente une liste déroulante de codes de pays
Information
Notez que d'un point de vue conception pure, la méthode « escapeString()
» du trait « StringEscaper
» est une méthode de classe puisqu'aucune donnée d'instance n'est utilisée. Cependant, pour respecter les bonnes pratiques d'implémentation et faciliter l'utilisation de la méthode (notamment dans les chaînes de caractères), nous l'avons définie comme méthode d'instance.
Base de données ¶
Les données proposées sont une version simplifiée des contenus accessibles depuis https://stefangabos.github.io/world_countries/. Les pays sont stockés dans une base de données MySQL
« cutron01_country
» sur le serveur « mysql
» du département informatique. Elle est accessible en lecture à l'utilisateur « web
» dont le mot de passe est « web
». La seule table de cette base de données a la structure suivante :
Travail à réaliser
- Placez le fichier de la classe «
MyPdo
» (télécharger) dans le répertoire «src/Database
» du projet - Lisez la documentation de la méthode «
setConfigurationFromIniFile()
» de la classe «MyPdo
» - Créez et complétez le fichier de configuration de l'accès à la base de données «
.mypdo.ini
»
Collection des pays ¶
La première étape va consister à développer la classe correspondant à une ligne de la table de la base de données ainsi que la collection d'objets possédant la méthode d'interrogation de la base de données. Cette démarche est identique à celle utilisée au semestre 2.
Travail à réaliser
- Créez la classe «
Entity\Country
» correspondant à une ligne de la table «country
» - Générez automatiquement les accesseurs aux propriétés de «
Entity\Country
»InformationComme l'an passé, vous pouvez générer des mutateurs autorisant le chaînage de méthodes si vous le souhaitez.
- Créez la classe «
Entity\Collection\CountryCollection
» - Écrivez la méthode de classe «
findAll()
» de la classe «CountryCollection
» qui effectue une requête base de données et retourne l'ensemble des «Country
» triés par nom
Liste de choix de pays ¶
La première étape va consister à développer une liste de choix de pays complètement indépendante des problématiques de session.
Travail à réaliser
- Créez la classe «
Html\Form\CountrySelect
» - Ajoutez les propriétés, constructeur, accesseurs et mutateurs de la classe «
CountrySelect
» conformément au diagramme de classe - Écrivez la méthode «
toHtml()
» qui produit le codeHTML
de la liste déroulante :- La liste déroulante porte comme nom la valeur de la propriété «
name
» du «CountrySelect
» - La première «
option
» a pour valeur une chaîne vide et le texte visible par l'utilisateur est la valeur de la propriété «firstOption
» du «CountrySelect
» - les «
option
» ont pour valeur le code du pays et affichent le nom du pays à l'utilisateur - L'«
option
» sélectionnée est celle dont la valeur est égale à la valeur de la propriété «selectedCode
» du «CountrySelect
»
- La liste déroulante porte comme nom la valeur de la propriété «
- Écrivez la méthode «
setSelectedCodeFromRequest()
» qui cherche si le tableau «$_REQUEST
» comporte une clé égale à la valeur de la propriété «name
» et affecte la propriété «selectedCode
» avec la valeur si elle est non vide - Placez le fichier «
select.php
» (télécharger) dans le répertoire «public
» - Vérifiez le bon fonctionnement de votre liste déroulante
- Contrôlez que le code
HTML
produit est conforme à vos attentes en consultant le code sourceHTML
dans le navigateur - Contrôlez la validité du code
HTML
produit
Prise en compte des données de session ¶
Le composant « CountrySelect
» est indépendant et réutilisable. Vous allez le réutiliser pour le dériver en une classe « SessionManagedCountrySelect
» qui permettra de mémoriser le choix de pays fait par l'utilisateur dans les données de session.
L'algorithme général de fonctionnement est alors :
- Construire une instance de «
SessionManagedCountrySelect
»- si possible, lire le code pays sélectionné depuis les données de session
- si possible, lire le code pays sélectionné depuis la « query string »
GET
ouPOST
- enregistrer le code pays sélectionné dans les données de session
Les méthodes et leur utilisation seront ajoutées au fur et à mesure.
Travail à réaliser
- Créez la classe «
Html\Form\SessionManagedCountrySelect
» héritant de «Html\Form\CountrySelect
» - Dans le constructeur, appelez le constructeur du parent et démarrez la session
- Copiez le fichier «
public/select.php
» en «public/session-managed-select.php
» - Éditez «
public/session-managed-select.php
» pour remplacer l'utilisation de la classe «CountrySelect
» par la classe «SessionManagedCountrySelect
» - Demandez cette nouvelle ressource à votre serveur Web local
- Vérifiez dans un premier temps que la liste déroulante reprend bien le pays sélectionné
- Observez les cookies associés au serveur Web local et vérifiez qu'un cookie «
PHPSESSID
» est présent - Ajoutez à la classe la méthode «
saveSelectedCodeIntoSession()
» dont le rôle est de « ranger » la valeur sélectionnée de l'objet «SessionManagedCountrySelect
» dans la case du tableau des données de session dont la clé est le nom de l'objet «SessionManagedCountrySelect
» - Affichez les informations de la variable «
$_SESSION
» dans le programme «session-managed-select.php
» :$webPage->appendContent('<pre>' . print_r($_SESSION, true) . '</pre>');
- Actualisez la vue de votre navigateur Web et constatez le contenu des données de session
- Ajoutez dans «
public/session-managed-select.php
» un appel à la méthode «saveSelectedCodeIntoSession()
» de la classe «SessionManagedCountrySelect
» juste après l'appel de «setSelectedCodeFromRequest()
» - Actualisez la vue de votre navigateur Web et constatez le contenu des données de session
- Définissez la méthode «
setSelectedCodeFromSession()
» qui affecte la valeur sélectionnée de l'objet «SessionManagedCountrySelect
» avec la valeur stockée dans les données de session et n'effectue aucune action si la valeur ne peut pas être trouvée dans les données de session - Ajoutez dans «
public/session-managed-select.php
» un appel à la méthode «setSelectedCodeFromSession()
» de la classe «SessionManagedCountrySelect
» juste avant l'appel de «setSelectedCodeFromRequest()
» - Supprimez la « query string » dans la barre d'adresse de votre navigateur, validez et constatez que la liste déroulante est positionnée sur le pays mémorisé dans les données de session
- Supprimez l'affichage des informations de la variable «
$_SESSION
»
Fiabilisation du comportement de la classe « SessionManagedCountrySelect
»
¶
Le composant « SessionManagedCountrySelect
» propose une interface de saisie et une gestion transparente de la mémorisation du code du pays dans les données de session. Cependant, les opérations nécessaires à son bon fonctionnement (comme la lecture des données depuis la session, la lecture des données depuis la « query string » ou la mémorisation du choix de l'utilisateur dans les données de session) pourraient être effectuées de façon fiable et surtout systématique en les appelant dans le bon ordre directement dans le constructeur. Vous allez apporter ces modifications.
Travail à réaliser
- Dans le constructeur de la classe «
Html\Form\SessionManagedCountrySelect
», appelez successivement les méthodes «setSelectedCodeFromSession()
», «setSelectedCodeFromRequest()
» et «saveSelectedCodeIntoSession()
» - Supprimez les appels aux méthodes «
setSelectedCodeFromSession()
», «setSelectedCodeFromRequest()
» et «saveSelectedCodeIntoSession()
» dans «public/session-managed-select.php
» - Vérifiez que le programme «
public/session-managed-select.php
» fonctionne toujours correctement
Sujet complémentaire ¶
Si vous avez traité l'ensemble des questions du sujet, vous pouvez poursuivre avec le sujet complémentaire.