Les Sessions

Vous êtes ici : >> PHP / Les Sessions
Temps d'étude : 1h. Niveau : Moyen.
Tags : Les Sessions
Fichier(s) utile(s) pour ce cours : /

Objectifs
fléche Conserver et échanger des informations avec un internaute.

Qu'est-ce qu'une session ?

Une session est un système mis en oeuvre dans le code PHP permettant de conserver sur le serveur, dans un fichier temporaire, des informations relatives à un internaute.

L'avantage d'une session c'est que les données seront enregistrées dans un fichier sur le serveur disponible et consultable par toutes les pages durant toute la navigation de l'internaute.


Contexte : Quels sont les cas d'utilisation ?

Habituellement pour sauvegarder des données, nous enregistrons des informations dans une base.

Mais nous ne devons pas avoir toujours recours à une base de données, parfois il est utile de sauvegarder des informations dans 1 fichier (1 fichier de session).

Exemple pour un panier :
Nous ferons le panier d'un site ecommerce avec un système de session.
Nous n'enregistrerons pas les produits ajoutés au panier dans une base de données puisque la plupart du temps les paniers ne sont pas payés (les internautes ne finalisent pas toujours la commande). Cela évitera de "polluer" la base de données pour rien. En revanche, (si le panier et le paiement sont validés) la commande sera enregistrée dans une base de données.

Exemple avec la connexion d'un internaute (membre) :
fléche Lorsqu'un internaute s'inscrit à 1 site, nous l'enregistrons dans une base de données.
fléche Lorsqu'il se connecte (avec le bon pseudo et le bon mot de passe), nous gardons l'information (comme quoi l'internaute est actuellement connecté) en mémoire dans 1 fichier de session.
En effet, nous n'allons pas solliciter une éventuelle table de la base "internaute_actuellement_connecte" car cela change souvent et les requêtes sql pour cette tâche allourdiraient le site web.

Plus généralement, voici des cas d'utilisation :
  • La connexion d'un membre à un site web.
  • Le panier d'un site ecommerce (vente en ligne).
  • Les formulaires à plusieurs étapes.
  • D'autres informations générales. Cela peut être marketing (derniers produits vus, suggestions de produits adaptés aux préférences de l'internaute selon sa navigation), etc.
Pour conclure, nous utiliserons les sessions pour sauvegarder des informations temporaires et garderons l'utilisation de base de données pour sauvegarder des informations durables.


A quoi ça sert ?

Comme vous l'aurez compris, les sessions en PHP vont nous permettre de conserver des informations sur un internaute côté serveur.

Sans ce mécanisme, vous ne pourriez pas connecter un internaute à votre site et maintenir sa connexion durant la navigation (de page en page).

De la même manière, lorsqu'un internaute ajoute des produits dans un panier (ecommerce), comment se fait-il que les produits soient toujours présents en mémoire même lorsque vous naviguez de page en page (pour partir et revenir du panier), ce n'est pas magique, là aussi ce sont grâce aux sessions !

1 page (ou fichier) représente 1 script qui s'exécute une fois, puis l'internaute se déplace dans le site pour se rendre vers un autre contenu (ce qui exécute 1 autre script).
Pour ne pas que les informations se perdent d'une page à un autre (d'un fichier script à un autre), nous utiliserons les sessions !

Comment cela fonctionne ?

2 besoins reviennent régulièrement :
  • Créer 1 fichier de session pour une première utilisation
  • Lire 1 fichier de session existant pour une seconde (ou énième) utilisation.
La bonne nouvelle c'est que pour ces 2 actions nous utiliserons la même fonction prédéfinie de PHP !

Pour créer ou lire un fichier de session, nous utiliserons la fonction prédéfinie session_start().

session1.php
		<?php
		session_start();
		

Quelques Explications :

session_start() permet de créer un fichier de session ou de l'ouvrir s'il existe déjà.

Où se trouve les fichiers de session ?

Les fichiers de session se trouvent sur le serveur, dans un dossier nommé /tmp/ (tmp pour temporaire).

