2012-05-25 43 views
3

我陷入了$_SESSION問題,而$_SESSION是隨機丟失數據。PHP會話數據丟失 - >會話文件被刪除太快

我有一個不同頁面的表單,用戶有特定的時間來瀏覽所有頁面。

因此,我在第一頁上設置了一個會話變量,並在其他頁面上檢查它。

start.php

<?php 
    session_start(); 

    //Set Variable for Starting application 
    if (!isset($_SESSION['STARTED'])){ 
     $_SESSION['STARTED'] = time(); 
    } 

app_init.php

<?php 
session_start(); 

if ((!isset($_SESSION['STARTED'])) || (time() - $_SESSION['STARTED'] > MAX_TIMELIMIT)) { 
    echo '<!-- st: '.$_SESSION['STARTED'].'-->'; 
    // Started Variable is not set or timelimit is over. 
    session_destroy(); // destroy session data in storage 
    session_unset();  // unset $_SESSION variable for the runtime 
    showTimeout('0'); // show timeout 
} 

事後頁開始:

<?php 

// get basic settings for applications 
require_once (MODEL_PATH.'/app_init.php'); 

整個系統在本地安裝,開發服務器和測試服務器上工作得很好。在生產服務器上,我在不同的時間得到一個超時。它從30秒到10分鐘不等。 MAX_TIMELIMIT是20分鐘。在這種情況下,$_SESSION['STARTED']總是空的。在其他環境中,即使在20分鐘後出現超時,它也可以正確設置。

產生額外的信息:

  • 如果我試圖達到一個新的頁面,或者如果我只需重新加載實際的頁面,我總是超時沒關係。
  • 我已經在任何環境檢查php.ini - >session.save_path設置正確,session.cookie_lifetime是0和session.gc_maxlifetime是1440
  • 磁盤空間是好的(>免費22 GB)
  • 每個文件是在同一臺服務器上,並且具有相同url(除了最後一部分指定了窗體的步驟),看起來像這樣:
    host/some/path/calc - > host/some/path/form - > host/some/path/summary - > host/some /路徑/發送
  • 會話設置在計算頁面上,並且每個頁面上都可能發生超時(計算,表格,彙總)
  • 我從生產服務器獲得了php.ini,並將其帶入我的本地工作區。更改一些路徑(extensions-path,session.save_path,tmp-path)後,它在我的本地安裝上運行得非常好。
  • 協議是所有頁面相同
  • 要重新創建會話(通過$tmpsession_destroy()session_create())並沒有幫助
  • 單前端,沒有負載均衡器(只是一個阿帕奇)
  • 會話文件不小心刪除

加入一些輸出和重新測試後,我得到如下:

  • 我加載頁(第一步驟)
  • 我經過的形式的任何步驟(計算值/形式/摘要)
  • 當頁面被加載$_SESSION

    array ( 'STARTED' => 1338298801, 'S_SID_' => '41554681145546', 'S_LC_' => 'de', 'version_testing' => 1, )

  • 我重裝該頁面每三十秒

  • 至少3分鐘(也可能是30秒)我得到超時和$_SESSION是後:

    array ( )

  • ,如果我嘗試這第一頁上,我得到了$_SESSION一個新值,作爲sessiondata是空的,全自動的新集。

  • 要記住:在測試/開發環境中,sessiondata仍然存在,即使超時發生在20分鐘後。

  • 更改session.save_path第一次似乎工作(會話持續至少24分鐘)。但一小時後,仍然是同樣的問題。沒有會話持續4分鐘以上。

發現問題(但沒有解決方案還)
今天我訪問生產服務器,我發現,與會話數據的文件夾中3-5分鐘後清理。沒有文件的時間戳超過3分鐘。 如前所述,PHP設置正確(GC生命週期),我沒有找到任何Windows作業,或類似的東西刪除這些文件。由於PHP.ini設置正確,我將嘗試通過數據庫處理會話。

感謝您的幫助

+1

確保生產服務器着手舉行會議的所有設置。您正在使用託管服務器還是專用服務器? – badc0re

+0

你如何存儲你的會話?數據庫,文件或memcache? – Ray

+0

嗨, 這是一個專用的服務器。我們將會話存儲在文件中,並且設置都已設置。 (據我所見) – Kelzama

回答

2

什麼在這種特定情況下的工作:

另一個網站是在同一臺服務器上,但在不同的虛擬主機hostet。這個網站使用了每個請求都會調用的「init.php」。它包含一行將gc_maxlifetime設置爲0,然後開始會話。所以隨機地在某個請求中,所有sessiondata被第二個網站清除。

在測試和開發,這不是一個問題,因爲這兩種環境都不算多用...

0

乍一看(沒有更多的信息),它似乎是可能的時間應已實際開始之前,你的會話啓動。這無疑會導致這個問題。如果這可能是問題,那就試試這個。

$tmp = $_SESSION; 
session_destroy(); 
session_start(); 
$_SESSION = $tmp; 
$_SESSION['started'] = time(); 

另外,如果您正在訪問某個子域名或類似位置,則您的會話將不存在。它只存在於設置時的確切域。

提供更多信息可能也有幫助。存在問題的網頁的網址。在頁面上添加幾個var_dump($_SESSION),並在您逐步瀏覽時查看它輸出的內容。當你發現一個變化時,找出它改變的地方和原因。

+0

嗨, 我在評論中添加了一些轉儲。 我編輯主要信息的進一步信息 – Kelzama

1

這是我多次看到PHP網站託管在多前端與負載平衡器多次的常見行爲。由於默認情況下PHP會在文件系統上存儲會話,因此您根據哪個前端啓動了一個或另一個會話。

簡單的解決方案是將會話存儲到數據庫,即使我對負載平衡器有錯,您應該嘗試直接在文件系統上讀取會話數據,檢查確切發生了什麼事情(PHP是否刪除數據?數據是否仍然存在,但會生成另一個會話令牌?等等)。