Manuel PHP
Précédent |  | Suivant

# XCVII. Sessions

# Introduction

Le support des sessions de PHP est un moyen de préserver des données entre plusieurs accès. Cela vous permet de créer des applications personnalisées, et d'augmenter l'attractivité de votre site.

Si vous êtes familier avec la gestion de session de la librairie PHPLIB, vous remarquerez que certains concepts sont similaires.

Chaque visiteur accédant à votre page web se voit assigné un identifiant unique, appelé 'identifiant de session'. Il peut être stocké soit dans un cookie, soit propagé dans l'URL.

Le support des sessions vous permet d'enregistrer un nombre illimité de variables qui doivent être préservées entre les requêtes. Lorsqu'un visiteur accède à votre site, PHP va vérifier automatiquement (si session.auto_start est activé1) ou sur demande (explicitement avec session_start() ou implicitement avec session_register()) si il existe une session du même nom. Si c'est le cas, l'environnement précédemment sauvé sera recréé.

Toutes les variables sont sérialisées après l'exécution du script PHP. Les variables qui sont indéfinies sont marquées comme telles. Lors des accès ultérieurs, elles ne seront pas définies, jusqu'à ce que l'utilisateur le fasse.

> Note : La gestion des sessions a été ajoutée en PHP 4.0.

# Sessions et sécurité

Lien externe : Session fixation

Utiliser les sessions ne signifie pas que les données de session ne pourront être vue que par un seul utilisateur. Il est important de garder cela en tête, lorsque vous stockez et affichez des données importantes. Lorsque vous stockez des données dans une session, il faut se demander quels seront les problèmes posés si quelqu'un d'autre accède à cette information, ou comment votre application est affectée si la session est en fait celle d'un autre.

Par exemple, si quelqu'un usurpe une session, il peut alors poster un message dans un forum sous une fausse identitée. Quelle est la gravité de ce problème? Ou bien, il peut accèder aux commandes d'un client, et même, modifier son panier d'achat. A priori, c'est moins problématique pour un fleuriste que pour un pharmacien.

Par conséquent, lorsque vous manipulez des données importantes, il faut exploiter d'autres méthodes pour décider si une session est valide ou pas. Les sessions ne fournissent pas une méthode fiable d'authentification.

Les sessions reposent sur un identifiant de session, ce qui signifie que quelqu'un peut voler cet identifiant, rien qu'en volant l'ID. Ce vol peut être rendu très difficile, comme par exemple en utilisant les cookies, mais en aucun cas cela sera impossible. Les sessions dépendent aussi de la discipline de l'utilisateur qui referme son navigateur à la fin de la session pour tout clore proprement. De plus, même les cookies de session peuvent être surveillés sur un réseau, ou bien notés par un proxy.

# Pré-requis

Ces fonctions sont disponibles dans le module PHP standard, qui est toujours accessible.

# Installation

Le suport des sessions est activé par défaut. Si vous souhaitez exclure le support des sessions de `PHP`, vous devez utiliser l'option `--disable-session` lors de l'exécution du script de configuration. Pour utiliser la mémoire vive pour le stockage des sessions, compilez `PHP` avec l'option `--with-mm[=DIR]` .

La version Windows de `PHP` dispose du support automatique de cette extension. Vous n'avez pas à ajouter de librairie supplémentaire pour disposer de ces fonctions.

# Configuration à l'exécution

Le comportement de ces fonctions est affecté par la configuration dans le fichier `php.ini`.

Tableau 1. Options de configuration

