FAQ PHPConsultez toutes les FAQ

Nombre d'auteurs : 68, nombre de questions : 580, dernière mise à jour : 29 juillet 2013 

 
OuvrirSommaireSécuritéSessions
  • Pour conserver de page en page les valeurs de certaines variables.
  • Pour pister le parcours du visiteur.
  • Pour effectuer des statistiques fines en termes de visiteurs réels et pas en hits (nombre d'appels d'un fichier).
Mis à jour le 6 août 2008  par Cyberzoide

Les sessions permettent tout du long de la visite d'un internaute sur le site, de conserver des informations de façon transparente.

Cela est sans ralentissement de performances car le client ne stocke sous forme de cookie que l'ID de session (généré aléatoirement), le serveur stockant sur disque le contenu des variables dans le répertoire défini par session.save_path.

Les sessions sont activées manuellement par la commande session_start() ou automatiquement si session.auto_start est à 1 ou encore implicitement par la commande session_register()(obsolète).

Le serveur attribue à chaque visiteur un identifiant unique qui est soit envoyé au client sous forme de cookie (par défaut), soit passé de façon systématique dans l'URL.

Mis à jour le 3 août 2008  par Cyberzoide

Il existe trois manières de démarrer une session :

Syntaxe : boolean session_start ( void) Crée une session ou continue la session courante, en fonction de l'identifiant de session passé par l'URL (méthode GET) ou par un cookie.
Exemple :

 
Sélectionnez
<?php
session_start() ;
...
?>
Mis à jour le 6 août 2008  par Cyberzoide

Fermeture conservatrice : La commande session_write_close() écrit les valeurs des variables de session sur le serveur et ferme la session.

Fermeture destructive : La commande session_destroy() détruit toutes les données enregistrées d'une session. Cette dernière commande est la plus utilisée car n'impose aucune sauvegarde au serveur. Retourne TRUE en cas de succès, et FALSE sinon.

