Auteur: Ludovic PATEY

Publié le 5 février 2008

Modifié le: 6 février 2008

Page d'accueil

Les cookies et les sessions en PHP

Vous êtes ici : Accueil / Articles / Formations en PHP

Les variables que nous manipulons en PHP n’ont pas de persistance par défaut, c’est à dire qu’une fois que le script est exécuté, elles sont supprimées. Très vite, il est apparu que ce système était très limité et qu’il était nécessaire de pouvoir conserver des informations durant une partie de la session. Ce besoin a été à l’origine de l’apparition des cookies

Les cookies

Qu’est-ce qu’un cookie ? Un cookie est une information ponctuelle stockée sous forme de fichiers par le navigateur. Ces informations transitent entre le serveur et le client par les headers lors des requêtes. Le navigateur n’envoie au serveur que les cookies qu’il possède. Le fait de passer par les headers va imposer des contraintes que nous verrons par la suite.

Le serveur a la possibilité de lire, de modifier et de créer de nouveaux cookies, pour peu que la fonctionnalité n’aie pas été désactivée dans le navigateur. Le pourcentage d’utilisateurs désactivant les cookies est non négligeable, sans compteur ceux qui les suppriment régulièrement.

Voyons maintenant la syntaxe proposée par PHP pour les manipuler.

Lire un cookie

Tous les cookies sont stockés dans la variable superglobale $_COOKIE : Cette variable est accessible en lecture et écriture, mais les modifications ne seront pas persistantes, c’est à dire qu’elles ne seront pas envoyées au client.

NB : Pour une version inférieure à PHP 4.1.0, il est nécessaire de faire appel au tableau $HTTP_COOKIE_VARS

<?php
// Affichage du cookie "mon_cookie"
echo 'Mon cookie mon_cookie vaut ' . $_COOKIE['mon_cookie'];
?>

Créer / modifier un cookie

Pour créer un cookie, PHP met à notre disposition la fonction setcookie qui admet un paramètre obligatoire, puis des paramètres optionnels.

<?php
// Crée un cookie simple qui sera supprimé à la fin de la session
setcookie( 'mon_cookie', $ma_valeur );
?>

L’exemple précédent était suffisant pour créer un cookie. Cependant, il est possible d’affiner la création du cookie en passant d’autres paramètres. Voici la définition complète de la fonction donnée par le site php.net :

<?php
bool setcookie  ( string $name  [, string $value  [, int $expire  [, string $path  [, string $domain  [, bool $secure  [, bool $httponly  ]]]]]] )
?>

$expire est un timestamp UNIX et correspond à une date limite au delà de laquelle le cookie sera supprimé.

$path correspond au chemin de disponibilité du cookie. Par exemple, si vous lui mettez la valeur /dossier, le cookie ne sera envoyé au serveur par le client que si la requête est faite vers un script dans l’arborescence du dossier /dossier

$domain est le domaine propriétaire du cookie. Si vous définissez un autre domaine que celui de votre site, vous ne pourrez plus accéder à son contenu.

$secure est un flag qui permet de spécifier si oui ou non le cookie sera chiffré dans la base de données.

$httponly limite la lisibilité du cookie au protocole http. Si un langage de script essaye d’y accéder, il ne pourra pas.

La grande majorité du temps, seul le nom, la valeur et le temps d’expiration sont définis.

Attention ! La fonction setcookie doit être appelée avant tout affichage par une fonction comme echo. En effet, lors du premier affichage, la partie consacrée aux headers se ferme pour passer au contenu de la page. Il devient alors impossible à PHP de transmettre le cookie créé puisqu’il ne peut plus l’ajouter aux headers. Ceci explique également le message d’erreur qui s’affiche lorsque vous avez recours à la fonction setcookie après un affichage :

Warning : Cannot add header information - headers already sent by (output started at c :\wamp\www\test.php:4) in c :\wamp\www\test.php on line 6

Attention ! La présence d’espace avant la balise PHP ouvrante est un affichage. Le message d’erreur s’affichera donc si vous essayez de modifier un cookie dans un script php comportant des espaces avant ses balises.

Supprimer un cookie

La suppression d’un cookie s’effectue toujours à l’aide de la fonction setcookie. Il suffit de ne pas préciser de valeur et le cookie sera détruit ( ou plus exactement, il contiendra une valeur vide ). Pour supprimer proprement votre cookie, il est également nécessaire de préciser une date d’expiration passée pour que le navigateur de l’internaute supprime le fichier correspondant.

<?php
// Supprime le cookie mon_cookie
setcookie( 'mon_cookie', '', time() - 1000 );
?>

Les sessions

Pourquoi les sessions ?

Le système des cookies, bien que très efficace, présente quelques désavantages :

- Il n’est pas certain que les utilisateurs n’aient pas désactivé les cookies dans leur navigateur.

- Les cookies ne sont pas très sécurisés, car comme ils sont stockés côté client, il est toujours possible à des programmes d’accéder à leur contenu et de récupérer les mots de passe qu’on entré les utilisateurs pour se connecter à des sites internets qui les stockent dans des cookies.