Nom | Par défaut | Modifiable
--- | --- | ---
session.save_path | "/tmp" | PHP_INI_ALL
session.name | "PHPSESSID" | PHP_INI_ALL
session.save_handler | "files" | PHP_INI_ALL
session.auto_start | "0" | PHP_INI_ALL
session.gc_probability | "1" | PHP_INI_ALL
session.gc_maxlifetime | "1440" | PHP_INI_ALL
session.serialize_handler | "php" | PHP_INI_ALL
session.cookie_lifetime | "0" | PHP_INI_ALL
session.cookie_path | "/" | PHP_INI_ALL
session.cookie_domain | "" | PHP_INI_ALL
session.cookie_secure | "" | PHP_INI_ALL
session.use_cookies | "1" | PHP_INI_ALL
session.use_only_cookies | "0" | PHP_INI_ALL
session.referer_check | "" | PHP_INI_ALL
session.entropy_file | "" | PHP_INI_ALL
session.entropy_length | "0" | PHP_INI_ALL
session.cache_limiter | "nocache" | PHP_INI_ALL
session.cache_expire | "180" | PHP_INI_ALL
session.use_trans_sid | "0" | PHP_INI_SYSTEM|PHP_INI_PERDIR
session.bug_compat_42 | "1" | PHP_INI_ALL
session.bug_compat_warn | "1" | PHP_INI_ALL
session.hash_function | "0" | PHP_INI_ALL
session.hash_bits_per_character | "4" | PHP_INI_ALL
url_rewriter.tags | "a=href,area=href,frame=src,input=src,form=fakeentry" | PHP_INI_ALL

Pour plus de détails sur les constantes PHP_INI_*, reportez-vous à ini_set().

Le système de sessions dispose d'un grand nombre de directives dans le fichier `php.ini`. En voici une présentation :

`session.save_handler` string

  Définit le nom du gestionnaire de session qui est utilisé pour stocker et relire les données. Par défaut, c'est le système intégré par fichiers : `files`.

`session.save_path` string

  Définit le chemin qui doit être passé au gestionnaire de sauvegarde. Si vous décidez de choisir le gestionnaire par défaut (par fichier), cet argument sera utilisé comme dossier de sauvegarde des sessions. Par défaut, il vaut `/tmp`. Si le niveau d'imbrication de `session.save_path` est supérieur à 2, le nettoyage des sessions obsolètes ne s'opérera pas.

  Avertissement
  Si vous laissez cette option configurée avec un dossier accessible en lecture à tout le monde, comme par exemple `/tmp` (par défaut), les autres utilisateurs pourront exploiter ces sessions en obtenant la liste de fichiers dans ce dossier.

  > Note : Les utilisateurs de Windows doivent changer cette valeur de variable pour que les fonctions de sessions de PHP fonctionnent. Indiquez un chemin de dossier valide, comme par exemple : `c:/temp`.

`session.name` string

  Spécifie le nom de la session, qui sera utilisé comme nom de cookie. Il ne doit contenir que des caractères alphanumérique. Par défaut, c'est `PHPSESSID`.

`session.auto_start` integer

  Spécifie si le module de session doit démarrer automatiquement au début de chaque script PHP. Par défaut, c'est `0` (désactivé).

`session.cookie_lifetime` integer

  Spécifie la durée de vie du cookie en secondes. La valeur de `0` siginifie : "Jusqu'à ce que le navigateur soit éteind". La valeur par défaut est : 0.

`session.serialize_handler` string

  Définit le nom du gestionnaire qui est utilisé pour linéariser/délinéariser les données. Actuellement, un format interne à PHP (nommé `php`) et WDDX (nommé `wddx`) sont supportés . WDDX est seulement disponible, si PHP a été compilé avec l'option WDDX. Par défaut, c'est `php`.

`session.gc_probability` integer

  Spécifie la probabilité en pourcents que la routine gc (garbage collection) soit démarrée à chaque requête. La valeur par défaut est `1`.

`session.gc_maxlifetime` integer

  Spécifie la durée de vie des données sur le serveur, en nombre de secondes. Après cette durée, les données seront considérées comme obsolètes, et supprimées.

  > Note : Si vous utilisez le gestionnaire de session par fichier, qui est fourni par défaut votre système doit garder la trace des dates de dernier accès aux fichier (atime). La FAT de Windows ne le fait pas, alors vous faudra trouver un autre système pour gérer les sessions qui ont expirées.

