今天下班坐班車,快到站的時候,上家公司的leader發了個qq給我,意思是救火,下車後回來在電腦上詳細問了下,leader的描述如下
<b>[cpp]</b> view plain copy
這個位址 你幫我看下 為啥上傳完試卷釋出任務 設定答題卡的時候 session就沒了
因為這個項目一開始背景都是我一人開發的,是以很快就找到了問題所在。流程為:使用者通過js元件上傳試卷,在上傳試卷的方法中通過session存儲剛剛上傳的試卷詳細資訊,如名稱、字尾、存入資源表的ID等,上傳成功後,再點選頁面上的其他選項,如學校、年級、難易度等,最後點選送出,在送出處理的方法裡,一開始便判斷剛剛上傳的session值是否存在,不存在便跳到試卷首頁。我在此方法中列印了$_SESSION,沒有值,奇怪了,以前還是好好的。于是我問了下,啥時候開始的,leader說下午快下班時,老師打電話說上傳試卷設定答題卡不成功,老跳轉。接着又問了下,動伺服器環境了麼,leader說沒有。
既然出現了問題,那就解決問題呗。正好這段時間在看《PHP核心技術與最佳實踐》一書,裡面就對session和cookie有詳細的描述,同時也加深了我對二者的了解。于是我先打開php的配置檔案,找到session相關的配置項,發現session.save_path為/data2/session,我記得以前都是設定為/data1/session的,怎麼變了。于是我退出來去看看此路徑,一開始我以為是該目錄權限不夠,後來一看,壓根就沒有該目錄,難怪每個session不會跨頁面。于是建立檔案,設定權限,再上傳,一切又恢複正常了。
寫到這,我也想再唠叨下session相關的技術點。session是存儲在伺服器端的,預設是以檔案方式存儲的(session.save_handler = files)。那session是如何産生的呢?session是通過session_start()函數産生的 ,當此函數運作時,在session存儲的目錄裡生成一個檔案和唯一一個與之對應的session id,通過session id可以取出該session檔案的資料。由于每次運作session_start()都會産生新的seession檔案,那麼如何利用到以前生成session檔案呢,隻需session_start($session_id),那麼便不會新産生session檔案了,而會去讀session id對應的session檔案。session id在預設情況下都是使用在用戶端(浏覽器)的cookie來儲存session id(在chrome浏覽器上按F12鍵,點選Resources-cookies,可以看到),使用$_COOKIE['PHPSESSID']可以擷取。那個PHPSESSID是session id的預設名稱,在php.ini裡可以通過session.name來設定,在腳本中用session_name()來擷取session id的名稱。每次浏覽器和伺服器對話時,浏覽器都會把session id傳給伺服器的,伺服器會依據傳遞過來的session id找到相應的session檔案擷取相應資訊進行相關操作。而一旦用戶端(浏覽器)禁用了cookie,那麼伺服器端變不會接收到session id,此時需要顯示傳遞session id了。兩種方法:手動通過URL傳遞session id;隐藏表單傳遞session id。上述兩種方法需要服務端的php環境中session.use_trans_sid 值為 1。
啰嗦了那麼多,最後還是linus那句話,“talk is cheap,show me the code”。
<?php
session_start();
$_SESSION['arr'] = array('name' => 'molaifeng', 'hobby' => 'php');
?>
<a href="testSession.php?<?php echo session_name(); ?>=<?php echo session_id()?>">testSession</a>
session_start($_REQUEST[session_name()]);
print_r($_SESSION);
代碼都看懂的吧,就不解釋了。
最後總結下吧,一般情況下出現跨頁面session失效,基本上是上述列出的幾點。1、session.save_path有誤,如權限不夠,或是目錄不存在;2、伺服器php配置中的session.use_trans_sid值為0;3、用戶端禁用了cookie。不過我覺得第一種情況出現的頻率應該挺高的。