2010-12-27 9 views
2

私は正しく機能しているセッションにデータベースハンドラを使用していますが、認証時に問題が発生します。session_regenerate_idとデータベースハンドラ

ユーザがユーザ名/パスワードでログインしたときにsession_regenerate_idを実行した後、現在のsession_idを選択しようとしています。

は、ここに私のコード

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

ですが、私はどんな結果を得るいけません。 session_idが正しいです。

終了したら、ページをコピーしてSQLコマンドをphpMyAdminに貼り付けて、結果を取得します。

私はそれが愚かだと知っていますが、私が考えることができる唯一の理由は、session_idがデータベースにまだ作成されていない次の行でsession_idを読み取ろうとしたときにsession_regenerate_id()が "遅すぎます"ということです。

誰でも助けてくれますか?

答えて

1

これはしばらくお待ちしておりますが、これが掲載されてから回答がありましたことを願っていますが、私は後世のために解決策を追加します。

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

私は思いますあなたと同じ問題を抱えています。これがPHP(キャッシュ)機能かバグかどうかは不明です。

カスタムSessionHandlerを使用してsession_regenerate_id(true)を呼び出すと、スクリプトが終了するまで新しいセッションが作成されないという問題があります。私はあなたがしたのと同じことをすることでそれを確認しました:データベースから新しいセッションIDを選択する。そして、新しいセッションはそこにはありません。しかし、スクリプトが終了した後は、それが終了します。

これは、私はそれを固定する方法である:

$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. 

そこで解決策(回避策)私は約セッションを書くためにPHPを強制することでした来ました。私はこれが役立つことを願っています

関連する問題