これはしばらくお待ちしておりますが、これが掲載されてから回答がありましたことを願っていますが、私は後世のために解決策を追加します。
session_generate_id()
への呼び出しがsession_id()
の値が変化するようになります:
<?php
$before = session_id();
session_regenerate_id();
$after = session_id();
var_dump($before == $after); // outputs false
セッション書き込みハンドラで、私は(もちろん、そのような偽のメソッド名なし)にこれをやっていたので、この問題は私のために明らかに:
<?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);
}
}
}
session_regenerate_id()
が呼び出されなかった場合、write()メソッドは正常に機能しました。ただし、呼び出された場合、write()
の$ id引数は、read()
に渡された$ idとは異なります。したがって、挿入されていないため、新しい$ idのレコードは見つかりません。
MySQLの「REPLACE INTO」構文を使用することをお勧めする人もいますが、作成日の列を作成する場合は、行を削除して置き換えます。私は問題を解決するためにやったことはキーとしてread
に渡されたIDを使用して、書き込みの際に、データベースにセッションIDを更新し、read
に渡されたセッションIDを保持することでした:
<?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);
}
}
}