2010-09-24 7 views
40

par demande, il y a quelques façons différentes que vous pouvez dire si oui ou non une session a été commencé, comme:Comment savoir si une session est active?

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

Ou:

$isSessionActive = defined('SID'); 

Cependant, ces deux échouer si vous commencer une session, puis fermez-la; session_id() renverra l'ID de la session précédente, tandis que SID sera défini. De même, l'appel session_start() à ce stade va générer un E_NOTICE si vous avez déjà une session active. Est-il un moyen sain d'esprit pour vérifier si une session est en cours, sans avoir à recourir à la mise en mémoire tampon de sortie, l'opérateur shut-up (@session_start()), ou quelque chose d'autre tout aussi aki?

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

EDIT 8/29/2011: Nouvelle fonction ajoutée à PHP 5.4 pour résoudre ce problème: "Expose session status via new function, session_status"

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

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

+0

Ceci est peut-être hacky: ['session_is_active()'] (http://stackoverflow.com/questions/3788369/how-to-tell-if-a-session-is-active/7656468#7656468), mais au moins quelque chose que j'ai trouvé. Merci pour le rapport de bug de toute façon, c'est bien de le voir résolu en 5.4. – hakre

+0

Encore une question pertinente avec l'addition de 5.4, comme je viens de pousser à une boîte 5.3 et trouvé 'session_status()' manquant! – quickshiftin

+0

C'est certainement étrange, car il est effectivement présent sur ma version 5.4. Areyou disant que vous utilisez 5.3 ou 5.4? Était-ce un binaire PHP personnalisé ou pré-intégré? Dans 'phpinfo()', avez-vous une section "session"? En action: http://codepad.viper-7.com/PiZmcw – ken

Répondre

3

Le code suivant dumps un seul session_id() pour moi, pas deux

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

Si vous éprouvez des difficultés avec ce que vous pouvez toujours essayer de créer une variable pour vérifier que vous détruisez lorsque vous détruisiez la session.

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

Mais si vous utilisez session_write_close(), les données fermées de la session, mais $ _SESSION sont toujours là, ce qui est ce que je pense que le PO est en train de faire ... vérifiez-vous si le fichier de session est toujours en cours d'utilisation? –

+0

Ouais, vous avez essentiellement posté la même solution que moi, en définissant une variable avant de la fermer (en aucune façon) et en vérifiant cette variable ... – Robert

+0

Ce que Marc B a dit. – ken

0

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

+1

'session_destroy()' ni 'session_write_close()' non défini '$ _SESSION'. – hakre

15

J'ai travaillé autour de ce en ajoutant des fonctions wrapper couple autour des différentes mesures de création de la session/fermeture/fonctions détruire. 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.

+0

Eh bien, c'est aussi la solution que j'ai choisie ...l'alternative aurait probablement implémenté un gestionnaire d'écriture de session qui modifie un indicateur interne que vous pouvez ensuite vérifier, mais cela aurait en quelque sorte vaincu son propre objectif car il faudrait le définir au début. – Archimedix

+0

Dans la fonction session_close, il existe un crochet bouclé qui doit être un point-virgule. SO ne me laissera pas éditer parce que pas assez de caractères ont besoin d'éditer. :/ – ShadeTreeDeveloper

10

Je suis en cours d'exécution dans ce aussi bien, et une mise en $_SESSION est pas une option pour moi. Pour PHP 5.3.8:

  1. Si une session a été lancé à la demande, define('SID') renverra FALSE, ainsi que $_SESSION est hors service.
  2. Ceci est indépendant ou non 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 sur un tableau vide.
  4. session_destroy() désactive le session_id(), c'est une chaîne vide alors. SID restera défini (et mis à sa valeur précédente qui pourrait être une chaîne vide). $_SESSION est laissé inchangé. Il sera réinitialisé/rempli la prochaine fois session_start est appelée.

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

« Trying » avec session_start() (par exemple avec @) pourrait ne pas être vraiment utile, car cela va changer l'état de session et modifier le contenu de $_SESSION (et en ajoutant un en-tête set-cookie si le cookie ne faisait pas partie de la demande). Ce n'était pas approprié dans mon cas.

Pendant que j'exécutais des tests, je suis tombé sur le comportement, que vous ne pouvez pas essayer de modifier le paramètre ini de session.serialize_handler lorsque la session est active, même si vous le définissez à la même valeur. La même chose est vraie pour session.use_trans_sidDocs qui est plus léger. Cela me 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; 
} 

Pour autant que je peux voir, l'erreur est la vérification de l'état de session active uniquement (non désactivé), donc cela ne devrait pas revenir un faux positif lorsque les sessions sont désactivées.

Pour obtenir cette fonction compatible avec PHP 5.2, il a besoin d'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 sandbox.

+1

Bien que ce soit encore un peu «hacky», je suis impressionné par votre technique. Je pensais qu'il y avait certains attributs du problème qui se prêteraient à l'inférence (comme ce que vous faites ici), j'étais simplement incapable de les trouver. Très agréable! – ken

+0

De plus, le bac à sable est-il votre site? L'analyse de l'opcode est douce. – ken

+0

Non, ce n'est pas mon site, mais je l'aime aussi. :) En ce moment je ne suis pas sûr avec ce hack si cela fonctionne pour PHP 5.1 (je pourrais avoir besoin de cela). – hakre

1

Voici une bonne baisse de remplacement qui ne cassera pas des choses lorsque vous passez à 5.4:

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

Comme je l'ai dit dans ma question initiale, c'est une solution inadéquate; si vous appelez 'session_start()', puis appelez 'session_write_close()', alors 'defined (" SID ") === true' même si la session n'est pas ouverte. Une telle technique peut seulement déterminer si une session a été commencée pendant le cycle de demande - et non si elle est actuellement ouverte. Cela peut fonctionner pour certains cas d'utilisation, mais cela ne remplace pas 'session_status()'. – ken

0

Il y a plusieurs endroits que vous devez vérifier pour vérifier la session est active:

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

+0

Je pense que vous avez mal compris le but/l'intention. – ken

+0

Peut-être que oui. Je suis plus habitué à traiter des sessions qui ont des fonctionnalités personnalisées. Il serait bon d'encapsuler la session dans une classe de sorte que lorsque le destructeur est appelé, ou que la fonction membre session_write_closed soit appelée, vous mettez à jour un indicateur booléen dans cette classe indiquant actif ou non. – beiller

+0

C'est pour éviter 'Remarque: Une session a déjà été démarrée - en ignorant session_start()'. Ce bug a plus d'informations sur le cas d'utilisation: http://bugs.php.net/bug.php?id=52982 – ken

Questions connexes