web-dev-qa-db-fra.com

Comment savoir si une session est active?

Sur demande, il existe différentes manières de déterminer si une session a été lancée ou non, telles que:

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

Ou:

$isSessionActive = defined('SID');

Cependant, ces deux-là échouent si vous démarrez une session, puis fermez-la; session_id() retournera l'ID de la session précédente, alors que SID sera défini. De même, appeler session_start() à ce stade générera un E_NOTICE si une session est déjà active. Existe-t-il un moyen sain de vérifier si une session est actuellement active, sans avoir à recourir à la mise en mémoire tampon de sortie, à l'opérateur de fermeture (@session_start()) ou à un autre moyen tout aussi hacky?

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

EDIT 29/08/2011: Une nouvelle fonction a été ajoutée à PHP 5.4 pour résoudre ce problème: "Exposer le statut de la session via une nouvelle fonction, statut_session" 

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

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

41
ken

Voir les modifications apportées à la question d'origine; En gros, PHP 5.4 et supérieur a maintenant une fonction appelée session_status() pour résoudre ce problème!

"Exposer le statut de la session via une nouvelle fonction, statut_session" (SVN Révision 315745)

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

22
ken

J'ai corrigé ce problème en ajoutant quelques fonctions d'emballage aux différentes fonctions de création/fermeture/destruction de session. Fondamentalement:

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 accompli ce dont j'avais besoin.

15
Marc B

Je suis aussi confronté à cela, 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') renverra FALSE, de même que $_SESSION est non défini.
  2. Cela est indépendant du fait que session_id() ait été utilisé ou non pour définir un identifiant de session.
  3. Après la première session_start(), SID est défini et $_SESSION est défini sur un tableau vide.
  4. session_destroy() désactive la session_id(), c'est une chaîne vide alors. SID restera défini (et définira sa valeur précédente qui pourrait être une chaîne vide). $_SESSION reste inchangé. Il sera réinitialisé/rempli la prochaine fois que session_start sera appelé.

Avec ces états, d'autant plus que session_id() peut être appelé entre pour définir l'id de la session next, il n'est pas possible de déterminer en toute sécurité l'état de la session avec SID, $_SESSION et session_id().

"Essayer" avec session_start() (par exemple avec @) pourrait ne pas être très utile, car cela modifierait le statut de la session et modifierait le contenu de $_SESSION (et l'ajout d'un en-tête set-cookie si le cookie ne faisait pas partie de la requête). Cela ne convenait pas dans mon cas.

Pendant que j’exécutais des tests, j’ai rencontré le problème suivant: vous ne pouvez pas essayer de modifier le paramètre ini de session.serialize_handler lorsque la session est active, même lorsque vous le définissez à la même valeur. Même chose pour session.use_trans_sidDocs 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;
}

Autant que je sache, l'erreur vérifie uniquement le statut de la session active (non désactivé). Par conséquent, cela ne devrait pas donner de résultat faussement positif lorsque les sessions sont désactivées.

Pour que cette fonction soit compatible avec PHP 5.2, il faut 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;
}

Certains bac à sable .

10
hakre

Le code suivant ne vide qu'une session_id () pour moi, pas deux

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

Si vous rencontrez des difficultés avec cela, vous pouvez toujours 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
4
Robert

Voici une bonne solution de remplacement qui ne casse rien lorsque vous passez à 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);   
    }        
}
1
Beachhouse

Vous devez vérifier plusieurs endroits pour vérifier que la session est active:

1- Le cookie existe et n'est pas expiré 2- Le mécanisme de stockage de session sous-jacent (système de fichiers ou base de données) contient un enregistrement correspondant au cookie.

0
beiller

Ken, si la session est détruite, le tableau $ _SESSION ne devrait pas être disponible ... ou tout au moins, vos valeurs devraient être non définies. Donc, en théorie (non testé), vous devriez pouvoir vérifier dans le tableau une valeur pour savoir si quelque chose est actuellement défini.

0
bpeterson76