亚洲韩日午夜视频,欧美日韩在线精品一区二区三区,韩国超清无码一区二区三区,亚洲国产成人影院播放,久草新在线,在线看片AV色

您好,歡迎來(lái)到思海網(wǎng)絡(luò),我們將竭誠(chéng)為您提供優(yōu)質(zhì)的服務(wù)! 誠(chéng)征網(wǎng)絡(luò)推廣 | 網(wǎng)站備案 | 幫助中心 | 軟件下載 | 購(gòu)買流程 | 付款方式 | 聯(lián)系我們 [ 會(huì)員登錄/注冊(cè) ]
促銷推廣
客服中心
業(yè)務(wù)咨詢
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352289
點(diǎn)擊這里給我發(fā)消息  81721488
有事點(diǎn)擊這里…  376585780
有事點(diǎn)擊這里…  872642803
有事點(diǎn)擊這里…  459248018
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  380791050
技術(shù)支持
有事點(diǎn)擊這里…  714236853
有事點(diǎn)擊這里…  719304487
有事點(diǎn)擊這里…  1208894568
有事點(diǎn)擊這里…  61352289
在線客服
有事點(diǎn)擊這里…  531199185
有事點(diǎn)擊這里…  61352288
有事點(diǎn)擊這里…  983054746
有事點(diǎn)擊這里…  893984210
當(dāng)前位置:首頁(yè) >> 技術(shù)文章 >> 文章瀏覽
技術(shù)文章

php設(shè)置session的生存周期

添加時(shí)間:2014-7-3 3:17:21  添加: 思海網(wǎng)絡(luò) 

當(dāng)程序需要為某個(gè)客戶端的請(qǐng)求創(chuàng)建一個(gè) session 的時(shí)候,服務(wù)器首先會(huì)檢查這個(gè)客戶端是否已經(jīng)包含了一個(gè) session 標(biāo)識(shí),這個(gè)我們稱為 session id(獲取方法為 session_id() ),如果已包含一個(gè) session id 則說(shuō)明此客戶端之前已經(jīng)創(chuàng)建過(guò) session,服務(wù)器則按照 session id 把這個(gè) session 中的值檢索出來(lái),如果客戶端不包含 session id,說(shuō)明此客戶端第一次請(qǐng)求服務(wù)器或手動(dòng)清除過(guò)緩存文件,則為此客戶端創(chuàng)建一個(gè) session 并且生成一個(gè)與此 session 相關(guān)聯(lián)的 session id,一般來(lái)說(shuō),session id 的值是不會(huì)重復(fù)的,并且加密的字符串,這個(gè) session id 將被在本次響應(yīng)中返回給客戶端保存。

session 在何時(shí)被創(chuàng)建 ?

通常(是指通常)是在瀏覽器向服務(wù)器端第一次請(qǐng)求時(shí)被創(chuàng)建,并且它會(huì)占用一定的內(nèi)存空間,因此在不必要的情況下,盡最關(guān)閉 session 。

session 何時(shí)被刪除 ?

通常情況下,session 在會(huì)在這幾種情況下被刪除:

一是使用 session_destroy() 重置函數(shù)手動(dòng)刪除;

二是 session 的上次活動(dòng)時(shí)間距離當(dāng)前時(shí)間的間隔超過(guò)了 session 的超時(shí)設(shè)置的時(shí)間;三是服務(wù)器進(jìn)程被停止。

怎么在瀏覽器關(guān)閉時(shí)刪除 session ?

理論上來(lái)說(shuō),是做不到這一點(diǎn),http是一種無(wú)狀態(tài)協(xié)議,因此服務(wù)器不知道客戶端什么時(shí)候關(guān)掉的瀏覽器,并且PHP也沒(méi)有一個(gè)關(guān)相的函數(shù)來(lái)獲取此項(xiàng)信息,但這個(gè)問(wèn)題還可以得到解決,就是使用 網(wǎng)頁(yè)特效 代碼 window.oncolose 來(lái)監(jiān)視瀏覽器的關(guān)閉動(dòng)作,然后用Ajax向服務(wù)器端發(fā)送一個(gè)請(qǐng)求來(lái)刪除 session ,但這個(gè)辦法也并不會(huì)完全解決問(wèn)題,原因是在有些情況下比如瀏覽器崩潰、突然斷電、用戶死機(jī)等這些時(shí)候并不能作出反應(yīng)。

