2010-12-27 8 views
2

Ich benutze Datenbank-Handler für meine Sitzungen, die gut funktionieren, aber jetzt stapeln ich in ein Problem bei der Authentifizierung.session_regenerate_id und Datenbank-Handler

Wenn ich mich mit Benutzername/Passwort anmelde, mache ich session_regenerate_id und danach versuche ich die aktuelle session_id auszuwählen.

Hier ist mein Code

session_regenerate_id(); 
echo $checkQ=" SELECT * FROM my_sessions WHERE id='".session_id()."' "; 
...... 

aber i dont keine Ergebnisse. Die Sitzungs-ID ist die richtige.

Nach dem Laden der Seite und kopieren Sie den SQL-Befehl in phpMyAdmin kopieren ich bekomme die Ergebnisse.

Ich weiß, dass das ist dumm, aber der einzige Grund, den ich denken kann ist, dass session_regenerate_id() "zu langsam ist" so wenn ich versuche, die Session-ID in der nächsten Zeile die Session-ID noch nicht in der Datenbank erstellt.

Kann mir jemand helfen!

Antwort

1

Ich weiß, dass es schon eine Weile her ist, ich hoffe, du hast eine Antwort gefunden, seit das gepostet wurde, aber ich werde meine Lösung der Nachwelt hinzufügen.

Der Aufruf von session_generate_id() den Wert von session_id() führen zu ändern:

<?php 
$before = session_id(); 
session_regenerate_id(); 
$after = session_id(); 
var_dump($before == $after); // outputs false 

Dieses Problem für mich manifestiert, weil in der Sitzung Schreib Handler ich dies (ohne eine solche falsche Methodennamen, natürlich) tat:

<?php 
class MySQLHandler 
{ 
    function read($id) 
    { 
     $row = $this->doSelectSql($id); 
     if ($row) { 
      $this->foundSessionDuringRead = true; 
     } 
     // snip 
    } 

    function write($id, $data) 
    { 
     if ($this->foundSessionDuringRead) { 
      $this->doUpdateSql($id, $data); 
     } 
     else { 
      $this->doInsertSql($id, $data); 
     } 
    } 
} 

Die Methode write() funktionierte gut, wenn session_regenerate_id() wurde nie genannt. Wenn es jedoch aufgerufen wurde, unterscheidet sich das $ id-Argument von write() von der $ id, die an read() übergeben wurde, so dass das Update keine Datensätze mit der neuen $ id finden wird, weil sie nie eingefügt wurden.

Einige Leute schlagen vor, MySQL "REPLACE INTO" -Syntax zu verwenden, aber das löscht und ersetzt die Zeile, die fröhliches Chaos spielt, wenn Sie eine Erstellungsdatumspalte haben möchten. Was ich tat, um das Problem zu beheben, war auf den Session-ID zu halten, die zu read verabschiedet wurden, aktualisieren Sie die Session-ID in der Datenbank während des Schreibens mit der ID read als Schlüssel übergeben:

<?php 
class MySQLHandler 
{ 
    function read($id) 
    { 
     $row = $this->doSelectSql($id); 
     if ($row) { 
      $this->rowSessionId = $id; 
     } 
     // snip 
    } 

    function write($id, $data) 
    { 
     if ($this->rowSessionId) { 
      $stmt = $this->pdo->prepare("UPDATE session SET session_id=:id, data=:data WHERE session_id=:rowSessionId AND session_name=:sessionName"); 
      $stmt->bindValue(':id', $id); 
      $stmt->bindValue(':rowSessionId', $this->rowSessionId); 
      $stmt->bindValue(':data', $data); 
      $stmt->bindValue(':sessionName', $this->sessionName); 
      $stmt->execute(); 
     } 
     else { 
      $this->doInsertSql($id, $data); 
     } 
    } 
} 
0

Ich denke, Ich habe das gleiche Problem wie du. Mir ist nicht klar, ob das eine PHP (Cache) -Funktion oder ein Bug ist.

Das Problem besteht darin, dass bei Verwendung eines benutzerdefinierten SessionHandlers und Aufruf von session_regenerate_id (true) die neue Sitzung erst erstellt wird, wenn das Skript beendet wird. Ich habe das bestätigt, indem ich dasselbe getan habe: SELECT der neuen Session-ID aus der Datenbank. Und die neue Sitzung ist nicht da. Nach Abschluss des Skripts ist dies jedoch der Fall.

Dies ist, wie ich es fest:

$old_id = session_id(); 
// If you SELECT your DB and search for $old_id, it will be there. 

session_regenerate_id(TRUE); 

$new_id = session_id(); 
// If you SELECT your DB for either $old_id or $new_id, none will be there. 

session_write_close(); 
session_start(); 

// If you SELECT your DB for $new_id, it will be there. 

Deshalb ist die Lösung (Abhilfe) kam ich war über PHP zu zwingen, um die Sitzung zu schreiben. Ich hoffe das hilft.

Verwandte Themen