Mis à jour le 6 août 2008  par Cyberzoide
  • En stockant leurs valeurs dans une base de données.
  • En les enregistrant dans un fichier sur le serveur (mais oblige à donner des droits d'écriture aux visiteurs).
  • Utiliser des cookies (malheureusement certains navigateurs ne les acceptent pas).
  • En les envoyant dans l'URL (mais seront visibles aux visiteurs dans la barre d'adresse et cela leur impose de toujours utiliser les liens hypertextes).
  • En les passant par un formulaire (mais impose aux visiteurs de cliquer sur un bouton d'envoi).
  • En utilisant une session.
Mis à jour le 3 août 2008  par Cyberzoide

Par l'usage de la commande session_register()(obsolète) dont voici la syntaxe :

 
Sélectionnez
boolean session_register ( mixed name [, mixed ...])

Elle prend en paramètre une chaîne de caractères contenant le nom de la variable à sauvegarder ou bien un tableau de chaînes de caractères ou encore un tableau de tableaux...

Exemple avec une variable chaîne de caractères :

 
Sélectionnez
<?php
session_start() ;
$foobar = "Hello Word !";
session_register("foobar");
...
?>

Autre exemple avec le tableau superglobal $_SESSION :

 
Sélectionnez
<?php
session_start() ;
$_SESSION["foobar"] = "Hello Word !";
...
?>

Toute modification ultérieure dans le script des variables de session (avant la fermeture de la session) sera automatiquement répercutée autant dans la session que dans l'espace mémoire des données du script en exécution.

Tous les types de variable, hormis les ressources, sont acceptés : chaînes, nombres, tableaux, objets (dont la classe doit être incluse avant le démarrage de la session).

Exemple avec une variable objet :

 
Sélectionnez
<?php
require("../common/visitor.class.php");
session_start() ;
$_SESSION["myVisitor"] = new Visitor();
...
?>
Mis à jour le 6 août 2008  par Cyberzoide

Lien : Les objets font-ils bon ménage avec les sessions en PHP 5 ?
Lien : Les objets font-ils bon ménage avec les sessions en PHP 4 ?

La commande session_is_registered (obsolète) renvoie TRUE si la variable dont l'identificateur est passé en paramètre a déjà été engegistrée parmi les variables de session.

Exemple :

 
Sélectionnez
<?ph
psession_start() ;
$foobar = "toto";
if(!session_is_registered("foobar")) {
    session_register("foobar");
}
...
?>

Si vous utilisez l'option register_globals=off, il faudra tester l'existence d'une variable dans la session à l'aide de la fonction isset().

Exemple :

 
Sélectionnez
<?php
session_start() ;
$_SESSION["foobar"] = "toto";
if(!isset($_SESSION["foobar"])) {
    $_SESSION["foobar"] = "toto";
}
...
?>
Mis à jour le 6 août 2008  par Cyberzoide

La commande session_unregister() (obsolète) supprime une variable dans la session courante. Elle a pour syntaxe :

 
Sélectionnez
boolean session_unregister (string name)

Elle retourne TRUE en cas de succès, FALSE sinon.

Si vous utilisez le tableau superglobal $_SESSION, il suffit alors d'utiliser unset() :

 
Sélectionnez
unset($_SESSION["mavariable"]);

Il est aussi possible de purger toutes les variables de la session avec session_unset().

Note : Si vous utilisez $_SESSION (ou $HTTP_SESSION_VARS), utilisez plutôt ceci :

 
Sélectionnez
$_SESSION = array();
Mis à jour le 6 août 2008  par Cyberzoide

Dès que l'on ferme le navigateur la session est détruite. Sauf à configurer le fichier php.ini avec session.lifetime qui fixe la durée de vie, en secondes, du cookie envoyé au client. La valeur 0 signifie "jusqu'à ce que le client soit fermé". Par défaut à 0.
Donc si on le laisse à zéro, la session dure jusqu'à la fermeture du navigateur, pour laisser les données durant 30 minutes, il faut remplacer 0 par 1800 (= 30 minutes * 60 secondes dans une minute).
session.lifetime = 0

Mis à jour le 6 août 2008  par Cyberzoide
Mis à jour le 6 août 2008  par Cyberzoide

Répertoire de session inaccessibleWarning: open(/tmp\sess_3c80883ca4e755aa72803b05bce40c12, O_RDWR) failed: m (2) in c:\phpdev\www\bp\header.php on line 2
ou encore :
PHP Warning: Unknown(): open(/tmp\sess_3c80883ca4e755aa72803b05bce40c12, O_RDWR) failed: No such file or directory (2) in Unknown on line 0
PHP Warning: Unknown(): Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/tmp) in Unknown on line 0

Cette erreur est due à l'absence du répertoire de sauvegarde (ici /tmp) des sessions ou bien au manque du droit d'écriture dans ce répertoire pour les visiteurs (utilisateur nobody, www-data ou autre... sous Apache).

Le répertoire de sauvegarde est défini dans le php.ini : session.save_path = /tmp

Il faut donc:

  • Créer un répertoire
  • Lui donner les droits d'écriture pour tous
  • En spécifier le chemin dans le php.ini

PHP n'est pas autorisé à utiliser les sessions Il faut s'assurer que le PHP est bien autorisé a créer des sessions. C'est juste un paramètre à activer. Faire un phpinfo() pour voir ces paramètres. La commande phpinfo() se contente d'afficher dans le navigateur le contenu du fichier de configuration php.ini.

Avoir déjà écrit dans la pageWarning: Cannot send session cookie - headers already sent by (output started at /home/SiteWeb/SiteAnalyse/index.php:3) in /home/SiteWeb/SiteAnalyse/index.php on line 6
Cette erreur survient lorsqu'on tente d'ouvrir une session après avoir déjà écrit dans le document, ce qui interdit, bien sûr.

Tentative d'envoi d'en-têtesWarning: Cannot add header information - headers already sent by (output started at /home/SiteWeb/SiteAnalyse/index.php:3) in /home/SiteWeb/SiteAnalyse/index.php on line 25
Cette erreur survient lorsqu'on tente d'envoyer des en-têtes grâce à la fonction header() après avoir écrit dans la page.

On ne peut pas commencer une session après que le serveur ait envoyé au client les en-têtes HTTP/1.0 (ou supérieures) de la page.

