TP04 : SESSION et Organisation du code

Transcription

TP04 : SESSION et Organisation du code
TP04 : SESSION et Organisation du code
Le but de cette séance est d’avoir un premier contact avec les sessions. Cela se fera progressivement :
1.
Ouverture de session............................................................................................................................. 2
2.
Organisation du code : partage d’une fonction .................................................................................... 2
3.
Un formulaire ........................................................................................................................................ 3
4.
Contenu conditionné à une variable de session ................................................................................... 3
5.
Redirection conditionné à une variable de session............................................................................... 4
6.
Remplacement de la redirection par le formulaire ............................................................................... 5
7.
Un début de navigation ......................................................................................................................... 7
8.
Facilité d’ajout d’un page ...................................................................................................................... 8
Les principales nouveautés utilisées dans ce tp, dans l’ordre d’apparition, sont : $_SESSION, function,
include, form (html), $_POST, header, $_SERVER.
Finir la partie 5 « Redirection conditionné à une variable de session » est l’objectif pour la première
séance de ce tp.
Finir le tp est l’objectif pour la seconde séance sur ce tp.
Pour cette séance, vous ferez tous vos fichiers dans un dossier tp04. Récupérez l’archive de départ
tp05.zip.
Celle-ci contient les fichiers initiaux qu’il faudra modifier. Il y a un peu de css pour la mise en forme du
code, un fichier index.php qui comprend l’énoncé de deux exercices (ceux du TP01) et un fichier
confidentiel.php qui contient la correction de l’exercice 1.
L’objectif du tp est de contrôler l’accès à certaines pages (par exemple confidentiel.php).
Placez le code php en début de fichier, à l’exception des « echo » qui devront être placés au bon endroit
dans la page.
Avertissement : ce tp ne traite pas de la sécurité. Ici il n’y en a aucune…
1. Ouverture de session
Il s’agit ici de simplement d’ouvrir une session. Ce qui suit est à faire dans index.php et dans
confidentiel.php.
Ceci se fera par les appels EN DEBUT DE FICHIER des fonctions : session_name (pour différencier votre
session de celle des autres) et session_start pour la démarrer.
Considérons une variable de session « connexion », manipulable donc par $_SESSION["connexion"] et
une variable $etat_connexion.
Si la variable $_SESSION["connexion"] existe (test avec isset) et qu’elle vaut 2412, alors $etat_connexion
vaut "<p>connecté</p>" ; $etat_connexion vaut sinon "<p>non connecté</p>". A la fin de l’entête de la
page (juste avant </header>), afficher la variable $etat_connexion.
Pour l’instant, vous n’êtes pas connecté. Pour essayer, vous pouvez rajouter l’une des lignes suivantes (et
raffrichissez vos pages) :
$_SESSION["connexion"] = 1234;
// ou
$_SESSION["connexion"] = "autre chose";
// ou
unset($_SESSION["connexion"]);
2. Organisation du code : partage d’une fonction
Vous l’aurez remarqué, vous avez écrit deux fois la même chose dans index.php et dans confidentiel.php.
Ce code, plutôt que le dupliqué, vous allez le « factoriser », c’est-à-dire l’écrire une fois et le partager
dans les deux pages.
Créez un fichier connexion.inc. A l’intérieur vous éditez du php (dans les pseudo-balises < ?php et ?>).
Démarrez la session (appel à session_name puis à session_start). Définissez également une fonction
estOnConnecte. Elle est sans paramètre. Elle retourne une chaîne de caractère qui vaut
"<p>connecté</p>" si la variable $_SESSION["connexion"] existe (test avec isset) et qu’elle vaut 2412 ;
sinon la fonction estOnConnecte retourne "<p>non connecté</p>" .
Dans index.php et dans confidentiel.php, remplacer le début de vos fichiers par l’inclusion de
connexion.inc (include ou require), et remplacez le « calcul » de $etat_connexion par un appel à la
fonction estOnConnecte.
Si tout est correct, il n’y a pas de différence avec la question précédente, mais maintenant, vous pourrez
faire évoluer le code en un seul endroit.
3. Un formulaire
Pour pouvoir modifier la variable de session, c’est-à-dire pour permettre au visiteur de la page de se
connecter, vous allez ajouter un formulaire en fin de <header> dans index.php.
Ce formulaire a pour destination (action) la page index.php, la méthode de transmission des données est
post. Le formulaire (illustrée par la Figure 1 ) contiendra :



