Jérôme Cutrona

Version statique de l'intranet de Jérôme Cutrona - Rejoindre la version dynamique 🔒

Les exemples et corrections sont potentiellement non fonctionnels.

B.U.T. Informatique - IUT de Reims - Université de Reims

Gestion des données de session

Navigation

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 commande cd 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 (fichiers pptx 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 » pour PhpStorm)
  • É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 premier commit)
    git branch -m main
    Notez que vous pouvez le faire de façon définitive avec la commande suivante, à condition d'utiliser git 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
  1. Testez le bon fonctionnement de composer en l'exécutant :
    composer --version
  2. 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
    
    Information
  3. 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 !

  1. 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 importante

    Notez l'information concernant l'auto-chargement sur la dernière ligne de la sortie de la commande, vous allez bientôt l'utiliser.

  2. Créez un nouveau projet PhpStorm en lançant la commande suivante dans le répertoire du projet :
    phpstorm . &
    Information

    Cette 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 !

  3. Vérifiez le contenu du fichier « .gitignore » qui doit comporter au minimum :
    /.idea
    /vendor/
    
  4. Éditez le fichier composer.json pour modifier l'auto-chargement généré par défaut en :
        "autoload": {
            "psr-4": {
                "": "src/"
            }
        },
    Remarque importante

    L'auto-chargement de Composer met en correspondance des espaces de noms (namespace) et des répertoires. À l'initialisation du projet, un auto-chargement PSR-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.
  5. Mettez à jour l'auto-chargement de Composer en lançant la commande suivante :
    composer dump-autoload
    Information

    La 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 classe PHP 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 commande composer 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 que composer d est ambigu puisque plusieurs commandes commencent par la lettre « d ».

  6. Ajoutez les fichiers « composer.json » et « composer.lock » à l'index git puis effectuez un nouveau commit

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
  1. Placez à la racine du projet le fichier de configuration de PHP CS Fixer (télécharger) pour respecter le jeu de règles Symfony
    Remarque importante

    Le 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.

  2. Excluez le fichier « .php-cs-fixer.cache » de l'index git en complétant le fichier « .gitignore »
  3. Créez le script Composer « test:cs » qui déclenchera la vérification du code PHP :
    php vendor/bin/php-cs-fixer fix --dry-run
  4. Créez le script Composer « fix:cs » qui déclenchera la correction du code PHP :
    php vendor/bin/php-cs-fixer fix
  5. Testez ces deux scripts Composer
  6. Accédez aux préférences de PhpStorm (CTRL+ALT+S)
  7. Accédez à la configuration des outils de qualité de code dans le menu « PHP - Quality Tools » des préférences de PhpStorm : Accès à la configuration des outils de qualité de code dans le menu PHP - Quality Tools des préférences de PhpStorm
  8. Accédez à la configuration du chemin de PHP CS Fixer en appuyant sur le bouton « … » : Configuration de PHP CS Fixer dans les préférences de PhpStorm
  9. Localisez le programme « php-cs-fixer » dans le répertoire « vendor/bin » du projet : Localisation du programme php-cs-fixer dans le répertoire vendor/bin du projet
  10. 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
  11. Fermez la fenêtre des préférences et accédez de nouveau aux préférences de PhpStorm (CTRL+ALT+S)
  12. Accédez à la configuration de PHP CS Fixer et constatez la mise à jour de la liste des jeux de règles disponibles : Mise à jour du jeu de règles de PHP CS Fixer dans les préférences de PhpStorm
  13. Choisissez le jeu de règles « Custom », utilisez le bouton parcourir pour localiser le fichier « .php-cs-fixer.php » puis activez la validation par PHP CS Fixer Réglages de PHP CS Fixer dans les préférences de PhpStorm
  14. 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
  1. Créez le répertoire « public » à la racine du projet
  2. Désignez le répertoire « public » comme racine des ressources Web dans PhpStorm : Configuration du répertoire public comme racine des ressources Web dans PhpStorm
  3. Créez un fichier « index.php » dans ce répertoire et insérez-y le code suivant :
    <?php
    
    echo 'Hello Session!';
    
    
  4. Créez le répertoire « bin » à la racine du projet
  5. Placez le fichier« run-server.sh » (télécharger) dans le répertoire « bin »
  6. Rendez le script « run-server.sh » exécutable :
    setfacl -m u::rwx bin/run-server.sh
  7. Placez le fichier « run-server.bat » (télécharger) dans le répertoire « bin »
  8. Ajoutez au fichier « composer.json » les scripts Composer « start:linux » et « start:windows » permettant de lancer respectivement les scripts « bin/run-server.sh » et « bin/run-sever.bat »
  9. Faites en sorte que les scripts Composer « start:linux » et « start:windows » n'aient pas de limite de temps d'exécution
  10. 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
    
  11. Interrogez le serveur Web local en utilisant l'URL « http://localhost:8000/ »
    Information

    Vous pouvez cliquer directement sur le texte « http://localhost:8000/ » dans le terminal de PhpStorm pour ouvrir l'URL dans le navigateur par défaut.

  12. Vérifiez que la réponse reçue par le client est conforme aux attentes
  13. Définissez un nouveau script Composer « start » qui référence le script « start:linux » que vous utiliserez le plus souvent en TP
  14. 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
  1. Placez le fichier du trait « StringEscaper » (télécharger) dans le répertoire « src/Html » du projet
  2. Placez le fichier de la classe « WebPage » (télécharger) dans le répertoire « src/Html » du projet
  3. Placez le fichier de la classe « AppWebPage » (télécharger) dans le répertoire « src/Html » du projet
  4. Placez le fichier « index.php » (télécharger) dans le répertoire « public », en remplacement du précédent fichier de même nom
  5. Placez le fichier « style.css » (télécharger) dans le répertoire « public/css »
  6. Interrogez le serveur Web local en utilisant l'URL « http://localhost:8000/ »
  7. Vérifiez que la page Web générée s'affiche correctement : Capture d'écran de la page d'accueil du serveur Web local

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. Diagramme de la classe Session