Ainsi, la commande session_start() doit impérativement être exécutée avant tout envoi par le serveur d'en-têtes HTTP au navigateur.

L'identifiant de session étant envoyé sous forme de cookie au client, ce dernier doit être envoyé avant que la page ne s'affiche car l'affichage force l'envoi d'en-têtes.

Tout contenu texte placé avant session_start() (même un saut de ligne) provoque un affichage et donc l'envoi d'en-têtes qui doivent précéder le contenu de la page.

Ce qu'il ne faut pas faire :

 
Sélectionnez
<html>
<body>
<?php 
session_start();
...

Ceci non plus :

 
Sélectionnez
<?php
echo "<html>";
...
session_start();

Car cela provoque l'envoi d'en-têtes au navigateur. Donc ces deux essais sont erronés. Il faut faire le session_start() avant toute chose !!!

Même un simple saut de ligne dans le script avant session_start() provoque cette erreur.

Défaut de déclaration de classeFatal error: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition utilisateur of the object you are trying to operate on was loaded _before_ the session was started in /home/SiteWeb/SiteAnalyse/test.php on line 12
Lorsqu'une variable que l'on veut enregistrer dans une session est un objet, PHP doit pouvoir en connaître la description, il faut donc déclarer les classes avant de faire un session_start().

Mis à jour le 6 août 2008  par Cyberzoide

Ci-après les options de configuration des sessions du fichier php.ini

session.save_handler
définit les noms des fonctions qui seront utilisées pour enregistrer et retrouver les données associées à une session. Par défaut, les sessions sont enregistrées dans des fichiers. Mais on pourrait les enregister dans une base de données ; il faudrait alors définir les fonctions d'écriture dans la base et les spécifier à session.save_handler.

session.save_path
définit l'argument qui est passé à la fonction de sauvegarde. Si vous utilisez la sauvegarde par fichier, cet argument est le chemin jusqu'au dossier où les fichiers sont créés. Par défaut, le dossier est /tmp. Si le dossier que vous utilisez a les droits de lecture universelle, comme /tmp (valeur par défaut), les autres utilisateurs du serveur peuvent aussi lire ces fichiers, et s'immiscer dans vos sessions.

session.name
spécifie le nom de la session, qui sera utilisé comme nom de cookie. Par défaut : PHPSESSID.

session.auto_start
indique qu'une session doit commencer automatiquement lors de la premiere requête. Par défaut, la valeur est à 0 (inactivé) ; il faut donc utiliser session_start().

session.lifetime
fixe la durée de vie, en secondes, du cookie envoyé au client. La valeur 0 signifie "jusqu'à ce que le client soit fermé". Par défaut à 0 (inactivé).

session.serialize_handler
définit le nom de la fonction qui sera utilisée pour enregistrer et relire les donnés. Actuellement, c'est un format interne de PHP (nom : php) et WDDX (nom : wddx). WDDX n'est utilisable que si PHP a été compilé avec le support WDDX. Par défaut, c'est le mode PHP qui est sélectionné.

session.gc_probability
précise la probabilité que la routine gc (garbage collection) soit lancée, en pourcentage. Par défaut, la valeur est à 1.

session.gc_maxlifetime
fixe la durée, en secondes, au-delà de laquelle les données considérées comme inutiles seront supprimées.

session.referer_check
représente la sous-chaîne que vous utilisez pour vérifier la provenance de l'internaute. Si l'en-tête HTTP Referer vous est fournie par le navigateur et que cette sous-chaîne n'est pas trouvée, la session qui vous est fournie sera considérée comme invalide (car provenant probablement d'un autre site que le vètre). Par défaut, cette chaîne est vide.

session.entropy_file
est le chemin jusqu'à une source externe (fichier) d'entropie, qui sera utilisée lors de la création de l'identifiant de session. Par exemple, /dev/random ou /dev/urandom qui sont disponibles sur de nombreux systèmes UNIX.

session.entropy_length
précise le nombre d'octets qui seront lus dans le fichier ci-dessus. Par défaut, 0 (inactivé).

