session原理總結

1、session是怎麼保存的?怎麼去查看其內容?php

session是以文件的形式保存的。php.ini中有個配置項--session.save_path= "";這個裏面填寫的路徑,將會使session文件保存在該路徑下。session文件的命名格式是:"sess_[PHPSESSID的值]"。每一 個文件,裏面保存了一個會話的數據。其實只要使用代碼$_SESSION['user_id'] = $value;就會促發php的session機制,結果往對應的session文件中寫入一個值。html

2、session.save_path路徑下這麼多的session文件,php是如何肯定要調用哪一個session文件的數據庫

php是依據,一個名爲PHPSESSID的cookie,根據它的值,肯定要調用哪一個session文件的。去瀏覽器中,能夠看到一個 cookie名爲PHPSESSID,假如它的值爲"sess_adbjsf2q1ass26oootd163sf84",那麼,當訪問服務器的時候,就會調用session目錄下名爲"sess_sess_adbjsf2q1ass26oootd163sf84"的文件。其實,PHPSESSID就是一個會話id,以此來肯定,哪一個是你的會話數據。數組

如下是在瀏覽器查看cookie所看到的瀏覽器

 

cookie的名字PHPSESSID是能夠改的,在php.ini中 session.name = PHPSESSID就是設置該cookie的名字安全

結合本身實際開發中遇到的問題,總結一下:要說session跟cookie有關聯的地方,就是跟PHPSESSID這個cookie有綁定關係。 其餘,無論你設置什麼cookie,使用session的時候是不會用到這些值的。也沒法獲取到。好比同步登錄,設置即便設置了cookie,而你的應用 是依據session判斷是否爲登錄狀態的(事實上也必須如此,由於session保存在服務器端,安全性更高,哪一個依據cookie認爲你已經登錄,那 麼很慘)。服務器

因此,這樣的狀況就會出現,即便成功設置了cookie。也仍是不能同步登錄。cookie

 

3、常常遇到的現象:爲何刪除一個session文件,以後生成一個session文件,新的文件名字仍是與原來同樣?session

理解到session文件的命名規則是:「sess_PHPSESSID值「。那麼,就很容易明白了。由於,客戶端存在 cookie:PHPSESSID。客戶端發送請求後,會將該cookie發送給服務器(php可使用$_COOKIE['PHPSESSID']看到 其內容),這樣的話,仍是會根據PHPSESSID生成一個session文件的。dom

4、如何查看session文件中的session值?

我在開發中發現,若是僅僅依靠session_start()和$_SESSION['user_id']這樣的代碼,去調試,還不夠全面的瞭解問 題所在。好比,我想知道,session_start()到底在完成哪些操做?若是,想動態,實時知道session的值是如何被改寫的,打開一個 session文件,查看是很瞭然的。原來,裏面就是保存的是一些被序列化後的值。也明白一個知識點,"php聖經"中講解session的時候,提到 session值作被序列化了。下面看到的session內容就是被序列化了。

打開一個session文件,內容以下:

cityID|i:0;cityName|s:3:"all";fanwe_lang|s:5:"zh- cn";fanwe_currency|a:4:{s:2:"id";s:1:"1";s:6:"name_1";s:9:"人民 幣";s:4:"unit";s:3:" ¥";s:5:"radio";s:6:"1.0000";}_fanwe_hash__|s:32:"77c18770c6cb5d89444c407aaa3e8477";

 

總結出讀取規則

一、每個session的值是以分號";"分開的。好比「cityID|i:0;cityName|s:3:"all";」就是一個完整的session值結束

二、裏面的讀取規則:符號「|」前面表示session名稱。符號後面是該session的具體信息。包括:數據類型,字符長度,內容。上面第一個就至關於使用以下php代碼訪問:$_SESSION['cityID']

 

後面的s表示數據值的長度,3表示字符長度。好比這一段:fanwe_lang|s:5:"zh-cn";  fanwe_lang是變量的名稱,變量值是"zh-cn",長度恰好是5,就是」s:5「標明的。

最後"all"就表示session的具體值了。就是使用代碼$_SESSION['cityID']後會獲得的結果。

 

3.一個session能夠保存一個數組。符號{}表示數組的內容。上面的花括號{}是$_SESSION['fanwe_currency']所保存的內容。要想查看id的值,就使用代碼:$_SESSION['fanwe_currency']['id']

 

5、怎麼樣理解session_start等函數所作的實際操做是什麼?

 