`session.referer_check` integer

  Contient une sous-chaîne que vous souhaitez retrouver dans tous les en-têtes HTTP Referer. Si cet en-tête a été envoyé par le client, et que la sous-chaîne n'a pas été trouvé, l'identifiant de session sera considéré comme invalide. Par défaut, cette option est la chaÎne vide.

`session.entropy_file` string

  Est un chemin jusqu'à une source externe (un fichier), qui sera utilisée comme source additionnelle d'entropie pour la création de l'identifiant de session. Des exemples valides sont `/dev/random` et `/dev/urandom`, qui sont disponibles sur tous les systèmes Unix.

`session.entropy_length` integer

  Spécifie le nombre d'octets qui seront lus dans le fichier défini ci-dessus. Par défaut, il vaut `0`, c'est à dire inactif.

`session.use_cookies` integer

  Spécifie si le module utilisera les cookies pour stocker les données de session sur le client. Par défaut, il vaut `1`, c'est à dire actif.

`session.use_only_cookies` integer

  Spécifie si le module doit utiliser seulement les cookies pour stocker les identifiants de sessions du coté du navigateur. Par défaut, cette option vaut `0` (inactif, pour compatibilité ascendante). En l'activant, vous éviterez les attaques qui utilisent des identifiants de sessions dans les URL. Cette configuration a été ajoutée en PHP 4.3.0.

`session.cookie_path` string

  Spécifie le chemin utilisé lors de la création du cookie. Par défaut, il vaut `/`.

`session.cookie_domain` string

  Spécifie le domaine utilisé lors de la création du cookie. Par défaut, il ne vaut rien.

`session.cookie_secure` bool

  Spécifie que les cookies ne doivent être émis que sur des connexion sécurisée. Par défaut, cette option est à `off`. Cette option a été ajoutée en `PHP` 4.0.4. Voir aussi session_get_cookie_params() et session_set_cookie_params().

`session.cache_limiter` string

  Spécifie le type de contrôle de cache utilisé pour les pages avec sessions. Les valeurs possibles sont : none, nocache, private, private_no_expire, public. Par défaut, il vaut `nocache`.

`session.cache_expire` integer

  Spécifie la durée de vie des données de sessions, en minute. Cette option n'a aucune conséquence sur le contrôle de cache. Par défaut, il vaut `180` (3 heures).

`session.use_trans_sid` integer

  > Note : En PHP 4.1.2 ou plus ancien, cette option est activée en utilisant l'option de compilation `--enable-trans-sid`. Depuis PHP 4.2.0, trans-sid est toujours compilée.

  > Le système de gestion des sessions par URL pose un risque supplémentaire de sécurité : un utilisateur peut envoyer son URL avec l'identifiant de session par email à un ami, ou bien le mettre dans ses signets. Cela diffusera alors l'identifiant de session.

`session.bug_compat_42` boolean

  Les versions de `PHP` antérieures à la version 4.2.0 disposaient d'une fonctionnalité/bogue non documentée, qui vous permettait d'initialiser une variable de session dans le contexte global, même si register_globals était désactivé. `PHP` 4.3.0 et plus récent vous préviendra de l'utilisation de cette fonctionnalité si vous avez aussi activé session.bug_compat_warn.

`session.bug_compat_warn` boolean

  Les versions de `PHP` antérieures à la version 4.2.0 disposaient d'une fonctionnalité/bogue non documentée, qui vous permettait d'initialier une variable de session dans le contexte global, même si register_globals était désactivé. `PHP` 4.3.0 et plus récent vous préviendra de l'utilisation de cette fonctionnalité si vous avez activé session.bug_compat_42 et session.bug_compat_warn.