session.use_cookies
indique si le module doit utiliser des cookies pour enregistrer l'identifiant de session chez le client. Par défaut, 1 (activé). Ce qui suppose que le client accepte les cookies, ce qui n'est pas acquis ! C'est pourquoi certains serveurs font le choix de ne pas stocker l'identifiant de session sous forme de cookie mais le rajoutent systématiquement en paramètre dans toutes les URL.

session.cookie_path
spécifie le chemin à utiliser avec session_cookie. Par défaut, /.

session.cookie_domain
spécifie le domaine à utiliser avec session_cookie. Par défaut, rien du tout.

session.cache_limiter
spécifie le contrèle du cache, à utiliser avec les pages de session (nocache/private/public). Par défaut, nocache.

session.cache_expire
spécifie la durée de vie des pages de session cachées, en minutes, mais sans que cela ait d'effets sur le limiteur "nocache". Par défaut, 180.

session.use_trans_sid
indique si le support du SID est activé ou pas, lors de la compilation avec l'option --enable-trans-sid. Par défaut, elle vaut 1 (activée).

url_rewriter.tags
spécifie si les balises html sont réécrites pour inclure l'identifiant de session si sid est activé. Par défaut, a=href, area=href, frame=src, input=src, form=fakeentry. Permet de passer l'identifiant de session de page en page par l'URL pour parer au refus de cookie, c'est la seule alternative à session.use_cookies.

Mis à jour le 6 août 2008  par Cyberzoide

Chez free, le répertoire de sessions doit être à la racine de votre compte FTP. Il suffit donc de créer le répertoire sessions (au pluriel).

Mis à jour le 6 août 2008  par Cyberzoide

Dans le cas où un serveur HTTP héberge plusieurs applications PHP utilisant chacune les sessions, il peut y avoir des problèmes si plusieurs applications utilisent les mêmes variables de sessions (lorsque un utilisateur visite simultanément plusieurs applications).

Pour résoudre ce problème il suffit de définir un nom de session différent pour chacune des applications lors de la création de la session :

 
Sélectionnez
session_name('appli1');
session_start();


Puis de rappeler ce nom lors de l'utilisation des variables de la session dans l'application.

 
Sélectionnez
session_name('appli1');
session_start();

Autre solution, au démarrage d'une nouvelle session, pour éviter tout conflit dans l'utilisation des noms de variables de session, spécifier un autre chemin de sauvegarde des données de session avec session_save_path().

Mis à jour le 6 août 2008  par Cyberzoide

Ce problème se pose lorsque l'on a 'session.use_trans_sid' à 1 (On). Pour chaque lien (balise <a>), formulaire (<form>) et d'autres balises, PHP va apporter des modifications.

Par exemple, pour un lien, PHP va rajouter &PHPSESSID=sid ou sid est l'identifiant de session dans le lien, en transparence. En XHTML, un & indique une référence HTML (par exemple &nbsp; espace insécable). Ce sera donc invalide pour la norme XHTML. Par contre, un &amp; sera valide. PHP va chercher ce caractère d'argument dans sa configuration, c'est a dire dans php.ini. Il est donc possible de modifier le & par défaut en &amp; à l'aide de la fonction ini_set() de la manière suivante :

 
Sélectionnez
<?php
// à placer avant session_start();
ini_set('arg_separator.output', '&amp;');
?>

Le problème est maintenant réglé pour les liens. Attaquons nous aux formulaires. Là, c'est plus délicat car PHP rajoute un input de type hidden contenant l'id de session directement à la suite de chaque <form>, ce qui est totalement invalide en XHTML. Pour contrer ceci, la solution est plus radicale. Il nous faut redéfinir quelles balises PHP modifie pour passer son identifiant de session.

 
Sélectionnez
<?php
// à placer avant session_start();
ini_set("url_rewriter.tags","a=href,area=href,frame=src,iframe=src,input=src");
?>

A la base, url_rewriter.tags contenait form=fakeentry. Cette partie a été supprimée, et PHP ne modifiera plus les balises <form>. On peut aussi contourner ce problème en utilisant des fieldsets au lieu de forms.

Mis à jour le 6 août 2008  par Emerica

