2016年4月20日 星期三

PHP教學 - 定時一段時間登出系統做法

自動登出方式

一、html做法

<META HTTP-EQUIV="REFRESH" CONTENT="600;URL=logout.php">

二、javascript做法

<script>
var oTimerId;
function Timeout(){
alert("\n您好\n您可能已離開!\n很抱歉!!請重新登入系統\n謝謝!!");
location.href= ('logout.php');
}
function ReCalculate(){
clearTimeout(oTimerId);
oTimerId = setTimeout('Timeout()', 1 * 60 * 1000); //js 是用毫秒計算
}
document.onmousedown = ReCalculate;
document.onmousemove = ReCalculate;
ReCalculate();
</script>

三、php做法

正常的php.ini,session 的預設存活時間為 24 分鐘(1440秒)

session.gc_maxlifetime = 1440

但如果時間到了,session 卻還存在,沒有被刪除是怎麼回事呢 ?

原來垃圾收集者(GC),並不是一定時間到就會工作,而是是透過機率來工作。

在 php.ini – GC的預設值如下:

session.gc_probability = 1
session.gc_divisor = 100

這代表著,有100分之一的機率會清除session

我們只要將其更改為下方,,並重啟 httpd 服務:

session.gc_maxlifetime = 216000
session.gc_probability = 1
session.gc_divisor = 1
就代表 存活24hrs並100%清除session

如果要設定SESSION的連線時間(例如設定24小時),並讓SESSION在設定時間過期後自動被刪除,需在php.ini中設定下列參數:
session.cookie_lifetime = 0
註:單位=秒,cookie存活時間,0秒代表瀏覽器一關掉就清除。
如果不要讓瀏覽器一關掉就清除cookie,可以設置一很大的數字如:999999999(秒),這樣就省得清除客戶端的cookie了!

session.gc_probability = 100
註:gc的分子。

session.gc_divisor = 100
註:gc的分母

session.gc_maxlifetime = 86400
註:單位=秒,session存活時間,86400秒代表可以存活24小時。

另一篇部落格則有更詳細的介紹
PHP在tmp目錄下(PHP.ini默認設置)創建一個“SESS”+隨機碼的無後綴名文件,來保存$_SESSION[]定義的數據。然後給這個文件匹配一個新的cookie,cookie name是“PHPSESSID”(PHP.ini默認設置),cookie value是對應這個文件的session.id,這個cookie每當關閉瀏覽器後就會過期(PHP.ini默認設置),和其匹配的$_SESSION[]也就跟着一起失效。你甚至可以把PHP的SESSION理解爲一個存在特殊目錄下的特殊COOKIE。區別是它的文件取名交複雜,正常人是猜不到的,而且保存在服務器上,所以比cookie更安全。

下面介紹PHP SESSION相關的函數和PHP.ini設定:

如果要讓PHP的session活的更長久,就要和它匹配的cookie更長久。

$lifetime = 3600; //單位秒,3600秒=1小時
session_set_cookie_params($lifetime);
session_start(); //注意一定要在session_start()之前
或者在php.ini中找到如下,默認是0,即關閉瀏覽器就失效 session.cookie_lifetime = 3600
效果是完全一樣的。這樣就算關閉瀏覽器,1小時內再次打開,session一樣存在(就是cookie嘛)。

你可以更改session的保存目錄,函數如下:

$sessionpath = './mysession/';
session_save_path($sessionpath);
session_start();
或者更改php.ini如下

session.save_path = "/mysession"
你可以通過函數得到當前的session.id 或者 自己定義session.id

session_id("vip123");
session_name("bluesdog");
session_start();
echo session.name()."=".session.id();
所以下面這句話和上面的session_set_cookie_params一樣定義了session的存活時間

setcookie(session_name(),session_id(),time()+3600,"/");
下面列舉一些搞人的session設定

PHP.ini中如下行

session.cache_limiter = nocache;
session.cache_expire = 180
乍一看像是session的存活週期設定,expire等於180分鐘嘛,其實這個和$_SESSION[]變量毫不搭界,它是頁面緩存的。

什麼是緩存?

它是屬於瀏覽器的特性,它決定你瀏覽網頁的緩存方式,沒有緩存的情況會使你按瀏覽的“後退”鍵時提示要你更新連接,之前的內容就沒有了,比如你填入的表單信息,都被丟失。
session_cache_limiter內的幾個參數意義是:
nocache:當然是不緩存(比如:表單信息被清除),但公共變量可以緩存
private:私有方式緩存(比如:表單信息被保留,但在生存期內有效)
private_no_cache:私有方式但不過期(表單信息被保留)
publice:公有方式,(表單信息也被保留)

也可以通過php函數設定

session_cache_limiter('private');
session_cache_expire(1);
session_start(); //注意任何session的設定必須在session_start()之前
PHP.ini中又發現如下行

session.gc_probability = 1
session.gc_divisor     = 100
session.gc_maxlifetime = 1440
乍一看這裏怎麼又有一個lifetime??其實這裏的lifetime和$_SESSION[]變量也毫不搭界,它是回收垃圾用的。

什麼是回收垃圾?

垃圾回收(Garbage Collection)時間,每個用戶登錄都會生成session文件,如果用戶中途關閉IE,那麼服務器就會生成一個垃圾文件。gc_maxlifetime就是用來定時刪除一些過期的垃圾文件的。

上面3句話的意思就是當 100 次鏈接中會有 1 次在 1440 秒後做清除垃圾文件的工作。如果你把gc_divisor設爲 1 ,那麼每次連接都會清除垃圾,但聽說服務器壓力會挺大,不建議。另外經過別人測試,在統一了 session.cookie_lifetime 和 session.gc_maxlifetime 後, session的定期清除效果纔會比較好。

session_destroy(); //這個不用說了,地球人都知道
那我一定要PHP的session和ASP的session一樣擁有兩個特性呢(關閉IE失效 && 時間到失效)?

將 Timestamp 放入 $_SESSION 中,每次 request 的時候對其值和現在值 now() 進行比較。如果時間間隔沒有超出 Time Out 的期限,那麼就將現在的時間 now() 賦值給 $_SESSION 中的紀錄 timestamp 的部分。
將 timestamp 放入數據庫中,每次 request 的時候對其值和現在值 now() 進行比較。如果時間間隔沒有超出 Time Out 的期限,那麼就將該用戶的 session 紀錄進行更新。
OK 這樣就行了。

沒有留言:

張貼留言