2010-12-27 4 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_regenerate_id() «слишком медленный», поэтому, когда я пытаюсь прочитать session_id на следующей строке, session_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() никогда не называли. Однако если он был вызван, аргумент $ id для write() отличается от $ id, переданного read(), поэтому обновление не найдет записи с новым $ id, потому что они никогда не были вставлены.

Некоторые люди предлагают использовать синтаксис «REPLACE INTO» MySQL, но это удаляет и заменяет строку, которая играет веселый хаос, если вы хотите иметь столбец даты создания. То, что я сделал, чтобы решить эту проблему было провести на идентификатор сеанса, который был передан в read, а затем обновить идентификатор сеанса в базе данных во время записи с помощью идентификатора передается read как ключ:

<?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) новый сеанс не создается до завершения сценария. Я подтвердил, что сделав то же самое, что и вы: ВЫБОР нового идентификатора сеанса из базы данных. А нового сеанса там нет. Однако, после завершения скрипта, это так.

Это, как я установил его:

$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 писать сессию. Надеюсь, это поможет.

Смежные вопросы