Easyphp 1.7 installe PHP 4.3 dont le fichier de configuration par défaut met la variable register_globals à off ce qui oblige à utiliser les tableaux superglobaux et peut donc poser quelques problèmes pour les sessions.
Pour rendre compatible le code, faites les remplacements suivants :

 
Sélectionnez
$ma_variable_de_session  -> $_SESSION['ma_variable_de_session']
                
session_register('variable') -> $_SESSION['variable'] = $variable

session_is_registered('variable') -> isset($_SESSION['variable'])

session_unregister('variable') -> unset($_SESSION['variable'])

session_unset() -> $_SESSION = array();

Il est vrai que remettre register_globals à on pourrait régler tous ces problèmes mais cela est fortement déconseillé car cela crée un énorme trou de sécurité dans votre application. Sachez également que si une application est développée avec register_globals à off, elle restera utilisable et avec le même niveau de sécurité si elle est exécutée avec register_globals à on.

Créé le 12 février 2004  par Nonothehobbit

Une méthode peut être mise en place. Le numéro de session ne change jamais. À chaque page, un autre numéro de session aléatoire est généré. Il est stocké dans une variable session et dans un cookie envoyé au client. À la page suivante, on vérifie que le numéro stocké dans la session est bien le même que celui dans le cookie. S'ils sont différents, la session est détruite et les deux (pirate et utilisateur) sont déconnectés. Le délai d'action du pirate qui aurait volé un numéro de session est donc réduit. L'inconvénient est que si l'utilisateur consultait sa dernière page (donc qu'il a fermé son navigateur sans fermer sa session) le numéro reste disponible. La seule solution reste d'éduquer les utilisateurs pour qu'ils cliquent systématiquement sur "se déconnecter" en quittant le site.

 
Sélectionnez
<?php
if($logged_in)
{
    // Test des valeurs extérieures afin de vérifier qu'elles n'ont pas été modifiées
    if(!ctype_digit($_COOKIE['id_aleatoire']) or !ctype_digit($_SESSION['id_aleatoire']))
    {
        // Ce ne sont pas des valeurs automatiques => tentative de piratage
    }
    else
    {
        // Récupération l'id dans le cookie
        $id2 = $_COOKIE['id_aleatoire'];

        // Vérification de l'existance
        if( isset($_SESSION['id_aleatoire']) )
        {
            // Comparaison de l'id du cookie avec l'id de la session
            if($id2 != $_SESSION['id_aleatoire'])
            {
                // Si les deux valeurs sont différentes, on détruit la session
                logout();
            }
            else
            {
                // On génère une nouvelle valeur de cookie et dans la variable session
                // Définition de la durée du cookie tjs en secondes dont la date d'expiration est un jour
                $expire = time()+24*3600;

                // Création d'un nb aléatoire que l'on stocke en session et dans le cookie
                $nb_aleatoire = mt_rand();

                // Stockage de ce nombre en session
                $_SESSION['id_aleatoire'] = $nb_aleatoire;

                // Stockage de ce nombre dans le cookie
                setcookie("id_aleatoire", $nb_aleatoire, $expire);
            }
        }
    }
}
?>
Créé le 8 février 2007  par july

Après une mise à jour d'Internet Explorer vers IE 7, les variables de session n'étaient plus transmises à la page provenant d'un autre site Web contenue dans un <IFRAME></IFRAME> (les variables de la session étaient détruites).

L'astuce consiste à envoyer une en-tête HTTP spécifique (en-tête de stratégie compacte P3P / Microsoft) :

 
Sélectionnez
<?php
// avant session_start()
header('P3P: CP="CAO PSA OUR"');

Selon Microsoft :
La norme P3P indique que, si une balise FRAMESET ou une fenêtre parente référence un autre site à l'intérieur d'une TRAME ou à l'intérieur d'une fenêtre enfant, le site enfant est considéré comme contenu de tiers. Internet Explorer, qui utilise le paramètre de confidentialité par défaut Moyen, repousse silencieusement des cookies envoyés par des sites tiers.

Créé le 5 juillet 2009  par Thierry Godin
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2003 Developpez.com Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.