2013-08-31 67 views
0

我在我的PHP代碼中使用session_destroy()時出現錯誤。錯誤 - session_destroy() - 試圖銷燬未初始化的會話

以下腳本位於每個頁面上,如果用戶已登錄,它將檢查會話是否有效,如果不是,則會話會被終止。

session_start(); 

// check for users already signed in and check session 
if (isset($_SESSION['user_id'])) { 
    $uid = $_SESSION['user_id']; 

    // check user_id is a valid id 
    if (!is_numeric($uid) || $uid < 0) { 
     session_unset(); 
     session_destroy(); 
     session_regenerate_id(true); 
    } 

    // if user agent is different, kill session 
    if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']) { 
     session_unset(); 
     session_destroy(); 
     session_regenerate_id(true); 
    } 

    // if user's last login record fails to match session_id, kill session 
    $SQL = "SELECT user_session FROM users_logins "; 
    $SQL .= "WHERE user_id = :user_id "; 
    $SQL .= "ORDER BY time_in DESC LIMIT 1;"; 
    $STH = $DBH_P->prepare($SQL); 
    $STH->bindParam(':user_id', $uid); 
    $STH->execute(); 
    $row = $STH->fetch(); 
    if ($STH->rowCount() > 0) { 
     $db_sid = $row['user_session']; 
    } 
    if ($db_sid !== session_id()) { 
     session_unset(); 
     session_destroy(); 
     session_regenerate_id(true); 
    } 
} 

我收到的錯誤表示失敗來自最後的session_destroy()調用。

我是否正確使用session_destroy()?我已經閱讀了其中的其他問題,但大多數答案都建議在銷燬它之前必須使用session_start(),但在檢查開始之前,我已經開始了頂部的會話。

+0

_Why_你在使用session_unset和session_destroy嗎?重新生成id應該足夠了。爲什麼你在會話中檢查用戶ID是數字?如果這應該是必要的 - 在將它放入會話之前進行。 – CBroe

+0

@CBroe我使用session_unset和session_destroy記錄用戶,如果發現任何問題,所以當他們去訪問另一個頁面時,他們必須再次登錄。由於會話劫持,我檢查user_id是數字。僅僅因爲我在首先將它放入會話中之前對其進行了檢查,並不表示它會在此頁面上有效,如果有人使用了它。 – TheCarver

+0

我現在在SO上追蹤那個'session_unset'神話,因爲從昨天開始。不管你告訴用戶什麼,不知何故傳聞在你看來,你認爲更適合投入腳本的功能越多越好。事實恰恰相反。 – hakre

回答

1

你做一些瘋狂的東西有(但你需要談判,與你自己的,我不包括它在我的回答),爲什麼你看到錯誤消息的原因很簡單:

session_regenerate_id(true); 

命令PHP破壞舊會話。問題是,你已經這樣做了,早一行:

session_destroy(); 
session_regenerate_id(true); 

所以只是從上面看一看。強迫症的方式沒有理由在你的會話處理中拋出儘可能多的功能(但實際上不理解/不清楚)。取而代之的是,如果你想在其中放置一些安全網,那麼需要一個用於完成這項工作的功能,並實際處理它的返回值。這會更有幫助。

+0

感謝您的解釋,很好。我想我在檢查我的會議時有點不高興。不久前,我來自Classic ASP,管理會話更簡單一些(因爲它是垃圾)。也許我只是使用'session_regenerate_id(true);'如果任何條件爲真,將用戶重定向到註銷頁面,在那裏所有會話數據都被清除,然後將它們彈回到它們所在的頁面。 – TheCarver

+1

是的,這就是我想說的,該函數單獨做它(以'true'作爲參數)。 – hakre

0

在開始另一個會話之前,您必須銷燬先前的會話。因此,除了「登錄」創建會話之外,還應該有一個「註銷」方法來銷燬會話。確保你的應用程序兼有。