`session.hash_function` integer

  `session.hash_function` vous permet de spécifier la fonction de hachage à utiliser pour générer les identifiants de session. '0' signifie MD5 (128 bits) et '1' signifie SHA-1 (160 bits).

  > Note : Cette directive a été ajoutée en `PHP` 5.

`session.hash_bits_per_character` integer

  `session.hash_bits_per_character` vous permet de définir le nombre de bits utilisés pour chaque caractère lors des conversions des données binaires en éléments lisibles. Les valeurs possibles sont '4' (0-9, a-f), '5' (0-9, a-v), et '6' (0-9, a-z, A-Z, "-", ",").

  > Note : Cette directive a été ajoutée en `PHP` 5.

`session.url_rewriter.tags` string

  Spécifie quels sont les balises HTML qui doivent être réécrites si le support transparent du SID est activé. Par défaut, il vaut `a=href,area=href,frame=src,input=src,form=fakeentry`.

Les options `track_vars` et `register_globals` influencent le comportement des sessions, leur stockage et leur restauration.

> Note : Depuis PHP 4.0.3, `track_vars` est toujours activé.

# Types de ressources

Cette extension ne définit aucune ressource.

# Constantes prédefinies

Ces constantes sont définies par cette extension, et ne sont disponibles que si cette extension a été compilée avec PHP, ou bien chargée au moment de l'exécution.

`SID` (chaîne de caractères)

  Constante contenant le nom de la session et l'identifiant en cours, sous la forme `"name=ID"`.

# Exemples

> Note : Depuis PHP 4.1.0, `$_SESSION` est disponible comme variable globale, au même titre que `$_POST`, `$_GET`, `$_REQUEST`, etc.. Contrairement à `$HTTP_SESSION_VARS`, `$_SESSION` est toujours globale. Par conséquent, vous n'avez pas besoin d'utiliser le mot réservé global avec `$_SESSION`. Notez que cette documentation a été modifiée pour utiliser `$_SESSION`. Vous pouvez toujours le remplacer par `$HTTP_SESSION_VARS` si vous préférez l'ancienne version.

> Les clés du tableau `$_SESSION` sont sujettes aux mêmes limitations que les variables PHP habituelles, c'est à dire qu'elles ne peuvent pas commencer par un nombre, mais commencer par une lettre ou un souligné '_'. Pour plus de détails, reportez vous à la section sur les variables.

Si `track_vars` est activé et `register_globals` est désactivé, seuls les éléments du tableau global `$_SESSION` contiendront les variables enregistrées dans la session. Les variables de sessions relues seront uniquement disponibles dans `$_SESSION`.

L'utilisation de `$_SESSION` (ou `$HTTP_SESSION_VARS` avec PHP 4.0.6 et plus ancien) est recommandé pour une meilleure sécurité et un code plus facilement maintenable. Avec `$_SESSION`, il n'y a pas besoin d'utiliser les fonctions session_register(), session_unregister() et session_is_registered(). Les variables de sessions sont accessibles comme toute autre variable.

Exemple 1. Enregistrer une variable avec $_SESSION.

`<?php session_start(); // Utilisez $HTTP_SESSION_VARS avec PHP 4.0.6 ou plus ancien if (!isset($_SESSION['compteur'])) { $_SESSION['compteur'] = 0; } else { $_SESSION['compteur']++; } ?>`

Exemple 2. Retirer une variable de session avec $_SESSION et register_globals inactif.

`<?php session_start(); // Utilisez $HTTP_SESSION_VARS avec PHP 4.0.6 ou plus ancien unset($_SESSION['compteur']); ?>`

Exemple 3. Retirer une variable de session avec $_SESSION et register_globals activé, après l'avoir enregistré avec $_SESSION.

`<?php session_start(); // Avec PHP 4.3 et plus récent, vous pouvez simplement utiliser l'exemple précédent session_unregister('compteur'); ?>`