如何設(shè)置使session在一段時(shí)間過(guò)后自動(dòng)失效(刪除)?

session_start()是session機(jī)制的開始,它有一定概率開啟垃圾回收,因?yàn)閟ession是存放在文件中,PHP自身的垃圾回收是無(wú)效的,SESSION的回收(刪除)是要?jiǎng)h文件的,這個(gè)概率是根據(jù)php.ini的配置決定的,但是有的系統(tǒng)是 session.gc_probability = 0,這也就是說(shuō)概率是0,而是通過(guò)cron腳本來(lái)實(shí)現(xiàn)垃圾回收(即刪除session)。

PHP中的session有效期默認(rèn)是1440秒(24分鐘,注:php5里默認(rèn)的是180分】,也就是說(shuō),客戶端超過(guò)24分鐘沒(méi)有刷新,當(dāng)前session就會(huì)失效。很明顯,這是不能滿足需要的。

一個(gè)已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存儲(chǔ)到數(shù)據(jù)庫(kù),這樣可以通過(guò)SQL語(yǔ)句來(lái)刪除所有過(guò)期的session,精確地控制session的有效期。這也是基于PHP的大型網(wǎng)站常用的方法。但是,一般的小型網(wǎng)站,似乎沒(méi)有必要這么勞師動(dòng)眾。

但是一般的Session的生命期有限,如果用戶關(guān)閉了瀏覽器,就不能保存Session的變量了!那么怎么樣可以實(shí)現(xiàn)Session的永久生命期呢?

大家知道,Session儲(chǔ)存在服務(wù)器端,根據(jù)客戶端提供的SessionID來(lái)得到這個(gè)用戶的文件,然后讀取文件,取得變量的值,SessionID可以使用客戶端的Cookie或者Http1.1協(xié)議的Query_String(就是訪問(wèn)的URL的“?”后面的部分)來(lái)傳送給服務(wù)器,然后服務(wù)器讀取Session的目錄。

要實(shí)現(xiàn)Session的永久生命期,首先需要了解一下php.ini關(guān)于Session的相關(guān)設(shè)置(打開php.ini文件,在“[Session]”部分):

1、session.use_cookies:默認(rèn)的值是“1”,代表SessionID使用Cookie來(lái)傳遞,反之就是使用Query_String來(lái)傳遞;

2、session.name:這個(gè)就是SessionID儲(chǔ)存的變量名稱,可能是Cookie,也可能是Query_String來(lái)傳遞,默認(rèn)值是“PHPSESSID”;

3、session.cookie_lifetime:這個(gè)代表SessionID在客戶端Cookie儲(chǔ)存的時(shí)間,默認(rèn)是0,代表瀏覽器一關(guān)閉SessionID就作廢……就是因?yàn)檫@個(gè)所以Session不能永久使用!

4、session.gc_maxlifetime:這個(gè)是Session數(shù)據(jù)在服務(wù)器端儲(chǔ)存的時(shí)間,如果超過(guò)這個(gè)時(shí)間,那么Session數(shù)據(jù)就自動(dòng)刪除!

還有很多的設(shè)置,不過(guò)和本文相關(guān)的就是這些了,下面說(shuō)下如何使用永久Session的原理和步驟。

前面說(shuō)過(guò),服務(wù)器通過(guò)SessionID來(lái)讀取Session的數(shù)據(jù),但是一般瀏覽器傳送的SessionID在瀏覽器關(guān)閉后就沒(méi)有了,那么我們只需要人為的設(shè)置SessionID并且保存下來(lái),不就可以了。如果你擁有服務(wù)器的操作權(quán)限,那么設(shè)置這個(gè)非常非常的簡(jiǎn)單,只是需要進(jìn)行如下的步驟:

