2.5 Sessions 103 echo "<input type=’submit ’ value=’Exécuter ’/>\n"; echo "</form>\n"; } ?> La figure 2.6 montre le formulaire affiché par le script ExSession.php, avec les entrées. Voicilecodedecescript. Figure 2.6 — Le formulaire, au début de la session Exemple 2.29 exemples/ExSession.php : Exemple de commande avec session <?php if ( i s S e t ($_COOKIE [ ’ i d _ s e s s io n ’ ] ) ) { // L’identifiant de session existe déjà $ id _ s e s s i o n = $_COOKIE [ ’ i d _ s es s io n ’ ] ; } else { // Créons un identifiant $id_session = $_SERVER[ ’REMOTE_ADDR’] . date("U"); // Envoi du cookie SetCookie (" id_session " , $id_session) ; } ?> <?xml version=" 1.0 " encoding=" iso −8959−1"?> <!DOCTYPE html PUBLIC " −/ /W3C / / DTD XHTML 1 . 0 S t r i c t / / EN " "http ://www.w3. org /TR/xhtml1/DTD/xhtml1−strict .dtd"> <html xmlns="http ://www.w3. org/1999/xhtml" xml:lang=" fr"> <head> 104 Chapitre 2. Techniques de base <title >Une commande au restaurant </title > < link rel=’stylesheet ’ href="films . css" type="text/ css" /> </head> <body> <h1>Faites votre commande au restaurant </h1> <?php require_once ("Connect.php"); require_once ("Connexion.php"); require_once ("ExecRequete.php"); require_once ("Normalisation .php"); require_once ("FormCommande.php"); // Connexion à la base $connexion = Connexion (NOM, PASSE, BASE, SERVEUR) ; // Normalisation des entrées HTTP Normalisation() ; // Si le type de choix n’ est pas défini : on commence // par proposer les entrées if (! isSet($_POST[ ’type_choix ’ ]) ) { echo "Bonjour . Nous vous avons attribué la session $id_session <br/>" ; FormCommande ("Entrée " , " ExSession .php" , $connexion) ; } else { // Insérons dans la table le choix qui vient d’être fait // Il faudrait tester que id_choix est défini $requete = "INSERT INTO Commande (id_session , id_choix) " . "VALUES ( ’ $ i d _ s e s s i o n ’ , ’ { $_POST [ ’ i d _ c h o i x ’ ] } ’ ) " ; ExecRequete ($requete , $connexion) ; // Affichage des choix déjà effectués $ r eq u et e = "SELECT C2 . ∗ FROM Commande C1 , Carte C2" . " WHERE id_session =’$id_session ’ AND C1. id_choix=C2. id_choix" . " ORDER BY C2. id_choix "; $resultat = ExecRequete ($requete , $connexion) ; while ($choix = ObjetSuivant ( $resultat)) echo "Vous avez choisi : $choix−>libelle <br/>\n"; // Affichage de la suite if ($_POST[ ’type_choix ’ ] == ’Entrée ’) { FormCommande (" Plat " , " ExSession .php" , $connexion) ; } else if ($_POST[ ’type_choix ’] == ’Plat ’) { FormCommande (" Dessert" , "ExSession . php" , $connexion) ; } else { // Traitement de la commande complète . Ici on détruit 2.5 Sessions 105 echo "Nous avons noté votre commande. Merci !<br/>" ; $ r e qu et e = "DELETE FROM Commande WHERE i d _ s e s si o n = ’ $id_session ’" ; ExecRequete ($requete , $connexion) ; } } ?> </body> </html> La première partie est relativement analogue à celle du premier exemple avec cookies, page 99. Si l’identifiant de session existe, on le conserve. Sinon on le calcule, et on crée le cookie pour le récupérer aux accès suivants. Pour l’identifiant, nous avons choisi ici simplement de concaténer l’adresse IP du client et le temps « Unix » lors de la première connexion (nombre de secondes depuis le 01/01/1970). Il y a raisonnablement peu de chances que deux utilisateurs utilisent la même machine au même moment (sauf cas où, par exemple, plusieurs dizaines de personnes accèdent simultanément au site derrière une passerelle unique). Cela suffit pour cet exemple simple. Pour la suite du script, on dispose de l’identifiant de session dans la variable $id_session. On affiche alors successivement le formulaire pour les entrées, les plats puis les desserts. À chaque fois, on insère dans la table Commande le choix effectué précédemment, et on récapitule l’ensemble des choix en les affichant dans la page HTML. C’est toujours l’identifiant de session qui permet de faire le lien entre ces informations. Notez que la requête SQL qui récupère les choix de la session courante est une jointure qui fait appel à deux tables. Si vous ne connaissez pas SQL, les jointures sont présentées dans le chapitre 7, page 289. Le langage SQL dans son ensemble fait l’objet du chapitre 10. Les figures 2.7 et 2.8 montrent respectivement le formulaire après choix de l’entrée et du plat, et après le choix du dessert. Dans ce script, nous devons intégrer des éléments d’un tableau associatif dans une chaîne de caractères. Quand il s’agit d’une variable simple, le fait que le nom de la variable soit préfixé par « $ » suffit pour que PHP substitue la valeur de la variable. C’est moins simple pour un tableau associatif. On ne peut pas écrire en effet : echo " Ceci est un ´el´ement de tableau : $tab[’code’] "; //Pas correct Il existe deux manières correctes de résoudre le problème. Première solution, une concaténation : echo " Ceci est un ´el´ement de tableau : ". $tab[’code’]; //Correct Seconde solution : on encadre par des accolades l’élément du tableau pour qu’il n’y ait plus d’ambiguïté. echo " Ceci est un ´el´ement de tableau : {$tab[’code’]} "; //Correct Quand le dessert a été choisi, la session est terminée. Il faudrait alors demander confirmation ou annulation, et agir en conséquence dans la base de données. Ici nous nous contentons de détruire la commande, tâche accomplie ! 106 Chapitre 2. Techniques de base Figure 2.7 — Après choix du plat et de l’entrée Figure 2.8 — Le menu est choisi 2.5.3 Prise en charge des sessions dans PHP PHP fournit un ensemble de fonctions pour faciliter la gestion des sessions. Ces fonctions permettent, pour l’essentiel : 1. d’engendrer automatiquement un identifiant de session, et de le récupérer à chaque nouvel accès ; 2.5 Sessions 107 2. de stocker des informations associées à la session (par défaut le stockage a lieu dans un fichier temporaire) ; 3. de détruire toutes ces informations une fois la session terminée. Dans la mesure où nous utilisons une base de données, une partie des fonctions de gestion de session, notamment celles qui consistent à conserver des informations sur les interactions passées de l’utilisateur, peuvent être avantageusement remplacées par des accès MySQL. L’intérêt est essentiellement de mieux protéger les accès aux donnés enregistrées dans le cadre de la session. Nous allons donc nous contenter des fonctions PHP essentielles à la gestion de session, données ci-dessous : Fonction Description session_start() Initialise les informations de session. Si aucune session n’existe, un identifiant est engendré et transmis dans un cookie.Silasession (connue par son identifiant) existe déjà, alors la fonction instancie toutes les variables qui lui sont liées. Cette fonction doit être appelée au début de tout script utilisant les sessions (il faut que l’instruction Set-Cookie puisse être placée dans l’en-tête HTTP). session_destroy() Détruit toutes les informations associées à une session. session_id() Renvoie l’identifiant de la session. En général, un script PHP intégré dans une session débute avec session_start(), qui attribue ou récupère l’identifiant de la session (un cookie nommé PHPSESSID). On peut associer des variables à la session en les stockant dans le tableau $_SESSION. Une fois qu’une variable a été associée à une session, elle est automatiquement recréée et placée dans le tableau $_SESSION à chaque appel à session_start(). On peut la supprimer avec la fonction unset(), qui détruit une variable PHP. Enfin, quand la session est terminée, session_destroy() supprime toutes les variables associées (équivalent à un appel à unset() pour chaque variable). Le script ci-dessous montre la gestion d’une session, équivalente à la précédente, avec les fonctions PHP. Exemple 2.30 exemples/SessionPHP.php : Gestion de session avec les fonctions PHP <?php // La fonction session_start fait tout le travail session_start () ; ?> <?xml version=" 1.0 " encoding=" iso −8959−1"?> <!DOCTYPE h t m l PUBLIC " −/ /W3C / / DTD XHTML 1 . 0 S t r i c t / / EN " "http ://www.w3. org /TR/xhtml1/DTD/xhtml1−strict .dtd"> <html xmlns="http ://www.w3.org/1999/xhtml" xml: lang=" fr " > <head> <title >Une commande au restaurant </title > < link rel=’stylesheet ’ href="films. css" type="text/ css"/> </head> <body> . l’objet du chapitre 10. Les figures 2.7 et 2.8 montrent respectivement le formulaire après choix de l’entrée et du plat, et après le choix du dessert. Dans ce script, nous devons intégrer des éléments. Traitement de la commande complète . Ici on détruit 2.5 Sessions 105 echo "Nous avons noté votre commande. Merci !<br/>" ; $ r e qu et e = "DELETE FROM Commande WHERE i. fournit un ensemble de fonctions pour faciliter la gestion des sessions. Ces fonctions permettent, pour l’essentiel : 1. d’engendrer automatiquement un identifiant de session, et de le récupérer à chaque