這篇文章主要介紹了php中實現精確設定session到期時間的方法,需要的朋友可以參考下
大多資料情況下我們對於session到期時間使用的是預設設定的時間,而對於一些有特殊要求的情況下我們可以設定一下session到期時間。
對此,可以在PHP中,設定php.ini,找到session.gc_maxlifetime = 1440 #(PHP5預設24分鐘)
這裡你可以隨便設定一下到期時間.但是有人說設定以後,好象不起作用!
其實不是不起作用,而是因為系統預設:
session.gc_probability = 1session.gc_pisor = 1000
garbage collection 有個機率的,1/1000就是session 1000次才有一次被回收。
只要你的訪問量大了,那就能達到回收的效果.
或者你也可以設定一下session.gc_pisor 的值,
比如:session.gc_pisor = 1,這樣就能明顯的看到SESSION到期的效果了.
我們最常用的是在php程式中設定,如下常式序所示:
<?phpif(!isset($_SESSION['last_access'])||(time()-$_SESSION['last_access'])>60)$_SESSION['last_access'] = time();?>
這樣就搞定了,如果要設定已到期的話也可以在程式中實現:
<?phpunset($_SESSION['last_access']);// 或 $_SESSION['last_access']='';?>
session有到期的機制:
session.gc_maxlifetime 原來session 到期是一個小機率的事件,分別使用session.gc_probability和session.gc_pisor 來確定運行session 中gc 的機率 session.gc_probability和session.gc_pisor的預設值分別為 1和100。分別為分子和分母 所以session中gc的機率運行機會為1% 。如果修改這兩個值,則會降低php的效率。所以這種方法是不對的!!
因此,修改php.ini檔案中的gc_maxlifetime變數就可以延長session的到期時間了:(例如,我們把到期時間修改為86400秒)
session.gc_maxlifetime = 86400
然後,重啟你的web服務(一般是apache)就可以了。
session“回收”何時發生:
預設情況下,每一次php請求,就會有1/100的機率發生回收,所以可能簡單的理解為“每100次php請求就有一次回收發生”。這個機率是通過以下參數控制的
#機率是gc_probability/gc_pisor
session.gc_probability = 1session.gc_pisor = 100
注意1:假設這種情況gc_maxlifetime=120,如果某個session檔案最後修改時間是120秒之前,那麼在下一次回收(1/100的機率)發生前,這個session仍然是有效。
注意2:如果你的session使用session.save_path中使用別的地方儲存session,session回收機制有可能不會自動處理到期session檔案。這時需要定時手動(或者crontab)的刪除到期的session:
cd /path/to/sessions; find -cmin +24 | xargs rm
PHP中的session永不到期
不修改程式是最好的方法了,因為如果修改程式,測試部一定非常鬱悶,那麼只能修改系統內容配置,其實很 簡單,開啟php.ini設定檔案,修改三行如下:
1、session.use_cookies
把這個的值設定為1,利用cookie來傳遞sessionid
2、session.cookie_lifetime
這個代表SessionID在用戶端Cookie儲存的時間,預設是0,代表瀏覽器一關閉SessionID就作廢……就是因為這個所以PHP的 session不能永久使用! 那麼我們把它設定為一個我們認為很大的數字吧,999999999怎麼樣,可以的!就這樣。
3、session.gc_maxlifetime
這個是Session資料在伺服器端儲存的時間,如果超過這個時間,那麼Session資料就自動刪除! 那麼我們也把它設定為99999999。
就這樣一切ok了,當然你不相信的話就測試一下看看——設定一個session值過個10天半個月的回來看看,如果你的電腦沒有斷電或者宕機,你仍然可以看見這個sessionid。
當然也可能你沒有控制伺服器的許可權並不能像我一樣幸運的可以修改php.ini設定,一切依靠我們自己也是有辦法的,當然就必須利用到用戶端儲存 cookie了,把得到的sessionID儲存到用戶端的cookie裡面,設定這個cookie的值,然後把這個值傳遞給session_id()這 個函數,具體做法如下:
<?phpsession_start(); // 啟動Session $_SESSION['count']; // 註冊Session變數Count isset($PHPSESSID)?session_id($PHPSESSID):$PHPSESSID = session_id(); // 如果設定了$PHPSESSID,就將SessionID賦值為$PHPSESSID,否則產生SessionID $_SESSION['count']++; // 變數count加1 setcookie('PHPSESSID', $PHPSESSID, time()+3156000); // 儲存SessionID到Cookie中 echo $count; // 顯示Session變數count的值 ?>
session失效不傳遞
我們先寫個php檔案:<?=phpinfo()?>, 傳到伺服器去看看伺服器的參數配置。
轉到session部分,看到session.use_trans_sid參數被設為了零。
這個參數指定了是否啟用透明SID支援,即session是否隨著URL傳遞。我個人的理解是,一旦這個參數被設為0,那麼每個URL都會啟一個session。這樣後面頁面就無法追蹤得到前面一個頁面的session,也就是我們所說的無法傳遞。兩個頁面在伺服器端產生了兩個session檔案,且無關聯。(此處精確原理有待確認)
所以一個辦法是在設定檔php.ini裡把session.use_trans_sid的值改成1。
當然我們知道,不是誰都有許可權去改php的配置的,那麼還有什麼間接的解決辦法呢?
下面就用兩個執行個體來說明:
檔案1 test1.php
<?php//表明是使用使用者ID為標識的sessionsession_id(SID);//啟動sessionsession_start();//將session的name賦值為Havi$_SESSION['name']="Havi";//輸出session,並設定超連結到第二頁test2.phpecho "<a href="test2.php" rel="external nofollow" >".$_SESSION['name']."</a>";?>
檔案2: test2.php
<?php表明是使用使用者ID為標識的sessionsession_id(SID);//啟動sessionsession_start();//輸出test1.php中傳遞的session。echo "This is ".$_SESSION['name'];?>
所以,重點是在session_start();前加上session_id(SID);,這樣頁面轉換時,伺服器使用的是使用者儲存在伺服器session檔案夾裡的session,解決了傳遞的問題。
不過有朋友會反映說,這樣一來,多個使用者的session寫在一個SID裡了,那Session的價值就發揮不出來了。所以還有一招來解決此問題,不用加session_id(SID);前提是你對伺服器的php.ini有配置的許可權:
output_buffering改成ON,道理就不表了。
第二個可能的原因是對伺服器儲存session的檔案夾沒有讀取的許可權,還是回到phpinfo.php中,查看session儲存的地址:
session.save_path: var/tmp
所以就是檢查下var/tmp檔案夾是否可寫。
寫一個檔案:test3.php來測試一下:
<?phpecho var_dump(is_writeable(ini_get("session.save_path")));?>
如果返回bool(false),證明檔案夾寫入權限被限制了,那就換個檔案夾咯,在你編寫的網頁裡加入:
//設定目前的目錄下session子檔案夾為session儲存路徑。$sessSavePath = dirname(__FILE__).'/session/';//如果新路徑可讀可寫(可通過FTP上變更檔案夾屬性為777實現),則讓該路徑生效。if(is_writeable($sessSavePath) && is_readable($sessSavePath)){session_save_path($sessSavePath);}