1、把“session.use_cookies”設(shè)置為1,打開Cookie儲(chǔ)存SessionID,不過(guò)默認(rèn)就是1,一般不用修改;

2、把“session.cookie_lifetime”改為正無(wú)窮(當(dāng)然沒(méi)有正無(wú)窮的參數(shù),不過(guò)999999999和正無(wú)窮也沒(méi)有什么區(qū)別);

3、把“session.gc_maxlifetime”設(shè)置為和“session.cookie_lifetime”一樣的時(shí)間;

在PHP的文檔中明確指出,設(shè)定session有效期的參數(shù)是session.gc_maxlifetime。可以在php.ini文件中,或者通過(guò)ini_set()函數(shù)來(lái)修改這一參數(shù)。問(wèn)題在于,經(jīng)過(guò)多次測(cè)試,修改這個(gè)參數(shù)基本不起作用,session有效期仍然保持24分鐘的默認(rèn)值。

由于PHP的工作機(jī)制,它并沒(méi)有一個(gè)daemon線程,來(lái)定時(shí)地掃描session信息并判斷其是否失效。當(dāng)一個(gè)有效請(qǐng)求發(fā)生時(shí),PHP會(huì)根據(jù)全局變量session.gc_probability/session.gc_divisor(同樣可以通過(guò)php.ini或者ini_set()函數(shù)來(lái)修改)的值,來(lái)決定是否啟動(dòng)一個(gè)GC(Garbage Collector)。

默認(rèn)情況下,session.gc_probability = 1,session.gc_divisor =100,也就是說(shuō)有1%的可能性會(huì)啟動(dòng)GC。GC的工作,就是掃描所有的session信息,用當(dāng)前時(shí)間減去session的最后修改時(shí)間(modified date),同session.gc_maxlifetime參數(shù)進(jìn)行比較,如果生存時(shí)間已經(jīng)超過(guò)gc_maxlifetime,就把該session刪除。

到此為止,工作一切正常。那為什么會(huì)發(fā)生gc_maxlifetime無(wú)效的情況呢?

在默認(rèn)情況下,session信息會(huì)以文本文件的形式,被保存在系統(tǒng)的臨時(shí)文件目錄中。在Linux下,這一路徑通常為\tmp,在Windows下通常為C:\Windows\Temp。當(dāng)服務(wù)器上有多個(gè)PHP應(yīng)用時(shí),它們會(huì)把自己的session文件都保存在同一個(gè)目錄中。同樣地,這些PHP應(yīng)用也會(huì)按一定機(jī)率啟動(dòng)GC,掃描所有的session文件。

問(wèn)題在于,GC在工作時(shí),并不會(huì)區(qū)分不同站點(diǎn)的session。舉例言之,站點(diǎn)A的gc_maxlifetime設(shè)置為2小時(shí),站點(diǎn)B的gc_maxlifetime設(shè)置為默認(rèn)的24分鐘。當(dāng)站點(diǎn)B的GC啟動(dòng)時(shí),它會(huì)掃描公用的臨時(shí)文件目錄,把所有超過(guò)24分鐘的session文件全部刪除掉,而不管它們來(lái)自于站點(diǎn)A或B。這樣,站點(diǎn)A的gc_maxlifetime設(shè)置就形同虛設(shè)了。

找到問(wèn)題所在,解決起來(lái)就很簡(jiǎn)單了。修改session.save_path參數(shù),或者使用session_save_path()函數(shù),把保存session的目錄指向一個(gè)專用的目錄,gc_maxlifetime參數(shù)工作正常了。

嚴(yán)格地來(lái)說(shuō),這算是PHP的一個(gè)bug?

還有一個(gè)問(wèn)題就是,gc_maxlifetime只能保證session生存的最短時(shí)間,并不能夠保存在超過(guò)這一時(shí)間之后session信息立即會(huì)得到刪除。因?yàn)镚C是按機(jī)率啟動(dòng)的,可能在某一個(gè)長(zhǎng)時(shí)間內(nèi)都沒(méi)有被啟動(dòng),那么大量的session在超過(guò)gc_maxlifetime以后仍然會(huì)有效。