Un input de type texte pour entrer un code, son nom (name) est « code »
Un label qui se rapporte à l’input pour indiquer ce qu’il faut faire (« entrez le code »)
Un input de type submit pour valider (envoyer) le formulaire. Son nom est « connexion » et sa
valeur (value) est « Validez ».
En début de page index.php, dans le code php, entre l’inclusion de connexion.inc et l’appel à
estOnConnecte, il faut réceptionner le formulaire : si les variables $_POST["connexion"] et
$_POST["code"] existent, que leurs valeurs sont respectivement « Validez » et « 2412 » (ici, c’est une
chaine de caractères), alors affecter à $_SESSION["connexion"] la valeur de $_POST["code"] convertie en
entier (intval).
Maitenant, vous pouvez vous connecter dans index.php, mais vous ne pouvez pas le faire d’ailleurs, ni
vous ne pouvez vous déconnecter. Commençons par la déconnexion.
4. Contenu conditionné à une variable de session
L’objectif est le suivant : dans index.php (et uniquement dans index.php), si on n’est pas connecté, on
affiche un formulaire pour entrer le code, comme l’illustre la Figure 1 :
Figure 1. Formulaire pour saisir le code
Figure 2. Formulaire de déconnexion
Au contraire, si on est connecté, la Figure 2 illustre ce qu’il faut afficher :
Vous devez donc modifier index.php en consequence :


Il faut pouvoir recevoir deux formulaires différents. Pour cela, faites des tests sur les variables
contenues (ou pas) dans $_POST. Un cas est déjà fait…
Le code pour se déconnecter (et finir une session) est le suivant :
Le code pour se déconnecter est le suivant :
// il faut detruire la session : copier coller de php.net...
// La session est deja initialisee
// Detruit toutes les variables de session
$_SESSION = array();
// Si vous voulez detruire completement la session, effacez egalement
// le cookie de session.
// cela detruira la session et pas seulement les donnees de session !
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000, '/');
}
// Finalement, on detruit la session.
session_destroy();
// on termine par la redirection
header("Location: index.php");

Il faut écrire un formulaire ou un autre selon les cas :
o Transformer estOnConnecte dans connexion.inc pour que la fonction retourne un
boolean (et non plus une chaine de caractère) : vrai si on est connecté, faux sinon.
 Notez que confidentiel.php n’affichera plus que 1 ou rien pour $etat_connexion,
ceci sera modifié plus tard.
o Dans index.php, initialisez une variable $nav à "". Selon l’état de la connexion, affectez à
cette variable :
 Le formulaire déjà écrit si on n’est pas connecté (vous pouvez utiliser un
heredoc)
 Ou bien un lien vers confidentiel.php et un formulaire (qui se limite à un bouton
« se déconnecter ») si on est connecté
 Dans les deux cas, le tout est contenu dans une balise <nav>