Etant donné que nous possédons un serveur web local (sur notre pc), vous pourrez vous rendre à l'emplacement de wamp.
En passant dans "ordinateur", voici des chemins d'exemple : c:/wamp/tmp/ ou c:/programmes/wamp/tmp/

Votre page de code session1.php restera vierge mais pas votre dossier /tmp/ puisque vous devriez y retrouver un fichier temporaire :

Résultat
explication PHP
Nous avons donc 1 fichier temporaire sur le serveur.

Si nous avons plusieurs internautes différents, nous aurons donc plusieurs fichiers de session.

Comment le serveur peut savoir à qui appartient tel ou tel fichier ?

Pour cela, nous allons avoir besoin de créer des cookies, des cookies de session !

Et bonne nouvelle, c'est déjà fait ! Lorsque nous utilisons session_start(), cela crée 1 fichier de session (sur le serveur) mais aussi 1 fichier cookie (sur l'ordinateur de l'internaute), comme si nous avions utilisé setCookie() !

Résultat
Exécuter la page session1.php et ensuite pour voir le cookie apparaitre (sous le navigateur mozilla firefox), vous pouvez vous rendre dans la partie suivante : Outils > Options > Vie privée > Régle de conservation : Utiliser les paramètres personnalisés pour l'historique > Afficher les cookies.

explication PHP

explication PHP

explication PHP


A noter : Le nom du fichier de session correspond au contenu du fichier cookie, dans mon cas : qtscf8bkkkqirmqchaffuov7t5

C'est ce qui permet de les relier ensemble !

explication PHP

Dans le cas d'un panier (sur un site ecommerce), les informations relatives aux produits seront conservées dans le fichier de session (sur le serveur) et seront reliées à l'internaute grâce au cookie.

Si l'internaute supprime son cookie, cela "casse" le lien avec le fichier de session (le panier sera donc vide, vous pouvez essayer ça sur nimporte quel site web).

De la même manière, ce système (session+cookie) permet de maintenir une connexion à un site web. L'internaute ne peut pas supprimer le fichier de session (puisqu'il n'a pas accès au serveur) mais il peut supprimer son cookie (sur son ordinateur) et donc la connexion sera perdue (pour faire le test : n'hesitez pas à supprimer vos cookies, vous perdrez toutes vos connexions en cours).



Pour résumé :
session_start() permet de créer un fichier de session (ou de l'ouvrir s'il existe déjà), mais aussi de créer un cookie (ou s'il existe déjà, de le relier à un fichier de session déjà existant).

Il faut toujours utiliser le code session_start() au plus haut de la page et si possible dans les toutes premières lignes !

Pour ne pas obtenir une erreur PHP du type : "Cannot modify header information - headers already sent by ...", ou encore "Cannot send session cookie - headers already sent by ...". Il faut éviter d'inscrire une balise html, un espace, ou une instruction d'affichage du type "echo, print, var_dump, print_r", etc. avant session_start().


Ecrire dans 1 fichier de session

Maintenant que nous avons obtenu 1 fichier de session, l'objectif est de conserver des données et donc pour cela d'écrire des informations.

Pour cela, une superglobale $_SESSION est prévue à cet effet.

Toutes les superglobales sont (par défaut) ARRAY, nous utiliserons donc des crochets pour y inscrire des valeurs.

session1.php
		<?php
		session_start();
		$_SESSION['pseudo'] = "Mathieu";
		$_SESSION['mdp'] = "Balmont";
		print_r($_SESSION);
		

Quelques Explications :

$_SESSION['pseudo'] = "Mathieu"; La présence des crochets permet d'affecter des valeurs dans le tableau array superglobale $_SESSION.

print_r($_SESSION); L'instruction print_r permet d'afficher le contenu d'un tableau ARRAY et, dans notre cas, d'explorer la superglobale $_SESSION.

Retournons dans notre dossier /tmp/ (présent à l'intérieur de wamp).

Résultat
explication PHP

Ouvrons ce fichier (clic droit > éditer avec notepad++) :

pseudo|s:7:"Mathieu";mdp|s:7:"Balmont";
s correspond à string (chaine de caractère)
7 correspond à la taille du string (taille de la chaine de caractère)

Créons un deuxième fichier, qui n'a aucun rapport, et qui peut être placé dans le même dossier ou ailleurs sur le serveur (prenez l'emplacement de votre choix dans le repertoire www).
Nous nommerons ce fichier : bonjour.php

bonjour.php
		<?php
		session_start();
		echo 'Bonjour ' . $_SESSION['pseudo'] . '
';

Résultat

Bonjour Mathieu


Ce fichier n'a rien à voir avec l'autre, il n'y a pas d'inclusion, il pourrait être dans un autre dossier, s'appeler nimporte comment, les informations contenues seraient quand même accessibles ! c'est la puissance et l'interêt des sessions !

Quelques Explications :

Ca fonctionne ! mais ce n'est pas magique, voici l'explication :
Dans notre cas, session_start(); permet d'ouvrir le fichier de session présent dans le dossier /tmp/ (il n'est pas créé ou recréé puisqu'un fichier de session relié au cookie de l'internaute existe déjà).

