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);
}
}
}