解決這個(gè)問(wèn)題的一個(gè)方法是,把session.gc_probability/session.gc_divisor的機(jī)率提高,如果提到100%,就會(huì)徹底解決這個(gè)問(wèn)題,但顯然會(huì)對(duì)性能造成嚴(yán)重的影響。另一個(gè)方法是自己在代碼中判斷當(dāng)前session的生存時(shí)間,如果超出了 gc_maxlifetime,就清空當(dāng)前session。

但是如果你沒(méi)有服務(wù)器的操作權(quán)限,那就比較麻煩了,你需要通過(guò)PHP程序改寫SessionID來(lái)實(shí)現(xiàn)永久的Session數(shù)據(jù)保存。查查php.net的函數(shù)手冊(cè),可以見到有“session_id”這個(gè)函數(shù):如果沒(méi)有設(shè)置參數(shù),那么將返回當(dāng)前的SessionID,如果設(shè)置了參數(shù),就會(huì)將當(dāng)前的SessionID設(shè)置為給出的值。

只要利用永久性的Cookie加上“session_id”函數(shù),就可以實(shí)現(xiàn)永久Session數(shù)據(jù)保存了!

但是為了方便,我們需要知道服務(wù)器設(shè)置的“session.name”,但是一般用戶都沒(méi)有權(quán)限查看服務(wù)器的php.ini設(shè)置,不過(guò)PHP提供了一個(gè)非常好的函數(shù)“phpinfo”,利用這個(gè)可以查看幾乎所有的PHP信息!

<?php
phpinfo();

打開編輯器,輸入上面的代碼,然后在瀏覽器中運(yùn)行這個(gè)程序,會(huì)見到PHP的相關(guān)信息。其中有一項(xiàng)“session.name”的參數(shù),這個(gè)就是我們需要的服務(wù)器“session.name”,一般是“PHPSESSID”。

記下了SessionID的名稱后,我們就可以實(shí)現(xiàn)永久的Session數(shù)據(jù)儲(chǔ)存了!

<?php
session_start();
ini_set('session.save_path','/tmp/');
//6個(gè)鐘頭
ini_set('session.gc_maxlifetime',21600);
//保存一天
$lifeTime = 24 * 3600;
setcookie(session_name(), session_id(), time() + $lifeTime, "/");

另外對(duì)于設(shè)置php session的生存時(shí)間,網(wǎng)上看到有網(wǎng)友寫了一個(gè)很不錯(cuò)的方法,這里將代碼分享一下:

<?php
function start_session($expire=0){
	if($expire==0){
		$expire=ini_get('session.gc_maxlifetime');
	}else{
		ini_set('session.gc_maxlifetime',$expire);
	}
	if(empty($_COOKIE['PHPSESSID'])){
		session_set_cookie_params($expire);
		session_start();
	}else{
		session_start();
		setcookie('PHPSESSID',session_id(),time()+$expire);
	}
}

使用方法也很簡(jiǎn)單,例如:

<?php start_session(600);//600秒以后過(guò)期

其實(shí)真正的永久儲(chǔ)存是不可能的,因?yàn)镃ookie的保存時(shí)間有限,而服務(wù)器的空間也有限……但是對(duì)于一些需要保存時(shí)間比較長(zhǎng)的站點(diǎn),以上方法就已經(jīng)足夠了!

關(guān)鍵字:php、周期、客戶端、服務(wù)器

分享到:

頂部 】 【 關(guān)閉
版權(quán)所有:佛山思海電腦網(wǎng)絡(luò)有限公司 ©1998-2024 All Rights Reserved.
聯(lián)系電話:(0757)22630313、22633833
中華人民共和國(guó)增值電信業(yè)務(wù)經(jīng)營(yíng)許可證: 粵B1.B2-20030321 備案號(hào):粵B2-20030321-1
網(wǎng)站公安備案編號(hào):44060602000007 交互式欄目專項(xiàng)備案編號(hào):200303DD003  
察察 工商 網(wǎng)安 舉報(bào)有獎(jiǎng)  警警  手機(jī)打開網(wǎng)站