php中實(shí)現(xiàn)精確設(shè)置session過(guò)期時(shí)間的方法
大多數(shù)據(jù)情況下我們對(duì)于session過(guò)期時(shí)間使用的是默認(rèn)設(shè)置的時(shí)間,而對(duì)于一些有特殊要求的情況下我們可以設(shè)置一下session過(guò)期時(shí)間。
對(duì)此,可以在PHP中,設(shè)置php.ini,找到session.gc_maxlifetime = 1440 #(PHP5默認(rèn)24分鐘)
這里你可以隨便設(shè)置一下過(guò)期時(shí)間.但是有人說(shuō)設(shè)置以后,好象不起作用!
其實(shí)不是不起作用,而是因?yàn)橄到y(tǒng)默認(rèn):
session.gc_probability = 1 session.gc_divisor = 1000
garbage collection 有個(gè)概率的,1/1000就是session 1000次才有一次被回收。
只要你的訪問(wèn)量大了,那就能達(dá)到回收的效果.
或者你也可以設(shè)置一下session.gc_divisor 的值,
比如:session.gc_divisor = 1,這樣就能明顯的看到SESSION過(guò)期的效果了.
我們最常用的是在php程序中設(shè)置,如下例程序所示:
<?php if(!isset($_SESSION['last_access'])||(time()-$_SESSION['last_access'])>60) $_SESSION['last_access'] = time(); ?>
這樣就搞定了,如果要設(shè)置已過(guò)期的話也可以在程序中實(shí)現(xiàn):
<?php unset($_SESSION['last_access']);// 或 $_SESSION['last_access']=''; ?>
session有過(guò)期的機(jī)制:
session.gc_maxlifetime 原來(lái)session 過(guò)期是一個(gè)小概率的事件,分別使用session.gc_probability和session.gc_divisor 來(lái)確定運(yùn)行session 中g(shù)c 的概率 session.gc_probability和session.gc_divisor的默認(rèn)值分別為 1和100。分別為分子和分母 所以session中g(shù)c的概率運(yùn)行機(jī)會(huì)為1% 。如果修改這兩個(gè)值,則會(huì)降低php的效率。所以這種方法是不對(duì)的??!
因此,修改php.ini文件中的gc_maxlifetime變量就可以延長(zhǎng)session的過(guò)期時(shí)間了:(例如,我們把過(guò)期時(shí)間修改為86400秒)
session.gc_maxlifetime = 86400
然后,重啟你的web服務(wù)(一般是apache)就可以了。
session“回收”何時(shí)發(fā)生:
默認(rèn)情況下,每一次php請(qǐng)求,就會(huì)有1/100的概率發(fā)生回收,所以可能簡(jiǎn)單的理解為“每100次php請(qǐng)求就有一次回收發(fā)生”。這個(gè)概率是通過(guò)以下參數(shù)控制的
#概率是gc_probability/gc_divisor
session.gc_probability = 1 session.gc_divisor = 100
注意1:假設(shè)這種情況gc_maxlifetime=120,如果某個(gè)session文件最后修改時(shí)間是120秒之前,那么在下一次回收(1/100的概率)發(fā)生前,這個(gè)session仍然是有效的。
注意2:如果你的session使用session.save_path中使用別的地方保存session,session回收機(jī)制有可能不會(huì)自動(dòng)處理過(guò)期session文件。這時(shí)需要定時(shí)手動(dòng)(或者crontab)的刪除過(guò)期的session:
cd /path/to/sessions; find -cmin +24 | xargs rm
PHP中的session永不過(guò)期
不修改程序是最好的方法了,因?yàn)槿绻薷某绦?,測(cè)試部一定非常郁悶,那么只能修改系統(tǒng)環(huán)境配置,其實(shí)很 簡(jiǎn)單,打開(kāi)php.ini設(shè)置文件,修改三行如下:
1、session.use_cookies
把這個(gè)的值設(shè)置為1,利用cookie來(lái)傳遞sessionid
2、session.cookie_lifetime
這個(gè)代表SessionID在客戶端Cookie儲(chǔ)存的時(shí)間,默認(rèn)是0,代表瀏覽器一關(guān)閉SessionID就作廢……就是因?yàn)檫@個(gè)所以PHP的 session不能永久使用! 那么我們把它設(shè)置為一個(gè)我們認(rèn)為很大的數(shù)字吧,999999999怎么樣,可以的!就這樣。
3、session.gc_maxlifetime
這個(gè)是Session數(shù)據(jù)在服務(wù)器端儲(chǔ)存的時(shí)間,如果超過(guò)這個(gè)時(shí)間,那么Session數(shù)據(jù)就自動(dòng)刪除! 那么我們也把它設(shè)置為99999999。
就這樣一切ok了,當(dāng)然你不相信的話就測(cè)試一下看看——設(shè)置一個(gè)session值過(guò)個(gè)10天半個(gè)月的回來(lái)看看,如果你的電腦沒(méi)有斷電或者宕機(jī),你仍然可以看見(jiàn)這個(gè)sessionid。
當(dāng)然也可能你沒(méi)有控制服務(wù)器的權(quán)限并不能像我一樣幸運(yùn)的可以修改php.ini設(shè)置,一切依靠我們自己也是有辦法的,當(dāng)然就必須利用到客戶端存儲(chǔ) cookie了,把得到的sessionID存儲(chǔ)到客戶端的cookie里面,設(shè)置這個(gè)cookie的值,然后把這個(gè)值傳遞給session_id()這 個(gè)函數(shù),具體做法如下:
<?php
session_start(); // 啟動(dòng)Session
$_SESSION['count']; // 注冊(cè)Session變量Count
isset($PHPSESSID)?session_id($PHPSESSID):$PHPSESSID = session_id();
// 如果設(shè)置了$PHPSESSID,就將SessionID賦值為$PHPSESSID,否則生成SessionID
$_SESSION['count']++; // 變量count加1
setcookie('PHPSESSID', $PHPSESSID, time()+3156000); // 儲(chǔ)存SessionID到Cookie中
echo $count; // 顯示Session變量count的值
?>
session失效不傳遞
我們先寫(xiě)個(gè)php文件:<?=phpinfo()?>, 傳到服務(wù)器去看看服務(wù)器的參數(shù)配置。
轉(zhuǎn)到session部分,看到session.use_trans_sid參數(shù)被設(shè)為了零。
這個(gè)參數(shù)指定了是否啟用透明SID支持,即session是否隨著URL傳遞。我個(gè)人的理解是,一旦這個(gè)參數(shù)被設(shè)為0,那么每個(gè)URL都會(huì)啟一個(gè)session。這樣后面頁(yè)面就無(wú)法追蹤得到前面一個(gè)頁(yè)面的session,也就是我們所說(shuō)的無(wú)法傳遞。兩個(gè)頁(yè)面在服務(wù)器端生成了兩個(gè)session文件,且無(wú)關(guān)聯(lián)。(此處精確原理有待確認(rèn))
所以一個(gè)辦法是在配置文件php.ini里把session.use_trans_sid的值改成1。
當(dāng)然我們知道,不是誰(shuí)都有權(quán)限去改php的配置的,那么還有什么間接的解決辦法呢?
下面就用兩個(gè)實(shí)例來(lái)說(shuō)明:
文件1 test1.php
<?php //表明是使用用戶ID為標(biāo)識(shí)的session session_id(SID); //啟動(dòng)session session_start(); //將session的name賦值為Havi $_SESSION['name']="Havi"; //輸出session,并設(shè)置超鏈接到第二頁(yè)test2.php echo "<a href="test2.php" rel="external nofollow" >".$_SESSION['name']."</a>"; ?>
文件2: test2.php
<?php 表明是使用用戶ID為標(biāo)識(shí)的session session_id(SID); //啟動(dòng)session session_start(); //輸出test1.php中傳遞的session。 echo "This is ".$_SESSION['name']; ?>
所以,重點(diǎn)是在session_start();前加上session_id(SID);,這樣頁(yè)面轉(zhuǎn)換時(shí),服務(wù)器使用的是用戶保存在服務(wù)器session文件夾里的session,解決了傳遞的問(wèn)題。
不過(guò)有朋友會(huì)反映說(shuō),這樣一來(lái),多個(gè)用戶的session寫(xiě)在一個(gè)SID里了,那Session的價(jià)值就發(fā)揮不出來(lái)了。所以還有一招來(lái)解決此問(wèn)題,不用加session_id(SID);前提是你對(duì)服務(wù)器的php.ini有配置的權(quán)限:
output_buffering改成ON,道理就不表了。
第二個(gè)可能的原因是對(duì)服務(wù)器保存session的文件夾沒(méi)有讀取的權(quán)限,還是回到phpinfo.php中,查看session保存的地址:
session.save_path: var/tmp
所以就是檢查下var/tmp文件夾是否可寫(xiě)。
寫(xiě)一個(gè)文件:test3.php來(lái)測(cè)試一下:
<?php
echo var_dump(is_writeable(ini_get("session.save_path")));
?>
如果返回bool(false),證明文件夾寫(xiě)權(quán)限被限制了,那就換個(gè)文件夾咯,在你編寫(xiě)的網(wǎng)頁(yè)里加入:
//設(shè)置當(dāng)前目錄下session子文件夾為session保存路徑。
$sessSavePath = dirname(__FILE__).'/session/';
//如果新路徑可讀可寫(xiě)(可通過(guò)FTP上變更文件夾屬性為777實(shí)現(xiàn)),則讓該路徑生效。
if(is_writeable($sessSavePath) && is_readable($sessSavePath))
{
session_save_path($sessSavePath);
}
相關(guān)文章
php中convert_uuencode()與convert_uuencode函數(shù)用法實(shí)例
這篇文章主要介紹了php中convert_uuencode()與convert_uuencode函數(shù)用法,以實(shí)例形式了convert_uuencode()與convert_uuencode進(jìn)行編碼與解碼的方法,是非常實(shí)用的技巧,需要的朋友可以參考下2014-11-11
redirect_uri參數(shù)錯(cuò)誤的解決方法(必看)
下面小編就為大家?guī)?lái)一篇redirect_uri參數(shù)錯(cuò)誤的解決方法(必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
php-fpm超時(shí)時(shí)間設(shè)置request_terminate_timeout資源問(wèn)題分析
之前發(fā)現(xiàn)一個(gè)php配置之后關(guān)于返回500和502的問(wèn)題,今天看到一個(gè)兄弟寫(xiě)的非常不錯(cuò),記錄一下2019-09-09
php優(yōu)化及高效提速問(wèn)題的實(shí)現(xiàn)方法
下面是phper在實(shí)際編寫(xiě)中,發(fā)現(xiàn)的一些問(wèn)題,其它我們的好多代碼,需要優(yōu)化,很多程序都是可以再提速的2008-10-10
php實(shí)現(xiàn)的樹(shù)形結(jié)構(gòu)數(shù)據(jù)存取類實(shí)例
這篇文章主要介紹了php實(shí)現(xiàn)的樹(shù)形結(jié)構(gòu)數(shù)據(jù)存取類,實(shí)例演示了以樹(shù)形數(shù)據(jù)結(jié)構(gòu)存取數(shù)據(jù)的實(shí)現(xiàn)方法,對(duì)于學(xué)習(xí)基于PHP的數(shù)據(jù)結(jié)構(gòu)有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-11-11
PHP獲取網(wǎng)頁(yè)所有連接的方法(附demo源碼下載)
這篇文章主要介紹了PHP獲取網(wǎng)頁(yè)所有連接的方法,涉及PHP基于curl針對(duì)網(wǎng)頁(yè)的操作技巧,并帶附demo源碼供讀者下載參考,需要的朋友可以參考下2016-03-03
DOM基礎(chǔ)及php讀取xml內(nèi)容操作的方法
這篇文章主要介紹了DOM基礎(chǔ)及php讀取xml內(nèi)容操作的方法,實(shí)例分析了php對(duì)XML文件的增刪改查操作原理與技巧,需要的朋友可以參考下2015-01-01

