2010-09-24 22 views
40

Pro Anfrage gibt es ein paar verschiedene Möglichkeiten, wie Sie, ob eine Sitzung gestartet wurde das beurteilen kann, wie zum Beispiel:Wie kann ich feststellen, ob eine Sitzung aktiv ist?

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

Oder:

$isSessionActive = defined('SID'); 

diese jedoch beide fehlschlagen, wenn Sie Starten Sie eine Sitzung und schließen Sie sie. session_id() gibt die ID der vorherigen Sitzung zurück, während SID definiert wird. Wenn Sie zu diesem Zeitpunkt session_start() aufrufen, wird E_NOTICE generiert, wenn Sie bereits eine Sitzung aktiviert haben. Gibt es einen vernünftigen Weg, um zu überprüfen, ob eine Sitzung gerade aktiv ist, ohne auf die Pufferung der Ausgabe zurückgreifen zu müssen, den "Shut-Up" -Operator (@session_start()) oder etwas anderes, genauso wie Hacky?

EDIT: Ich habe einen Patch, um zu versuchen schrieb in PHP enthalten diese Funktionalität zu erhalten: http://bugs.php.net/bug.php?id=52982

EDIT 2011.08.29: Neue Funktion hinzugefügt, um PHP 5.4 zu beheben diese: "Expose session status via new function, session_status"

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

EDIT 05.12.2011: session_status() auf das PHP-Handbuch.

+0