我是這樣理解的:session_start,能夠當作是建立一個session文件。假若有原來的session文件,或許沒有建立。引入一個。往session文件中寫值,那是代碼「$_SESSION['']=" ";  賦值所完成的操做。
session_start() 生成一個新的session文件名時。會判斷是否存在cookie名爲PHPSESSID的值。若是存在,那麼就會按照它的值,組合成一個文件 名"sess_[phpcookie值]"。因此,在目錄下,總是可以看到以前刪除過的session文件名。若是將瀏覽器中對應的cookie(PHPSESSID)刪掉。那麼就不會生成一樣的名字了。若是不存在名爲PHPSESSID的cookie。php所作的估計爲:先發送一個cookie,而後按照cookie的值生成一個(我能夠在瀏覽器中立刻看到一個名爲PHPSESSID的cookie)

其實,如今也更加深入地理解了一個知識:在調用session_start()以前不能有任何輸出。有輸出就會報錯。

session_start()已經封裝了發送cookie的操做(發送一個名稱爲PHPSESSID的cookie到瀏覽器)。涉及到http的一個原理:頭部信息必須在內容以前發送才行。因此,使用echo '內容';

header('Content-type: text/xml; charset=gb2312');//頭部信息,不算內容

能夠這樣認爲:session_start()內部已經進行了一次發送頭部動做。因此以前不能有任何輸出內容。
手冊中的英文大體是這樣說的:建立一個session,或者恢復當前一個session(基於request請求傳遞的session id,這裏應該值的就是http請求時傳遞的名爲PHPSESSID的cookie)

 

實際開發應用總結:

只要是同一個用戶的操做。導航程序訪問記錄和團購程序訪問的記錄都是保存在同一個session文件中

若是是不一樣的域呢?假如用戶訪問cs.test.com和daohang.test.com,兩方程序都設置了session。那麼session的結果保存在同一個session文件中嗎?

由於:服務器是統一管理session文件的存放的。而php引擎是根據phpsessionid的值肯定要操做哪一個session文件。session

文件名的格式是:"sess_[phpcookie值]"。依次尋找對應的session文件(因而在瀏覽器查看名爲PHPSESSIONID的cookie,過時時間是在會話結束後)
因此,只要cs.test.com和daohang.test.com使用的是同一臺服務器。
這樣的話,假如是多臺服務器的狀況。那麼就不得不將session保存在數據庫中去。這樣實現session共享。跟具體的服務器是無關的。

 

