会话处理类奇怪的行为

时间:2016-02-02 04:42:06

标签: php mysql ajax session

我正在使用以下类来处理会话:

class DBHandler implements SessionHandlerInterface {

public function open($save_path, $name) {
    try {
        DBCxn::get();
        return true;
    } catch(PDOException $e) {
        return false;   
    }
}

public function close() {
    return true;    
}

public function destroy($session_id) {
    $sth = DBCxn::get()->prepare("DELETE FROM sessions WHERE session_id = ?");
    $sth->execute(array($session_id));
    return true;
}

public function gc($maxlifetime) {
    $sth = DBCxn::get()->prepare("DELETE FROM sessions WHERE session_id = ?");
    $sth->execute(array(time() . $maxlifetime));    
    return true;    
}

public function read($session_id) {
    $sth = DBCxn::get()->prepare("SELECT session_data FROM sessions WHERE session_id = ?");
    $sth->execute(array($session_id));
    $rows = $sth->fetchALL(PDO::FETCH_NUM);
    if (count($rows) == 0) {
        return '';  
    }
    else {
        return $rows[0][0]; 
    }   
}

public function write($session_id, $session_data) {
    $sth = DBCxn::get()->prepare("UPDATE sessions SET session_data = ?, last_update = NOW() WHERE session_id = ?");
    $sth->execute(array($session_data, $session_id));
    if ($sth->rowCount() == 0) {
        $sth = DBCxn::get()->prepare("INSERT INTO sessions (session_id, session_data, last_update) VALUES (?, ?, NOW())");
        $sth->execute(array($session_id, $session_data));           
    }


  }
}

session_set_save_handler(new DBHandler);

然后我开始会话,然后使用开关(通过 get变量或ajax 访问)来包含索引中主div的内容。 PHP。

如果通过ajax访问,交换机具有以下验证:

if(!isset($_SESSION)) 
{ 
    session_start();
} 

if(isset($_SESSION['l'])) {

在index.php结束时,会话以 session_write_close();

结束

数据库表具有唯一会话ID的约束。

出于某种原因,只有一些时间我收到以下错误:

  

致命错误:带有消息的未捕获异常'PDOException'   'SQLSTATE [23000]:完整性约束违规:1062重复条目   '312505097fb815255103447952d0af61'用于file_path中的键'PRIMARY'':99   堆栈跟踪:#0 file_path(99):PDOStatement-> execute(Array)#1   [内部功能]:DBHandler->写('312505097fb8152 ...',   'login | i:1;')#2 file_path(185):session_write_close()#3 {main}   抛出file_path:99

     

file_path:99是前面提到的类中的下一行   “$ sth-> execute(array($ session_id,$ session_data));”

     

file_path:185是index.php末尾的session_write_close()

可能导致此错误的原因是什么?

1 个答案:

答案 0 :(得分:1)

写入功能正在生成重复错误。如果会话数据与DB中的存储会话数据相同,则它将始终为$ sth-> rowCount()返回值0。因此,它尝试使用相同的session_id插入会话数据并生成重复错误。