2016-02-02 91 views
1

我使用下面的類來處理會話:會話處理類奇怪的行爲

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

然後我開始會話,然後用開關(被訪問或者通過得到變量或ajax)在index.php中包含main div的內容。

開關具有下面的驗證的情況下,它經由AJAX訪問:

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

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

在的的index.php的會話與session_write_close()封閉端;

數據庫表對唯一會話ID有約束。

出於某種原因,只是有些時候,我發現了以下錯誤:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '312505097fb815255103447952d0af61' for key 'PRIMARY'' in file_path:99 Stack trace: #0 file_path(99): PDOStatement->execute(Array) #1 [internal function]: DBHandler->write('312505097fb8152...', 'login|i:1;') #2 file_path(185): session_write_close() #3 {main} thrown in file_path:99

file_path:99 is the folowing line in the previously mentioned class "$sth->execute(array($session_id, $session_data));"

file_path:185 is session_write_close() at the end of index.php

什麼導致這個錯誤?

+0

那麼,錯誤意味着你已經有一個session_id設置爲顯示的數字。它發生錯誤的地方可能是插入命令。但是這對你來說應該相當容易調試 - 只需要放入一些ECHO語句,這樣你就可以看到發生了什麼,也可以使用錯誤的try-catch,這樣你就可以回溯到問題出現的位置。現在看起來你並沒有看到任何錯誤。所以這是弄清楚代碼有什麼問題的第一步。 –

回答

1

寫入函數正在生成重複錯誤。如果會話數據與DB中的存儲會話數據相同,那麼對於$ sth-> rowCount(),它將始終返回值0。由於它嘗試使用相同的session_id插入會話數據並生成重複錯誤。