首頁 php教程 PHP开发 PHP session有效期限問題

PHP session有效期限問題

Dec 24, 2016 am 09:15 AM

一個已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session資訊儲存到資料庫,這樣可以透過SQL語句來刪除所有過期的session,精確地控制session的有效期限。這也是基於PHP的大型網站常用的方法。但是,一般的小型網站,似乎沒有必要這麼勞師動眾。 
但是一般的Session的生命期有限,如果用戶關閉了瀏覽器,就不能保存Session的變數了!那麼怎麼樣可以實現Session的永久生命期呢?
大家知道,Session儲存在伺服器端,根據客戶端提供的SessionID來得到這個使用者的文件,然後讀取文件,取得變數的值,SessionID可以使用客戶端的Cookie或Http1.1協定的Query_String(就是存取的URL的「?」後面的部分)來傳送給伺服器,然後伺服器讀取Session的目錄… 
要實現Session的永久生命期,首先需要了解一下php.ini關於Session的相關設定(開啟php.ini文件,在“[Session]”部分): 
1、session.use_cookies:預設的值是“1”,代表SessionID使用Cookie來傳遞,反之就是使用Query_String來傳遞; 
2、session.name:這個就是SessionID儲存的變數名稱,可能是Cookie,也可能是Query_String來傳遞,預設值是「PHPSESSID」; 
3、session.cookie_lifetime:這個代表SessionID在客戶端Cookie儲存的時間,預設為0,代表瀏覽器一關閉SessionID就作廢…就是因為這個所以Session不能永久使用! 
4、session.gc_maxlifetime:這個是Session資料在伺服器端儲存的時間,如果超過這個時間,那麼Session資料就會自動刪除! 
還有很多的設置,不過和本文相關的就是這些了,以下開始講使用永久Session的原理和步驟。
前面說過,伺服器透過SessionID來讀取Session的數據,但是一般瀏覽器傳送的SessionID在瀏覽器關閉後就沒有了,那麼我們只需要人為的設定SessionID並且保存下來,不就可以… 
如果你擁有伺服器的操作權限,那麼設定這個非常非常的簡單,只是需要進行如下的步驟: 
1、把「session.use_cookies」設定為1,開啟Cookie儲存SessionID,不過預設就是1,一般不用修改; 
2.把「session.cookie_lifetime」改為正無窮(當然沒有正無窮的參數,不過999999999和正無窮也沒有什麼區別); 
3、把「session.gc_maxlifetime」設定為和「session.cookie_lifetime」一樣的時間; 
在PHP的文件中明確指出,設定session有效期限的參數是session.gc_maxlifetime。可以在php.ini檔案中,或透過ini_set()函數來修改此參數。問題在於,經過多次測試,修改這個參數基本上不起作用,session有效期仍然保持24分鐘的預設值。 
由於PHP的工作機制,它並沒有一個daemon線程,來定時地掃描session資訊並判斷其是否失效。當一個有效請求發生時,PHP會根據全域變數session.gc_probability/session.gc_divisor(同樣可以透過php.ini或ini_set()函數來修改)的值,來決定是否要啟動一個GC(Garbage Collector)。預設情況下,session.gc_probability = 1,session.gc_divisor =100,也就是說有1%的可能性會啟動GC。 
GC的工作,就是掃描所有的session訊息,用當前時間減去session的最後修改時間(modified date),同session.gc_maxlifetime參數進行比較,如果生存時間已經超過gc_maxlifetime,就把該session刪除。 
到此為止,工作一切正常。那為什麼會發生gc_maxlifetime無效的情況呢? 
在預設情況下,session資訊會以文字檔案的形式,並保存在系統的暫存檔案目錄中。在Linux下,這條路徑通常為tmp,在 Windows下通常為C:WindowsTemp。當伺服器上有多個PHP應用時,它們會把自己的session檔案都保存在同一個目錄中。同樣地,這些PHP應用也會以一定機率啟動GC,掃描所有的session檔。 
問題在於,GC在工作時,並不會區分不同站點的session。舉例言之,站點A的gc_maxlifetime設定為2小時,站點B的 gc_maxlifetime設定為預設的24分鐘。當站點B的GC啟動時,它會掃描公用的臨時檔案目錄,把所有超過24分鐘的session檔案全部刪除掉,而不管它們來自於站點A或B。這樣,站點A的gc_maxlifetime設定就形同虛設了。 
找到問題所在,解決起來就很簡單了。修改session.save_path參數,或是使用session_save_path()函數,把儲存session的目錄指向一個專用的目錄,gc_maxlifetime參數運作正常了。 
嚴格來說,這算是PHP的一個bug? 
還有一個問題就是,gc_maxlifetime只能保證session生存的最短時間,並不能夠保存在超過這一時間之後session資訊立即會被刪除。因為GC是按機率啟動的,可能在某一個長時間內都沒有被啟動,那麼大量的session在超過gc_maxlifetime以後仍然會有效。解決這個問題的一個方法是,把session.gc_probability/session.gc_divisor的機率提高,如果提到100%,就會徹底解決這個問題,但顯然會對效能造成嚴重的影響。另一個方法是自己在程式碼中判斷目前session的生存時間,如果超出了 gc_maxlifetime,就清空目前session。 
但是如果你沒有伺服器的操作權限,那就比較麻煩了,你需要透過PHP程式改寫SessionID來實現永久的Session資料保存。查查php.net的函數手冊,可以看到有「session_id」這個函數:如果沒有設定參數,那麼將會傳回目前的SessionID,如果設定了參數,就會將目前的SessionID設定為給定的值…
只要利用永久性的Cookie加上「session_id」函數,就可以實現永久Session資料保存了!
但是為了方便,我們需要知道伺服器設定的“session.name”,但是一般使用者都沒有權限查看伺服器的php.ini設置,不過PHP提供了一個非常好的函數“phpinfo”,利用這個可以查看幾乎所有的PHP資訊!
------------------------------------------------- ----------------------------------- 