echo 'Bonjour ' . $_SESSION['pseudo'] . '
';
Avec ce code, nous affichons le pseudo gardé en mémoire dans le fichier de session.
Nous pouvons le traduire par (echo) affiche moi, (bonjour) bonjour, (.) suivi de..., ($_SESSION['pseudo']) le pseudo conservé dans la session

Pour conclure, après avoir utilisé session_start() pour travailler avec les sessions, la superglobale $_SESSION nous permet d'intéroger le fichier de session sur le serveur (présent dans le dossier /tmp/).

L'avantage c'est que les informations contenues dans le fichier de session seront disponibles sur tout le site durant la navigation de l'internaute !

C'est la raison pour laquelle vous etes parfois toujours connecté lorsque vous retournez sur un site web.

Le fichier bonjour.php pourrait retourner une erreur si la session était détruite car en l'absence d'une condition IF, nous tenterons toujours d'afficher le pseudo contenu dans la session, il y a donc 1 risque d'erreur unedfined.


Vider une partie du fichier de session

Pour vider un fichier de session, nous utilisons la fonction prédéfinie unset() :
session1.php
		<?php
		session_start();
		$_SESSION['pseudo'] = "Mathieu";
		$_SESSION['mdp'] = "Balmont";
		print_r($_SESSION);
		unset($_SESSION['mdp']);
		print_r($_SESSION);
		

Quelques Explications :