Travail à réaliser
  1. Écrivez la classe « Service\Exception\SessionException », héritant de « Exception »
  2. Définissez une classe « Service\Session » dans un nouveau ficher convenablement placé dans la sous-arborescence de « src »
  3. 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êtes HTTP, 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
  1. Créez le répertoire « public/demo » et placez-y programmes suivants :
  2. Lancez votre serveur Web local
  3. À l'aide de votre navigateur, accédez à la ressource « /demo/ » de votre serveur Web local
  4. Utilisez le lien « Démarrage de la session »
  5. Vérifiez que la session est correctement démarrée (🆗️ : il n'y a pas d'erreur,  : il y a une d'erreur)
  6. Utilisez le lien « Double démarrage de la session »
  7. Vérifiez que la session est correctement démarrée (🆗️ : il n'y a pas d'erreur,  : il y a une d'erreur)
  8. Utilisez le lien « Démarrage impossible de la session »
  9. 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
  1. Ajoutez au répertoire « public/demo » les programmes suivants :
  2. À l'aide de votre navigateur, accédez à la ressource « /demo/ » de votre serveur Web local
  3. Ouvrez la barre de développement du navigateur
  4. 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 »
  5. 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).

  6. Cliquez sur le lien « Écriture de la donnée » correspondant au programme « write.php »
  7. Observez l'apparition d'un cookie associé au serveur Web local
  8. Mettez le code source du programme en relation avec le diagramme d'échange suivant : échange HTTP initial entre client et serveur conduisant à la création de la session
  9. Revenez à l'index de démonstration (ressource « /demo/ »)
  10. Cliquez sur le lien « Lecture de la donnée » correspondant au programme « read.php »
  11. Mettez le code source du programme en relation avec le diagramme d'échange suivant : échange HTTP entre client et serveur conduisant à la lecture depuis la session
  12. Revenez à l'index de démonstration (ressource « /demo/ »)
  13. Cliquez sur le lien « Effacement de la donnée » correspondant au programme « delete.php »
  14. Mettez le code source du programme en relation avec le diagramme d'échange suivant : échange HTTP entre client et serveur conduisant à la lecture depuis la session
  15. Revenez à l'index de démonstration (ressource « /demo/ »)
  16. Cliquez sur le lien « Écriture de la donnée » correspondant au programme « write.php »
  17. Mettez le programme en relation avec le diagramme d'échange suivant : échange HTTP entre client et serveur conduisant à la lecture depuis la session
  18. 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
Diagramme de la classe CountrySelect
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 : Le schéma de la base de données

Travail à réaliser
  1. Placez le fichier de la classe « MyPdo » (télécharger) dans le répertoire « src/Database » du projet
  2. Lisez la documentation de la méthode « setConfigurationFromIniFile() » de la classe « MyPdo »
  3. 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
  1. Créez la classe « Entity\Country » correspondant à une ligne de la table « country »
  2. Générez automatiquement les accesseurs aux propriétés de « Entity\Country »
    Information

    Comme l'an passé, vous pouvez générer des mutateurs autorisant le chaînage de méthodes si vous le souhaitez.

  3. Créez la classe « Entity\Collection\CountryCollection »
  4. É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
  1. Créez la classe « Html\Form\CountrySelect »
  2. Ajoutez les propriétés, accesseurs et mutateurs de la classe « CountrySelect » conformément au diagramme de classe
  3. Écrivez la méthode « toHtml() » qui produit le code HTML 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 »
  4. É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
  5. Placez le fichier « select.php » (télécharger) dans le répertoire « public »
  6. Vérifiez le bon fonctionnement de votre liste déroulante
  7. Contrôlez que le code HTML produit est conforme à vos attentes en consultant le code source HTML dans le navigateur
  8. 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. Diagramme de la classe SessionManagedCountrySelect

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 ou POST
  • 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
  1. Créez la classe « Html\Form\SessionManagedCountrySelect » héritant de « Html\Form\CountrySelect »
  2. Dans le constructeur, appelez le constructeur du parent et démarrez la session
  3. Copiez le fichier « public/select.php » en « public/session-managed-select.php »
  4. Éditez « public/session-managed-select.php » pour remplacer l'utilisation de la classe « CountrySelect » par la classe « SessionManagedCountrySelect »
  5. Demandez cette nouvelle ressource à votre serveur Web local
  6. Vérifiez dans un premier temps que la liste déroulante reprend bien le pays sélectionné
  7. Observez les cookies associés au serveur Web local et vérifiez qu'un cookie « PHPSESSID » est présent
  8. 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 »
  9. Affichez les informations de la variable « $_SESSION » dans le programme « session-managed-select.php » :
    $webPage->appendContent('<pre>' . print_r($_SESSION, true) . '</pre>');
  10. Actualisez la vue de votre navigateur Web et constatez le contenu des données de session
  11. Ajoutez dans « public/session-managed-select.php » un appel à la méthode « saveSelectedCodeIntoSession() » de la classe « SessionManagedCountrySelect » juste après l'appel de « setSelectedCodeFromRequest() »
  12. Actualisez la vue de votre navigateur Web et constatez le contenu des données de session
  13. 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
  14. Ajoutez dans « public/session-managed-select.php » un appel à la méthode « setSelectedCodeFromSession() » de la classe « SessionManagedCountrySelect » juste avant l'appel de « setSelectedCodeFromRequest() »
  15. 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
  16. 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
  1. Dans le constructeur de la classe « Html\Form\SessionManagedCountrySelect », appelez successivement les méthodes « setSelectedCodeFromSession() », « setSelectedCodeFromRequest() » et « saveSelectedCodeIntoSession() »
  2. Supprimez les appels aux méthodes « setSelectedCodeFromSession() », « setSelectedCodeFromRequest() » et « saveSelectedCodeIntoSession() » dans « public/session-managed-select.php »
  3. 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.