PHP相關資訊顯示 
phpinfo()?> 
-------------------------------------------- ---------------------------------------- 
打開編輯器,輸入上面的程式碼,然後在瀏覽器中執行這個程序,會看到PHP的相關資訊(如圖1所示)。其中有一項“session.name”的參數,這個就是我們需要的伺服器“session.name”,一般是“PHPSESSID”。 
記下了SessionID的名稱後,我們就可以實現永久的Session資料儲存了! 
session_start(); 
ini_set('session.save_path','/tmp/'); 
//6个钟头 
ini_set('session.gc_maxlifetime',21600); 
//保存一天 
$lifeTime = 24 * 3600; 
setcookie(session_name(), session_id(), time() + $lifeTime, "/");
登入後複製

後記: 
其實真正的永久儲存是不可能的,因為Cookie的保存時間有限,而伺服器的空間也有限…但是對於一些需要保存時間比較長的站點,以上方法就已經足夠了! 
把session放入mysql的Example: 
資料庫裡建表:session ( sesskey varchar32 , expiry int11 , value longtext) 
code: 
程式碼執行前已經連接資料庫了。

define('STORE_SESSIONS','mysql'); 

if (STORE_SESSIONS == 'mysql') { 
if (!$SESS_LIFE = get_cfg_var('session.gc_maxlifetime')) { 
$SESS_LIFE = 1440; 
} 

function _sess_open($save_path, $session_name) { 

// 如果没有连接数据库,可以在此执行mysql_pconnect,mysql_select_db 
return true; 
} 

function _sess_close() { 
return true; 
} 

function _sess_read($key) { 
$value_query = mysql_query("select value from sessions where sesskey = '" .addslashes($key) . "' and expiry > '" . time() . "'"); 
$value = mysql_fetch_array($value_query); 

if (isset($value['value'])) { 
return $value['value']; 
} 

return false; 
} 

function _sess_write($key, $val) { 
global $SESS_LIFE; 

$expiry = time() + $SESS_LIFE; 
$value = $val; 

$check_query = mysql_query("select count(*) as total from sessions where sesskey = '" . addslashes($key) . "'"); 
$check = mysql_fetch_array($check_query); 

if ($check['total'] > 0) { 
return mysql_query("update sessions set expiry = '" . addslashes($expiry) . "', value = '" . addslashes($value) . "' where sesskey = '" . addslashes($key) . "'"); 
} else { 
return mysql_query("insert into sessions values ('" . addslashes($key) . "', '" . addslashes($expiry) . "', '" . addslashes($value) . "')"); 
} 
} 

function _sess_destroy($key) { 
return mysql_query("delete from sessions where sesskey = '" . addslashes($key) . "'"); 
} 

function _sess_gc($maxlifetime) { 
mysql_query("delete from sessions where expiry < &#39;" . time() . "&#39;"); 

return true; 
} 

session_set_save_handler(&#39;_sess_open&#39;, &#39;_sess_close&#39;, &#39;_sess_read&#39;, &#39;_sess_write&#39;, &#39;_sess_destroy&#39;, &#39;_sess_gc&#39;); 
} 

danoo_session_name( &#39;dtvSid&#39; ); 
danoo_session_save_path(SESSION_WRITE_DIRECTORY);
登入後複製
還是有點不懂,open,write那些參數是哪裡來的。
修改php.ini配置的兩個常用函數: 
get_cfg_var('session.gc_maxlifetime') : 取得session.gc_maxlifetime的值 

ini_set('session.cookie_lifetime','0') : 0。

更多PHP session有效期限問題相關文章請關注PHP中文網!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1324
25
PHP教程
1272
29
C# 教程
1251
24