41 votes

Comment savoir si une session est active ?

Par requête, il existe plusieurs façons de savoir si une session a été lancée ou non, par exemple :

$isSessionActive = (session_id() != "");

Ou :

$isSessionActive = defined('SID');

Cependant, elles échouent toutes deux si vous démarrez une session, puis la fermez ; session_id() retournera l'ID de la session précédente, tandis que SID seront définis. De même, l'appel à session_start() à ce stade, génère un E_NOTICE si vous avez déjà une session active. Existe-t-il un moyen sain de vérifier si une session est actuellement active, sans devoir recourir à la mise en mémoire tampon de la sortie, à l'opérateur de fermeture ( @session_start() ), ou quelque chose d'autre tout aussi bidon ?

EDIT : J'ai écrit un patch pour essayer d'inclure cette fonctionnalité dans PHP : http://bugs.php.net/bug.php?id=52982

MODIFIER 8/29/2011 : Nouvelle fonction ajoutée à PHP 5.4 pour résoudre ce problème : "Exposer l'état de la session via une nouvelle fonction, session_status"

// as of 8/29/2011
$isSessionActive = (session_status() == PHP_SESSION_ACTIVE);

EDIT 12/5/11 : session_status() sur le manuel PHP.

22voto

ken Points 1925

Voir les modifications apportées à la question d'origine ; en fait, PHP 5.4 et les versions ultérieures ont maintenant une fonction appelée session_status() pour résoudre ce problème !

"Exposer l'état de la session via une nouvelle fonction, session_status" (SVN Revision 315745)

Si vous avez besoin de cette fonctionnalité dans une version antérieure à PHP 5.4, voir réponse de hakre .

15voto

Marc B Points 195501

J'ai contourné ce problème en ajoutant quelques fonctions enveloppantes autour des diverses fonctions de création/fermeture/destruction de session. En gros :

function open_session() {
     session_start();
     $_SESSION['is_open'] = TRUE;
}

function close_session() {
   session_write_close();
   $_SESSION['is_open'] = FALSE;
}

function destroy_session() {
   session_destroy();
   $_SESSION['is_open'] = FALSE;
}

function session_is_open() {
   return($_SESSION['is_open']);
}

Hackish, mais a accompli ce dont j'avais besoin.

10voto

hakre Points 102271

J'ai également rencontré ce problème, et un paramètre dans $_SESSION n'est pas une option pour moi. Pour PHP 5.3.8 :

  1. Si une session a été lancée avec la demande, define('SID') retournera FALSE ainsi que $_SESSION n'est pas réglé.
  2. Ceci est indépendant du fait que session_id() a été utilisé pour définir un identifiant de session ou non.
  3. Après le premier session_start() , SID est défini et $_SESSION est défini comme un tableau vide.
  4. session_destroy() ne désactive pas l'option session_id() c'est une chaîne vide alors. SID restera défini (et prendra sa valeur précédente, qui peut être une chaîne vide). $_SESSION est laissé inchangé. Il sera réinitialisé/peuplé la prochaine fois. session_start s'appelle.

Avec ces états, d'autant plus que session_id() peut être appelé entre les deux afin de définir l'identifiant de l'utilisateur. suivant il n'est pas possible de déterminer en toute sécurité l'état de la session à l'aide de la fonction SID , $_SESSION y session_id() .

"Essayer" avec session_start() (par exemple, avec @ ) n'est pas vraiment utile, car cela modifiera l'état de la session et le contenu du fichier $_SESSION (et l'ajout d'un en-tête set-cookie si le cookie ne faisait pas partie de la demande). Dans mon cas, cela ne convenait pas.

Pendant que j'effectuais des tests, j'ai constaté que l'on ne pouvait pas essayer de modifier le paramètre ini de l'option session.serialize_handler lorsque la session est active, pas même lorsque vous la définissez à la même valeur. Il en va de même pour session.use_trans_sid Docs qui est plus léger. Cela m'a conduit à la fonction suivante :

/**
 * @return bool
 */
function session_is_active()
{
    $setting = 'session.use_trans_sid';
    $current = ini_get($setting);
    if (FALSE === $current)
    {
        throw new UnexpectedValueException(sprintf('Setting %s does not exists.', $setting));
    }
    $result = @ini_set($setting, $current); 
    return $result !== $current;
}

D'après ce que je vois, l'erreur vérifie uniquement l'état de la session active (et non désactivée), ce qui ne devrait pas renvoyer un faux positif lorsque les sessions sont désactivées.

Pour que cette fonction soit compatible avec PHP 5.2, elle nécessite une petite modification :

/**
 * @return bool
 */
function session_is_active()
{
    $setting = 'session.use_trans_sid';
    $current = ini_get($setting);
    if (FALSE === $current)
    {
        throw new UnexpectedValueException(sprintf('Setting %s does not exists.', $setting));
    }
    $testate = "mix$current$current";
    $old = @ini_set($setting, $testate);
    $peek = @ini_set($setting, $current);
    $result = $peek === $current || $peek === FALSE;
    return $result;
}

Quelques bac à sable .

5voto

Robert Points 12091

Le code suivant ne vide qu'un seul session_id() pour moi, et non deux

session_start();
echo session_id();
session_destroy();
echo session_id();

Si vous avez encore des difficultés avec cela, vous pouvez essayer de créer une variable à vérifier, que vous détruisez lorsque vous détruisez la session.

session_start();
$_SESSION['intialized'] = 'This will not print';
$_SESSION = array(); // Unset all variables
session_destroy();
echo $_SESSION['initialized']; // No output

1voto

Beachhouse Points 1245

Voici une bonne solution de remplacement qui ne cassera rien lorsque vous passerez à la version 5.4 :

if(!function_exists('session_status')){
    function session_active(){
        return defined('SID');   
    }
}else{
    function session_active(){
        return (session_status() == PHP_SESSION_ACTIVE);   
    }        
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X