Dies ist vielleicht hacky: ['session_is_active()'] (http://stackoverflow.com/questions/3788369/how-to-tell-if-a-session-is-active/7656468#7656468), aber zumindest etwas, was ich gefunden habe. Danke für den Fehlerbericht, schön zu sehen, dass dies in 5.4 gelöst wurde. – hakre

+0

Noch eine relevante Frage mit dem 5.4 Zusatz, da ich gerade auf eine 5.3 Box gedrängt habe und 'session_status()' fehlt! – quickshiftin

+0

Das ist sicherlich merkwürdig, wie es tatsächlich auf meinem 5.4 Build ist. Willst du sagen, dass du 5.3 oder 5.4 benutzt? War es eine benutzerdefinierte oder vordefinierte PHP-Binärdatei? Haben Sie in 'phpinfo()' einen Abschnitt "Sitzung"? In Aktion: http://codepad.viper-7.com/PiZmcw – ken

Antwort

3

Der folgende Code-Dumps nur eine session_id() für mich, zwei nicht

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

Wenn Sie mit dieser Schwierigkeiten haben, sind nach wie vor können Sie versuchen, eine Variable erstellen, um zu überprüfen, dass Sie zerstören, wenn Sie zerstören die Sitzung.

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

Aber wenn Sie session_write_close() verwenden, ist die Sitzung geschlossen, aber $ _SESSION Daten sind immer noch da, was ist, was ich denke, dass die OP bekommen ... wie überprüfen Sie, ob die Sitzungsdatei selbst noch verwendet wird? –

+0

Ja, du hast im Grunde die gleiche Lösung gepostet, die ich gemacht habe, indem ich eine Variable gesetzt habe, bevor ich sie geschlossen habe (in irgendeiner Weise) und diese Variable überprüft habe ... – Robert

+0

Was Marc B gesagt hat. – ken

0

Ken, wenn die Sitzung zerstört wird, sollte das Array $ _SESSION nicht zur Verfügung ... oder zumindest sollten Sie Ihre Werte nicht gesetzt sein. Also, in der Theorie (ungetestet) sollten Sie in der Lage sein, das Array auf einen Wert zu überprüfen, um zu wissen, ob gerade etwas gesetzt ist.

+1

'session_destroy()' noch 'session_write_close()' unset '$ _SESSION'. – hakre

15

Ich arbeitete um dieses herum, indem ich ein paar Wrapper-Funktionen um die verschiedenen Funktionen Session Creation/Closing/Destroying hinzufügte. Grundsätzlich:

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, aber erreicht, was ich brauchte.

+0

Nun, das ist auch die Lösung, die ich gewählt habe ...Die Alternative hätte wahrscheinlich einen Session-Write-Handler implementiert, der ein internes Flag modifiziert, das Sie dann überprüfen können, aber das hätte seinen eigenen Zweck besiegt, weil es am Anfang definiert werden müsste. – Archimedix

+0

in der Funktion session_close gibt es eine lockige geschweifte Klammer, die ein Semikolon sein muss. SO lässt mich nicht bearbeiten, weil nicht genug Zeichen bearbeitet werden müssen. :/ – ShadeTreeDeveloper

10

Ich renne auch in diesem, und eine Einstellung in $_SESSION ist keine Option für mich. Für PHP 5.3.8:

  1. Wenn eine Sitzung mit dem Auftrag gestartet wurde, wird define('SID')FALSE zurückkehren, sowie $_SESSION ist nicht gesetzt.
  2. Dies ist unabhängig davon, ob session_id() zum Festlegen einer Sitzungs-ID verwendet wurde oder nicht.
  3. Nach dem ersten session_start() ist SID definiert und $_SESSION ist auf ein leeres Array festgelegt.
  4. session_destroy() deaktiviert die session_id(), es ist dann eine leere Zeichenfolge. SID bleibt definiert (und auf den vorherigen Wert gesetzt, der eine leere Zeichenfolge sein könnte). $_SESSION bleibt unverändert. Beim nächsten Aufruf wird session_start aufgerufen.

Mit diesen Staaten, vor allem als session_id() in aufgerufen werden zwischen der ID für die nächste Sitzung zu setzen, ist es nicht möglich, sicher den Sitzungsstatus mit SID, $_SESSION und session_id() zu bestimmen.

„Trying“ mit session_start() (zB mit @) ist vielleicht nicht wirklich hilfreich sein, da dies den Sitzungsstatus ändern und den Inhalt des $_SESSION zu wechseln (und das Hinzufügen eines Set-Cookie-Header, wenn das Cookie nicht Teil des Antrags war). Es passte in meinem Fall nicht.

Während ich Tests ausgeführt habe, bin ich auf das Verhalten gestoßen, dass Sie nicht versuchen können, die Ini-Einstellung von session.serialize_handler zu ändern, wenn die Sitzung aktiv ist, nicht einmal wenn Sie denselben Wert einstellen. Gleiches gilt für session.use_trans_sidDocs, die leichter ist. Dies führt mich zu der folgenden Funktion:

/** 
* @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; 
} 

Soweit ich sehen kann, ist der Fehler nur für aktive Sitzung Statusprüfung (nicht deaktiviert), so sollte dies nicht ein falsch positive zurück, wenn Sitzungen deaktiviert sind.

diese Funktion mit PHP 5.2 kompatibel zu erhalten, braucht es eine kleine Änderung:

/** 
* @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; 
} 

Einige sandbox.

+1

Während dies immer noch etwas "hacky" ist, bin ich von Ihrer Technik beeindruckt. Ich dachte, dass es einige Attribute des Problems gäbe, die sich für Schlussfolgerungen eignen (wie das, was Sie hier tun), ich konnte sie einfach nicht finden. Sehr schön! – ken

+0

Ist die Sandbox auch deine Seite? Die Opcode-Analyse ist süß. – ken

+0

Nein, das ist nicht meine Seite, aber ich mag sie auch. :) Im Moment bin ich mir bei diesem Hack nicht sicher, ob es für PHP 5.1 funktioniert (ich könnte das brauchen). – hakre

1

Hier ist ein guter Tropfen in Ersatz, der nicht Sachen brechen, wenn Sie 5.4 bewegen:

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

Wie ich in meiner ursprünglichen Frage gesagt habe, ist das eine unangemessene Lösung; Wenn Sie 'session_start()' aufrufen und dann 'session_write_close()' aufrufen, dann ist 'defined (" SID ") === true', obwohl die Sitzung nicht geöffnet ist. Eine solche Technik kann nur bestimmen, ob eine Sitzung während des Anfragezyklus gestartet wurde - und nicht, ob eine gerade geöffnet ist oder nicht. Es kann für einige Anwendungsfälle funktionieren, aber es ist kein Ersatz für 'session_status()'. – ken

0

Es gibt mehrere Orte, die Sie müssen überprüfen, um die Sitzung zu überprüfen, ob aktiv:

1- Cookie existiert und ist nicht abgelaufen 2- zugrunde liegenden Sitzung Speichermechanismus (Dateisystem oder Datenbank) hat einen Datensatz mit dem Cookie.

+0

Ich glaube, du hast das Ziel falsch verstanden. – ken

+0

Vielleicht ja. Ich bin eher daran gewöhnt, mit Sitzungen zu arbeiten, die benutzerdefinierte Funktionen haben. Es wäre gut, die Sitzung in eine Klasse zu kapseln, so dass beim Aufruf des Destruktors oder beim Aufrufen der Memberfunktion session_write_closed ein boolesches Flag in dieser Klasse aktualisiert wird, das aktiv ist oder nicht. – beiller

+0

Es ist zu vermeiden 'Notice: Eine Sitzung wurde bereits gestartet - Session_start()' ignorierend. Dieser Fehler enthält weitere Informationen zum Anwendungsfall: http://bugs.php.net/bug.php?id=52982 – ken

Verwandte Themen