Tutoriel Vidéo PHP Comment marche $_SESSION

Télécharger la vidéo

$_SESSION en PHP est une variable qui permet de stocker des informations pour un utilisateur pendant la durée de sa visite sur le site. C'est une variable qui s'avère très utile mais qui est aussi source de problèmes avec notamment la fameuse erreur Cannot send session cookie - headers already sent. Aussi je vous propose de démystifier le fonctionnement des session et de mieux comprendre le session_start() ensemble.

Une histoire de cookies

Lorsque l'on souhaite utiliser la variable $_SESSION il faut commencer par appeler la fonction session_start(). Cette fonction va renvoyer une en-tête supplémentaire au navigateur afin de lui demander de sauvegarder une clef dans ses cookies (il rajoutera aussi une en-tête pour empêcher la mise en cache de cette page)

Set-Cookie: PHPSESSID=za46aze6a4rf4az4re6az8raz86e468az74; path=/
Cache-control: no-store, no-cache, must-revalidate

Cette clef sera alors sauvegardé dans les cookies du navigateur tant que celui-ci reste ouvert. Ainsi, lors d'une prochaine requête au serveur le navigateur transmettra les informations qu'il a dans ses cookies :

Cookie: PHPSESSID=za46aze6a4rf4az4re6az8raz86e468az74

Cette en-tête sera comprise par PHP qui sera capable de récupérer les informations sauvegardées pour cet utilisateur. Ce comportement permet d'expliquer l'erreur Cannot send session cookie - headers already sent :

  • Vous affichez du contenu (même un simple espace), du coup PHP renvois les en-tête classiques et commence à renvoyer le contenu.
  • Plus tard vous faites un session_start() mais PHP est bloqué car les en-têtes ont déjà été envoyées et il ne peut donc pas rajouter ces en-têtes pour le cookie et renvois l'erreur headers already sent

Pour éviter ce problème il faut bien faire attention à ne pas afficher de contenu avant un session_start(). D'ailleurs, comment sont sauvegardées les informations que l'on stocke en session ?

Lors d'un session_start() PHP va créer un fichier sur le serveur qui aura le même nom que la clef renvoyée au navigateur et écrira dans ce fichier toutes les informations qui seront stockées dans la variable $_SESSION. Vous pouvez d'ailleurs obtenir ou modifier le dossier qui est utilisé en utilisant la fonction session_save_path().

Changer la mécanique de sauvegarde

Ecrire les informations en Session dans un fichier est suffisant pour la plupart des cas mais peut s'avérer relativement problématique dans certains cas :

  • Si les temps d'écriture / lecture sont lent, un simple session_start peut rallonger le temps de génération des pages
  • Si PHP fonctionne sur plusieurs serveurs les sessions ne seront pas partagé et si un utilisateur change de serveur pendant une même session il se trouvera déconnecté.

Pour solutionner ces problématiques il est possible de mettre en place des systèmes de sauvegarde différents, avec par exemple une sauvegarde dans une base de données (sqlite, memcache, redis...). PHP permet de changer le Session Handler en créant une classe qui hérite de l'interface SessionHandlerInterface.

class MonHandlerSession implements SessionHandlerInterface {

   // ....

}

$handler = new MonHandlerSession();
session_set_save_handler($handler, true);
session_start();

// Maintenant $_SESSION utilisera MonHandlerSession pour persister les informations

Certains modules PHP intègrent des handlers "tout fait" qui permettent de mettre en place rapidement une persistance en base de données. Par exemple si vous installez le module redis pour PHP il vous suffit de changer la valeur de session.save_handler pour redis.