unset($_SESSION['mdp']); permet de vider la partie "mdp" (mot de passe).
Rouvrez le contenu de votre fichier temporaire (dossier /tmp/, présent à l'intérieur de wamp).

Résultat
explication PHP

Ouvrons ce fichier (clic droit > éditer avec notepad++) :

pseudo|s:7:"Mathieu";



Supprimer un fichier de session

Pour supprimer un fichier de session, nous utilisons la fonction prédéfinie session_destroy() :
session1.php
		<?php
		session_start();
		$_SESSION['pseudo'] = "Mathieu";
		$_SESSION['mdp'] = "Balmont";
		print_r($_SESSION);
		unset($_SESSION['mdp']);
		print_r($_SESSION);
		session_destroy();
		print_r($_SESSION);
		


Quelques Explications :

session_destroy(); permet de supprimer physiquement le fichier de session dans le dossier /tmp/ et donc toutes les informations contenues dans le fichier.

Petite particularité : il faut savoir que le session_destroy() est vu par l'interpréteur, gardé, puis exécuté qu'à la fin du script.

C'est la raison pour laquelle le dernier print_r vous donnera toujours accès aux informations de la session car l'exécution du script n'est pas terminé.

Cependant, si vous retourner dans votre dossier /tmp/, présent à l'intérieur de wamp, vous verrez que le fichier n'existe plus !

explication PHP


Explications supplémentaires

Comment se fait-il, techniquement, que quand vous vous rendez sur un site et que vous mettez le bon pseudo et le bon mdp, vous restez connecté pendant 1h si votre navigation dure 1h ? pourquoi on ne vous demande pas de vous reconnecter à chaque changement de page ? ...car il existe une session prouvant que vous êtes déjà passé par la porte d'entrée (vous êtes déjà identifié) ! Sans session, la connexion ne serait pas maintenue.

Les informations d'une session sont enregistrées dans la session coté serveur, cela crée (dans le même temps) un cookie précisement à l'identifiant de la session, sur le pc du client.

C'est la raison pour laquelle nous enregistrerons le prix d'un panier dans un fichier de session, de cette manière il ne pourra pas être modifié (par l'internaute) car il s'agit d'un fichier enregistré directement sur le serveur du site. Et, dans le cookie nous reliant au site, nous retrouverons uniquement l'identifiant qui permet de mener à la bonne session (la notre).

Si le prix d'un panier était enregistré dans le cookie, l'internaute pourrait le modifier car il s'agit d'un fichier sur son ordinateur.

Sur 1 site web il peut y avoir des dizaines, des centaines, des milliers ou des millions de sessions, il ne suffit pas d'en créer 1 à un internaute, il faut aussi que l'internaute soit relié à la sienne, c'est donc aussi grâce au cookie que le lien est établi. Si l'internaute supprime son cookie ou si le site décide de supprimer la session : le lien est cassé.

Quand vous effectuer un session_start(), un fichier de session est créé coté serveur (/tmp/) et un cookie de session est créé automatiquement coté client (pc) afin que le lien entre le site et le pc de l'internaute soit bien établit.

Quand vous cliquez sur "se déconnecter" :
fléche cela effectue un "unset()" pour vider votre partie de membre mais quand même conserver le reste des informations (produit dans le panier par exemple).
fléche cela peut aussi effectuer un "session_destroy()" pour supprimer le fichier de session complétement.

TOUS les sites qui vous proposent une connexion fonctionne avec les sessions. N'hesitez donc pas à relire ce chapitre s'il n'est pas parfaitement clair.



Exemple d'un formulaire avec session

Pour mieux comprendre le système de session, munissons-nous d'un formulaire simple.

formulaire_session.php
		<?php
		session_start();
		if($_POST)
		{
			$_SESSION["pseudo"] = $_POST['pseudo'];
		}
		//--------------------------------------
		if(isset($_SESSION['pseudo']))
		{
			echo "votre pseudo est: " . $_SESSION['pseudo'] . "
"; } else { echo '


'; }


Quelques Explications :

session_start(); nous permet de créer 1 fichier de session la première fois (et de l'ouvrir les fois suivantes).

if($_POST) permet de déclarer une condition "si l'internaute à posté en cliquant sur le bouton submit", nous rentrons dans les accolades du IF et exécutons le code présent
- Enregistrement du pseudo posté par l'internaute via le formulaire, dans le fichier de session.

if(isset($_SESSION['pseudo'])) permet de déclarer une condition "si un pseudo est défini dans le fichier de session de l'internaute", nous rentrons dans les accolades du IF et exécutons le code présent
- Affichage du pseudo de l'internaute conservé dans le fichier de session.

else (ce else se réfère au IF précédent) permet de déclarer un cas par défaut "si aucun pseudo n'est défini dans le fichier de session de l'internaute", nous rentrons dans les accolades du ELSE et exécutons le code présent
- Affichage d'un formulaire.

Résultat
explication PHP

explication PHP


Le formulaire sera affiché tant qu'un pseudo n'est pas saisi, posté, et conservé dans le fichier de session.

Lorsqu'un pseudo est conservé dans le fichier de session, le formulaire n'apparait plus.

Pour ré-initialiser la page et faire ré-apparaitre le formulaire, vous pouvez vider vos cookies (ctrl+shift+suppr) cela cassera le lien avec le fichier de session.


Exemple avec l'inactivité d'une session

Il arrive parfois que la durée de vie des sessions soit limitée sur certains sites (par exemple sur les sites des banques vous êtes déconnécté automatiquement au bout de 10 minutes d'inactivité).
Le réglage de la durée de vie d'une session peut se faire dans le paramètrage du serveur ou directement dans le script.

Voici un exemple :

inactivitee.php
		<?php
		session_start();
		echo 'Temps Actuel : ' . time() . '
'; print "
"; print_r($_SESSION); print "
"; if(isset($_SESSION['temps'])) { if(time()>($_SESSION['limite'] + $_SESSION['temps'])) { session_destroy(); echo "déconnexion"; } else { $_SESSION['temps'] = time(); echo "connexion mise à jour"; } } else { echo "connexion"; $_SESSION['limite'] = 20; $_SESSION['temps'] = time(); }

Quelques Explications et déroulement du script :

Pour les tests il serait judicieux de spliter l'écran en deux avec d'un côté votre page web et de l'autre votre dossier /tmp/.

session_start() nous permet de créer 1 fichier de session la première fois (et de l'ouvrir les fois suivantes).

echo 'Temps Actuel : ' . time() . '
';
permet de voir le timestamp actuel

if(isset($_SESSION['temps'])) si une session du nom de "temps" existe nous rentrons dans le IF (ce qui n'est pas le cas, la toute première fois), nous rentrerons donc dans le ELSE

else Nous rentrons dans le ELSE car aucune session du nom de "temps" existe.

$_SESSION['limite'] = 20; Nous rentrons le chiffre 20 dans une partie de la session que nous nommerons "limite". Cela nous permettra plus tard de limiter la session à 20 secondes.

$_SESSION['temps'] = time(); Nous rentrons le timestamp actuel (nombre de secondes écoulées entre le 01/01/1970 et maintenant) dans une partie de la session que nous nommerons "temps". Cela nous permettra plus tard d'interroger la dernière trace d'activité sur le site web.

...Relancer l'exécution de la page avec l'aide de F5 ou Ctrl+R.

...Le code se ré-exécute.

if(isset($_SESSION['temps'])) si une session du nom de "temps" existe nous rentrons dans le IF (ce qui est le cas, la seconde première fois, nous ne rentrerons donc pas dans le ELSE

if(time()>($_SESSION['limite'] + $_SESSION['temps'])) si le timestamp actuel est supérieur au dernier timestamp enregistré dans la session + la partie limite enregistrée dans la session (pour rappel, 20 secondes), c'est donc que nous avons dépassé notre temps de connexion inactive autorisée, nous rentrerons dans les accolades du IF

session_destroy(); permet de supprimer le fichier de session.

... Dans l'autre cas, si vous affichez la page web une première fois et que vous la raffraichissez rapidement (moins de 20 secondes après), nous rentrons dans le 1er IF puis dans le ELSE (présent à l'intérieur du premier IF)

$_SESSION['temps'] = time(); cela nous permet de mettre la connexion à jour en affectant le timestamp actuel dans la session (cela le modifiera pour l'actualiser).

Pour conclure :
Nous n'avons pas autorisé l'internaute à garder une connexion de 20 secondes au total mais nous l'avons autorisé à conserver une connexion de 20 secondes après son dernier mouvement (clic, raffraichissement de page, etc.).

Résultat
explication PHP

Les résultats diffèrent selon l'état de la page web.

Démo conseillée : Lancer l'exécution de la page...attendre 2 sec, effectuer un ctrl+r, attente 2 sec, effectuer un ctrl+r, attendre 30 secondes, effectuer un ctrl+r. Et surtout (au même moment) observer le dossier /tmp/ avec un écran splité en deux.

Gérer la durée de vie des sessions

Gérer la durée de vie des sessions et/ou supprimer les fichiers de session du serveur

Dans le fichier de configuration php.ini (pas toujours disponible, selon l'hebergement souscrit, mutualisé, dédié, vps, etc.)
session.gc_maxlifetime : permet de determiner la durée de vie des fichiers de sessions du dossier /tmp/ avant qu'ils ne soient supprimés. Cela commence par "gc" pour Garbage Collector.


Sécurité des fichiers de sessions

Dans le fichier de configuration php.ini, nous pouvons modifier 2 ou 3 paramètres liés à l'utilisation des sessions :

session.use_cookies 1 permet de préciser que l'identifiant de session sera transmis par un cookie
session.use_only_cookies 1 permet de préciser que seulement le cookie sera en mesure de transmettre l'identifiant de session (les autres moyens seront interdits et refusés)
session.use_trans_sid 0 L'argument/paramètre PHPSESSID transmis parfois dans les adresses url des sites web sera strictement refusé dans notre cas.