(2013年更新:實際上共享session不侷限於數據庫中保存,關於session共享方案,根據本身的理解一年後寫了一篇總結文章,http://www.cnblogs.com/wangtao_20/p/3395518.html

session 文件是某個用戶整個會話過程當中數據。那麼,假如cs.test.com和daohang.test.com下的兩個程序運行在同一個服務器上。就意味着, 訪問cs.test.com與訪問daohang.test.com是同一個會話。也就意味着,這兩邊訪問後設置的session數據是保存在同一個 session文件中的。

能夠將名爲PHPSESSIONID的cookie,其值當作是一個會話的id。會話結束後,該cookie過時或者被刪。那麼,服務器對應的 session文件(名爲"sess_[phpcookie值]")會被刪掉嗎?查看發現並不會被刪掉。因此纔會有session文件不少,出現讀取性能 的問題。session文件比較多的狀況下,產生I/Q讀寫性能問題。瞭解到能夠將session文件分多個目錄保存(參考http://www.jb51.net/article/27941.htm)。php.ini中的配置項session.save_path,前面一個值M能夠指定目錄的深度級別。這個沒測試過。須要用到的時候,再去測試一下。

待解決疑問

1、session的過時時間是怎麼肯定的?
查看session文件內容,發現裏面有個值設置了session文件的過時時間:__HTTP_Session_Expire_TS|i:1297750868;

已掌握的信息:
PHPSESSID該cookie的過時時間在瀏覽器中顯示:會話結束後過時

全部的session文件沒有被自動刪掉,只是有個過時時間,以此決定:是新生成一個session文件仍是使用原來的。

原來:服務器按期session清理機制估計會用到這個東西

2、若是沒有設置php.ini中的參數。php默認會將session文件保存到什麼位置?

附網文:php.ini中配置session參數的說明。

【Session】

[服務端]

session.save_handler = files

默認爲file,定義session在服務端的保存方式,file意爲把sesion保存到一個臨時文件裏,若是咱們想自定義別的方式保存

(好比用數據庫),則須要把該項設置爲user;

session.save_path = "D:/APMServ5.2.0/PHP/sessiondata/"

定義服務端存儲session的臨時文件的位置。

session.auto_start = 0

如置1,則不用在每一個文件裏寫session_start(); session自動start :)

session.gc_probability = 1

session.gc_divisor    = 100

session.gc_maxlifetime = 1440

這三個配置組合構建服務端session的垃圾回收機制

session.gc_probability 與session.gc_divisor構成執行session清理的機率,理論上的解釋爲服務端按期有必定的機率調用gc函數來對session進行清 理,清理的機率爲:gc_probability/gc_divisor 好比:1/100  表示每個新會話初始化時,有

1%的機率會啓動垃圾回收程序,清理的標準爲session.gc_maxlifetime定義的時間。

 

[客戶端]

session.use_cookies = 1

sessionid在客戶端採用的存儲方式,置1表明使用cookie記錄客戶端的sessionid,同時,$_COOKIE變量裏纔會有$_COOKIE[

‘PHPSESSIONID’]這個元素存在;

session.use_only_cookies = 1

也是定義sessionid在客戶端採用的存儲方式,置1表明僅僅使用 cookie 來存放會話 ID。通常來講,如今客戶端都會支持

cookie,因此建議設置成1,這樣能夠防止有關經過 URL 傳遞會話 ID 的攻擊。
session.use_trans_sid = 0

相對應於上面那個設置,這裏若是置1,則表明容許sessionid經過url參數傳遞,同理,建議設置成0;

session.referer_check = 

這個設置在session.use_trans_sid = 1的時候纔會生效,目的是檢查HTTP頭中的"Referer"以判斷包含於URL中的會話id是否

有效,HTTP_REFERER必須包含這個參數指定的字符串,不然URL中的會話id將被視爲無效。因此通常默認爲空,即不檢查。 
session.name = PHPSESSID

定義sessionid的名稱,即變量名,因此經過瀏覽器http工具看到的http頭文件裏的PHPSESSID=##############;

session.hash_function = 0

選擇session_name的加密方式,0表明md5加密,1表明sha1加密,默認是0,可是聽說用sha1方式加密,安全性更高;
session.hash_bits_per_character = 4

指定在session_name字符串中的每一個字符內保存多少位二進制數,這些二進制數是hash函數的運算結果。

4   bits:   0-9,   a-f 

5   bits:   0-9,   a-v 

6   bits:   0-9,   a-z,   A-Z,   "-",   ","

 

url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset="

指定重寫哪些HTML標籤來包含sid(session_id)(僅在"session.use_trans_sid"打開的狀況下有效),URL重寫器將添加一個

隱藏的"<input>",它包含了本應當額外追加到URL上的信息。 

session.cookie_lifetime = 0

保存sessionid的cookie文件的生命週期,如置0,表明會話結束,則sessionid就自動消失,常見的強行關閉瀏覽器,就會丟

失上一次的sessionid;

session.cookie_path = /

保存sessionid的cookie文件在客戶端的位置;

session.cookie_domain = /

保存sessionid的cookie的域名設置,這跟cookie容許的域名的訪問權限設置有關,通常來講想讓本身網站全部的目錄都能訪

問到客戶端的cookie,就應該設置成「/」如須要詳細瞭解,能夠看下setcookie()函數的domain參數相關設置和使用方法;

session.bug_compat_42 = 1

session.bug_compat_warn = 1

這兩個能夠說幾乎是快要被廢棄的設置,是爲了老版本的php服務的,主要是針對 session_register函數,由於php5的

register_global默認是關閉狀態,因此在php5里根本用不到 session_register這個函數;而且php6就要廢除這個設置,直接定義爲關閉,因此不必研究這兩個了;

今天無心中看php手冊,注意到這句話:

在某些操做系統上,建議使用能夠高效處理 大量小尺寸文件的文件系統上的路徑來保存會話數據。 例如,在 Linux 平臺上,對於會話數據保存的工做而言,reiserfs 文件系統會比 ext2fs 文件系統可以提供更好的性能。

這個是好的方向。session的數據通常很小。適合小文件的文件系統來使用,而咱們的傳統的文件系統不太適合。

原文地址:http://www.cnblogs.com/wangtao_20/archive/2011/02/16/1955659.html

相關文章
相關標籤/搜索