Si `register_globals` est activé, alors toutes les variables globales peuvent être enregistrées comme variables de session, et toutes les variables de sessions seront reconstituées comme variables globales. Comme PHP doit savoir quels variables globales sont enregistrées comme variables de sessions, l'utilisateur doit enregistrer les variables avec session_register() tandis que `$HTTP_SESSION_VARS` et `$_SESSION` ne nécessitent pas session_register().

Attention

Si vous utilisez `$HTTP_SESSION_VARS` et `$_SESSION` et désactivez `register_globals`, n'utilisez pas session_register(), session_is_registered() et session_unregister().

Si vous activez `register_globals`, session_unregister() doit être utilisé, car les variables de session sont enregistrés comme variables globales lorsque les données de sessions sont relues. Désactiver `register_globals` est recommandé pour des raisons de sécurité et de performances.

Exemple 4. Enregistrer une variable avec `register_globals` activé

`<?php if (!session_is_registered('compteur')) { session_register("compteur"); $compteur = 0; } else { $compteur++; } ?>`

Si `register_globals` est activé, alors les variables globales et les entrées dans le tableau `$_SESSION` seront des références sur la même valeur pour les valeurs qui auront été enregistrées avant le démarrage de la session (donc, dans les page précédentes).

De plus, si vous enregistrez une nouvelle variable avec la fonction session_register(), l'entrée dans l'environnement globale et `$_SESSION` ne fera pas de référence vers la même valeur jusqu'à la prochaine utilisation de session_start() (ceci s'applique à PHP 4.2 est avant seulement). C'est à dire qu'une modification dans les variables globales ne seront pas répercutés dans les entrées de `$_SESSION`. Il est peu probable que cela ait un impact en pratique, et de plus, cela a été corrigé en PHP 4.3.

# Passer l'identifiant de session (session ID)

Il y a deux méthodes de propagation de l'identifiant de session :

- Cookies

- Par URL

Le module de session supporte les deux méthodes. Les cookies sont optimaux, mais comme ils ne sont pas sûrs (tous les internautes ne les acceptent pas), ils ne sont pas fiables. La seconde méthode place l'identifiant de session directement dans les URL.

PHP est capable de faire cela de manière transparente, lorsqu'il est compilé avec l'option `--enable-trans-sid`. Si vous activez cette option, les URL relatives seront modifiées pour contenir l'identifiant de session automatiquement. Alternativement, vous pouvez utiliser la constante `SID`, qui est définie, si le client n'a pas envoyé le cookie approprié. `SID` est soit de la forme `session_name=session_id` ou une chaîne vide.

> Note : L'option arg_separator.output de `php.ini` vous permet de personnaliser le séparateur d'arguments.

L'exemple suivant vous montre comment enregistrer une variable et comment réaliser un lien correct avec une autre page, avec `SID`.

Exemple 5. Compter le nombre de hits d'un utilisateur sur une page

`<?php if (!session_is_registered('compteur')) { session_register('compteur'); $compteur = 1; } else { $compteur++; } ?> Bonjour visiteur, vous avez vu cette page <?php echo $compteur; ?> fois.<p>; Pour continuer, <A HREF="nextpage.php?<?php echo SID?>">cliquez ici</A>.`

`<?php echo SID?>` (ou bien `<?=SID?>` peut être utilisé si les short_open_tag sont actifs) est nécessaire pour préserver l'identifiant de session dans le cas où l'utilisateur a désactivé les cookies. `<? echo SID?>` n'est pas nécessaire, si `--enable-trans-sid` a été activé à la compilation de PHP.

> Note : Les URLS non relatives sont considérées comme externes au site, et ne recevront pas le SID, car c'est une fuite d'information vers un autre site (envoi d'informations importantes).

# Gestion personnalisée des sessions

Pour implémenter un stockage en base de données, ou toute autre méthode, vous aurez besoin de la fonction session_set_save_handler() pour paramétrer vos propres fonctions de stockage.

Précédent | Sommaire | Suivant
sesam_settransaction | Niveau supérieur | session_cache_expire