o Cette variable $nav est à afficher dans le « <header> », à la place de l’affichage de
$etat_connexion (qui ne sert plus).
Si cela fonctionne, vous pourrez vous connecter et vous déconnecter depuis index.php. Mais rien ne
vous interdit d’aller sur la page confidentiel.php, même si vous n’êtes pas connectés. C’est ce qui sera
fait dans la prochaine partie.
5. Redirection conditionné à une variable de session
Dans cette partie, vous allez modifier dans un premier temps confidentiel.php. L’idée est d’interdire
l’accès à la page si on n’est pas connecté. Ainsi donc, vous allez modifier le début de confidentiel.php
pour tester la connexion (avec estOnConnecte). Si on ne l’est pas, il faut rediriger (header) vers
index.php. Pour être sûr de ne pas afficher la page, après la redirection, vous ajouterez un « return ; ».
Pour indiquer un message d’erreur à l’utilisateur, vous allez utiliser une variable de session,
$_SESSION["erreur"]. Toujours dans confidentiel.php, juste avant la redirection, ajoutez :
$_SESSION["erreur"] = "vous devez entrer le code avant d'aller sur la
correction.";
Dans index.php, il faut alors traiter ce message d’erreur : il faut tester si la variable de session
$_SESSION["erreur"] existe. Si oui, il faut préparer un paragraphe de classe « erreur » (dans une variable
$erreur) pour l’afficher plus tard (dans le <header>) et il faut détruire cette variable de session (unset sur
la variable). En cas d’accès « non autorisé » à confidentiel.php, on obtiendra un résultat semblable à la
Figure 3.
Figure 3. Redirection en cas d'accès non autorisé
Avec un traitement similaire, ajoutez un message d’erreur si on n’entre pas le bon code, comme l’illustre
la Figure 4.
Figure 4. Message d'erreur en cas de mauvais code
6. Remplacement de la redirection par le formulaire
La solution précédente, avec la redirection est une possibilité pour contrôler l’accès. L’autre possibilité
est d’afficher le formulaire de connexion (et rien de plus) en cas de tentative d’accès à confidentiel.php.
Pour cela, il faut grandement modifier la structure du code php. Tout ce qui est génération de
formulaire(s) et réception de formulaire(s) sera commun aux deux pages index.php et confidentiel.php, il
faut donc déplacer ce code dans connexion.inc et le fournir sous forme de fonction (pour qu’il soit
exécuté sur demande et non pas automatiquement).
Il y a donc une première fonction receptionFormulaires qui pourra recevoir les deux formulaires (de
connexion ou de déconnexion). Cette fonctionne ne retourne rien (aucune valeur).
Pour simplifier le code des pages web (comme index.php et confidentiel.php), vous allez aussi faire une
fonction qui génère non seulement la génération de formulaire (de connexion ou de déconnexion) mais
aussi tout le début des pages : du « < !doctype html> » jusqu’à « </header> ». En fait, les pages sont
structurées de la façon suivante :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>TITRE QUI CHANGE SELON INDEX OU CONFIDENTIEL</title>
<link rel="stylesheet" href="code.css" type="text/css" />
</head>
<body>
<header>
<h1> TITRE (le même que dans <title>) </h1>
<p> MESSAGE QUI CHANGE SELON INDEX OU CONFIDENTIEL <p>
Eventuellement : un message d’erreur de connexion, si le code n’est pas le bon
<nav>
FORMULAIRE SELON L’ETAT DE LA CONNEXION
</nav>
</header>
Puis il y a le reste de la page.
Il est donc possible de faire une fonction genererEntetes qui retourne une chaine de caractère contenant
ce début de page, en ayant en paramètre :
-
$titre pour le titre (qui sert pour le <title> et pour le <h1>) et
$msgHeader pour le message (dans le <p> dans le <header>)
Les étapes de genererEntetes sont :
1. Initialisation de la variable dont la valeur sera retournée ($entetes).
2. La génération du début du fichier (jusqu’au <h1> inclus). C’est mémorisé dans $entetes.
3. L’insertion du message ($msgHeader) dans une balise <p>. C’est concaténé (ajouté à la fin de) à
$entetes.
4. L’insertion éventuelle d’un message d’erreur (code faux). S’il y a lieu, c’est concaténé (ajouté à la
fin de) à $entetes.
5. La génération du formulaire adéquate (en fonction de la connexion). C’est concaténé (ajouté à la
fin de) à $entetes.
6. Ajout de la balise fermante </header> à la fin de $entetes.
7. Fin de la fonction avec « return $entetes ; »
Modifiez les débuts des fichiers index.php et confidentiel.php :
-
-
Pour index.php, l’accès est toujours possible, le cas est simple : inclusion de connexion.inc, appel
à receptionFormulaires, appel à genererEntetes (avec les paramètres adéquats) puis affichage du
résultat de cette dernière fonction. Le reste est du html
Pour confidentiel.php, c’est un peu plus compliqué. On commence aussi par l’inclusion de
connexion.inc et l’appel à receptionFormulaires. Par contre, ensuite, il y a deux cas de figures :
o On n’est pas connecté. Dans ce cas, il faut un message d’erreur (il faut se connecter pour
voir la correction), on génère les entêtes genererEntetes, on ajoute au résultat les balises
fermantes </body> et </html>. On affiche cela et on finit la page en appelant « return ; »
o Sinon, on est connecté. Dans ce cas, il faut faire appel à genererEntetes (avec les
paramètres adéquats) puis afficher le résultat de cette dernière fonction. Le reste est du
html
7. Un début de navigation
Dans la solution actuelle, une fois connecté, il est affiché : un lien vers la correction et un bouton pour se
déconnecter. Mais il n’est pas possible d’une page à l’autre, si ce n’est en modifiant l’adresse dans la
barre d’adresse (ou en utilisant le bouton back du navigateur).
L’objectif est d’ajouter une navigation :


Qui liste les deux pages [index.php / l’énoncé] et [confidentiel.php / la correction de l’exo 1]
Qui met en valeur la page courrante, par exemple si on est sur la page index, comme l’ill
Figure 5. Navigation sur le site, ici dans la page index.php

Et qui affiche toujours le bouton « déconnexion » (cela ne change pas par rapport à avant).
Les modifications sont à faire dans la fonction genererEntetes. Comme cette fonction est utilisée par les
deux pages index.php et confidentiel.php, la répercussion sera visible sur les deux. Il faut donc remplacer
la génération de la liste <ul> (dans la balise <nav>). Pour cela, faites un tableau $liens. Il contient deux
cases, la première pour un lien vers l’index, par exemple "<a href='index.php'>énoncé des deux exo</a>"
et la seconde vers confidentiel.php : "<a href='confidentiel.php'>correction de l'exo 1</a>". En fonction
de la page en cours, il faudra ajouter une balise <mark> autour du <a> correspondant. Pour savoir sur
quelle page on est, il faut exploiter $_SERVER['PHP_SELF'] qui contient le chemin (depuis la racine du
site) vers la page actuelle (elle comprise). L’utilisation de la fonction explode avec le caractère ‘/’
permettra de trouver le nom de la page.
A vous d’exploiter ce tableau, avec une boucle for/foreach ou une suite de if (comme vous préférez),
pour générer la liste de lien.
8. Facilité d’ajout d’un page
Pour finir, ajoutez une page à ce mini-site. Cette page est confidentiel2.php, disponible dans l’archive
confidentiel2.zip (il faut l’extraire de l’archive).
Modifiez cette page confidentiel2.php, à l’instar de confidentiel.php, pour l’insérer dans la navigation et
en restreindre l’accès.
Vous devez donc modifier connexion.inc pour l’inclure dans la navigation (et la mettre en valeur si on est
sur cette page) quand on est connecté.
La Figure 6 et Figure 7 illustrent l’insertion de cette page dans le site.
Figure 6. Accès à confidentiel2.php sans être connecté
Figure 7. Accès une fois connecté