Les sessions ont donc été créées pour répondre à ces problèmes, en tant que surcouche des cookies. Elles sont basées sur un principe très simple : au lieu de stocker les données sensibles côté client, il suffit de stocker chez lui un identifiant unique qui va pointer vers ses données sensibles stockées côté serveur.

Les données sont toujours stockées sous forme de fichiers, mais cette fois-ci côté serveur. Le nom de ce fichier, généré aléatoirement, va constituer l’id de session. Si le nom du cookie stockant l’id de session n’est pas défini, sa valeur par défaut sera PHPSESSID.

Manipuler les sessions

Avant tout, il est nécessaire de faire appel à la fonction session_start()

Celle-ci va récupérer le cookie de session, ou le définir s’il n’existe pas. Comme les sessions manipulent des cookies, il va être nécessaire d’appeler cette fonction avant tout affichage, sinon PHP retournera un message d’erreur similaire à celui de la fonction setcookie.

Une fois la session démarrée, le tableau superglobal $_SESSION va être disponible et contiendra toutes les valeurs que nous y aurons stocké depuis le début de la session.

La variable $_SESSION est accessible en lecture et écriture, et contraitement aux cookies, les modifications sont conservées durant la durée de la session.

<?php
// Démarre une session
session_start();

// Affiche l'ancienne valeur stockée en session
echo $_SESSION['ma_donnee_persistante'];

// Stocke une nouvelle valeur en session
$_SESSION['ma_donnee_persistante'] = 'Hello World';
?>

NB : La manipulation de contenu à travers le tableau $_SESSION se fait au niveau de son implémentation sous forme de fichiers et non de cookies : seul le nom du fichier est stocké sous forme de cookie et celui-ci est déjà défini lors de l’appel à la fonction session_start(). Ainsi, il est possible de modifier ce tableau même après des affichages. Cette liberté est un grand avantage par rapport au système des cookies où l’on devait tout définir avant le moindre affichage.

Il est possible de récupérer le nom du cookie par la fonction session_name() qui admet un paramètre optionnel : un nouveau nom de cookie. Cette fonction doit être appelée avant la fonction session_start(). Par défaut, session_name() retourne PHPSESSID.

<?php
echo session_name() // Affiche PHPSESSID
?>

session_id() retourne l’identifiant de session, c’est à dire le nom du fichier sous lequel sont stockées les données de session.

Pour supprimer toutes les informations relatives à une session, il existe la fonction session_destroy()

<?php
// Demarre une session
session_start();

// Arrête une session
session_destroy();
?>

La durée de la session est définie dans le php.ini et peut être modifiée grâce à la fonction session_cache_expire(), cependant, comme cela affecte la création du cookie contenant l’id, il est nécessaire d’appeler cette fonction avant le session_start().

Il est possible d’automatiser l’appel à la fonction session_start() est définissant la directive session.auto_start du php.ini

Une autre directive intéressante est session.use_trans_sid qui permet de passer automatiquement par l’url les id de session au cas où le navigateur refuserait les cookies. Il est cependant à noter que cette directive représente un danger pour l’intégrité des données, dans le sens où un internaute peut enregistrer l’url dans ses favoris, puis se rendre sur le site en transmettant un ancien id de session qui a été réattribué à un autre internaute entre temps.

Correction de bugs sur les sessions

Voici les explications aux bugs les plus reccurrents aux sessions :

- Warning : Cannot add header information - headers already sent by (output started at c :\wamp\www\test.php:4) in c :\wamp\www\test.php on line 6

Ce message s’affiche lorsque vous tentez de modifier un cookie alors que vous avez déjà eu recours à un affichage ( par exemple en appellant la fonction echo ). Lorsque vous faites appel à la fonction session_start(), celle-ci manipule par derrière un cookie et les contraintes d’affichage s’appliquent donc. Veuillez à mettre ces fonctions en tout début de code pour éviter les messages d’erreur. Si le message d’erreur persiste, vérifiez que vous n’avez pas un affichage caché dû par exemple à un caractère avant les balises php, ne s’affichant pas dans votre encodage.

- Les informations de session ne sont pas conservées

Les informations sont la plus part du temps perdues lorsque votre navigateur n’accepte pas les cookies et donc qu’il est impossible à PHP de récupérer le chemin du fichier dans lequel sont stockées les données de sessoin. Prévoyez cette situation en activant le session.use_trans_sid dans le php.ini ou en les transmettant manuellement dans l’url.

Commentaires

FKIH a dit le 28 février 2009

je suis un nouveau developpeur de site web dynamiques je veut s’avoir comment reagir avec le panier et les variables de session s’il vous plait donner a moi meme un petit exemple de code qui peut gerer un produit par son nom et son reference

Ludovic PATEY a dit le 28 février 2009

Bonjour, le texte est un peu trop long pour le mettre dans un post.
Donnez-moi votre adresse email et je vous l’enverrai.

Auteur :

Message :