原文連接https://blog.csdn.net/xihuangwutong/article/details/9819033php
1. session概念html
2. http協議與狀態保持web
3. 理解cookiesql
4. php中session的生成機制瀏覽器
5. php中session的過時回收機制緩存
6. php中session的客戶端存儲機制服務器
1. session概念
在web服務器蓬勃發展的時代,session在web開發語境下的語義是指一類用來在客戶端與服務器之間保持狀態的解決方案。cookie
2. http協議與狀態保持http協議自己是無狀態的,客戶端只須要簡單的向服務器請求下載某些文件,不管是客戶端仍是服務器都沒有必要紀錄彼此過去的行爲,每一次請求之間都是獨立的。session
然而人們很快發現若是可以提供一些按需生成的動態信息會使web變得更加有用,就像給有線電視加上點播功能同樣。這種需求一方面迫使HTML逐步添加了表單、腳本、DOM等客戶端行爲,另外一方面在服務器端則出現了CGI規範以響應客戶端的動態請求,做爲傳輸載體的HTTP協議也添加了文件上載、cookie這些特性。其中cookie的做用就是爲了解決HTTP協議無狀態的缺陷所做出的努力。至於後來出現的session機制則是又一種在客戶端與服務器之間保持狀態的解決方案。dom
session機制可能須要藉助於cookie機制來達到保存標識的目的。因此有必要了解下cookie。
3. 理解cookiecookie分發是經過擴展HTTP協議來實現的,服務器經過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也能夠生成cookie。
而cookie 的使用是由瀏覽器按照必定的原則在後臺自動發送給服務器的。瀏覽器檢查全部存儲的cookie,若是某個cookie所聲明的做用範圍大於等於將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。
cookie的內容主要包括:名字,值,過時時間,路徑和域。
其中域能夠指定某一個域好比.google.com,至關於總店招牌,好比寶潔公司,也能夠指定一個域下的具體某臺機器好比www.google.com或者froogle.google.com,能夠用飄柔來作比。路徑就是跟在域名後面的URL路徑,好比/或者/foo等等,能夠用某飄柔專櫃作比。
路徑與域合在一塊兒就構成了cookie的做用範圍。
若是不設置過時時間,則表示這個cookie的生命期爲瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期爲瀏覽器會話期的 cookie被稱爲會話cookie。會話cookie通常不存儲在硬盤上而是保存在內存裏,固然這種行爲並非規範規定的。若是設置了過時時間,瀏覽器就會把cookie保存到硬盤上,關閉後再次打開瀏覽器,這些cookie仍然有效直到超過設定的過時時間
存儲在硬盤上的cookie 不能夠在不一樣的瀏覽器間共享,能夠在同一瀏覽器的不一樣進程間共享,好比兩個IE窗口。
這是由於每中瀏覽器存儲cookie的位置不同,好比
Chrome下的cookie放在:
C:\Users\sharexie\AppData\Local\Google\Chrome\User Data\Default\Cache
Firefox下的cookie放在:
C:\Users\sharexie\AppData\Roaming\Mozilla\Firefox\Profiles\tq2hit6m.default\cookies.sqlite (倒數第二個文件名是隨機的文件名字)
Ie下的cookie放在:
C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Cookies
(網上都說是在這裏,可是我一直沒找到)
我在這裏也有一個測試,在firefox下用httplook軟件進行嗅探:
一、在本機上第一次打開必應網站,抓包:
返回的數據以下:
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Set-Cookie: _FS=NU=1; domain=.bing.com; path=/
Set-Cookie: _SS=SID=442E36ABF8F5431E8DFF0CAC018437E3; domain=.bing.com; path=/
Set-Cookie: MUID=32B1FE9DB0EB65B52006FD50B1E86565; expires=Sun, 31-Aug-2014 11:35:51 GMT; domain=.bing.com; path=/
Set-Cookie: OrigMUID=32B1FE9DB0EB65B52006FD50B1E86565%2c15deb35b84a74788ae2d9978e3e657b1; expires=Sun, 31-Aug-2014 11:35:51 GMT; domain=.bing.com; path=/
Set-Cookie: SRCHD=D=2454455&MS=2454455&AF=NOFORM; expires=Sun, 31-Aug-2014 11:35:51 GMT; domain=.bing.com; path=/
Set-Cookie: SRCHUID=V=2&GUID=F6DCC04B2CC54139928925763DAEE04A; expires=Sun, 31-Aug-2014 11:35:51 GMT; path=/
Set-Cookie: SRCHUSR=AUTOREDIR=0&GEOVAR=&DOB=20120831; expires=Sun, 31-Aug-2014 11:35:51 GMT; domain=.bing.com; path=/
P3P: CP=」NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND」
Date: Fri, 31 Aug 2012 11:35:50 GMT
Content-Length: 12787
X-Cache-Lookup: MISS from proxy:8080
咱們能夠看到sessionId爲442E36ABF8F5431E8DFF0CAC018437E3,domain爲.bing.com; path爲/。服務器爲本用戶創建一個session,id爲442E36ABF8F5431E8DFF0CAC018437E3做爲客服端的cookie中的SID的值。
二、第二次請求必應網站,請求內容以下:
看到請求中帶有sid爲442E36ABF8F5431E8DFF0CAC018437E3的cookie。
服務器返回數據:
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
P3P: CP=」NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND」
Date: Fri, 31 Aug 2012 11:41:12 GMT
Content-Length: 12437
X-Cache-Lookup: MISS from proxy:8080
服務器查看本tmp目錄中有一個文件的名字和SID匹配,知道是一個老用戶,沒有新建session,直接返回數據。
固然也有不少304的返回,表示在expires內直接用用戶的緩存便可。
咱們先來分析一下PHP中是怎麼生成一個session的。設計出session的目的是保持每個用戶的各類狀態來彌補HTTP協議的不足(無狀態)。session是保存在服務器的,既然它用於保持每個用戶的狀態那它利用什麼來區別用戶的呢?這個時候就得藉助cookie了。當咱們在代碼中調用session_start();時,PHP會同時往SESSION的存放目錄(默認爲/tmp/)和客戶端的cookie目錄各生成一個文件。session文件名稱像這樣:
格式爲sess_{SESSIONID} ,這時session文件中沒有任何內容,當咱們在session_start();添加了這兩行代碼:
$_SESSION['name'] =’sharexie’;
$_SESSION['webUlr'] = ’www.qq.com’;
這時文件就有內容了:
name|s:8:」sharexie」;webUlr|s:10:」www.qq.com」;
這時再看看cookie:
能夠看到服務器爲咱們自動生成了一個cookie,cookie名稱爲」PHPSESSID」,cookie內容是一串字符,其實這串字符就是{SESSIONID}。當咱們使用session時,PHP就先生成一個惟一的SESSIONID號(如2bd170b3f86523f1b1b60b55ffde0f66),再在咱們服務器的默認目錄下生成一個文件,文件名爲sess_{SESSIONID},同時在當前用戶的客戶端生成一個cookie,內容已經說過了。這樣PHP會爲每個用戶生成一個SESSIONID,也就是說一個用戶一個session文件。PHP第一次爲某個用戶使用session時就向客戶端寫入了cookie,當這個用戶之後訪問時,瀏覽器會帶上這個cookie,PHP在拿到cookie後就讀出裏面的SESSIONID,拿着這個SESSIONID去session目錄下找session文件。
5. php中session的過時回收機制咱們明白了session的生成及工做原理,發如今session目錄下會有許多session文件。固然這些文件必定不是永遠存在的,PHP必定提供了一種過時回收機制。在php.ini中session.gc_maxlifetime爲session設置了生存時間(默認爲1440s)。若是session文件的最後更新時間到如今超過了生存時間,這個session文件就被認爲是過時的了。在下一次session回收的時候就會被刪除。那下一次session回收是在何時呢?這和php請求次數有關的。在PHP內部機制中,當php被請求了N次後就會有一次觸發回收機制。究竟是請求多少次觸發一次是經過如下兩個參數控制的:
session.gc_probability = 1
session.gc_divisor = 100
這是php.ini的默認設置,意思是每100次PHP請求就有一次回收發生。機率是gc_probability/gc_divisor (這裏我把session.gc_divisor改成1,好像訪問了不少次都沒有觸發回收事件,不知道什麼緣由)。咱們瞭解了服務器端的session過時機制,再來看看客戶端的cookie的過時機制。
若是cookie失效了瀏覽器天然發送不了cookie到服務器,這時即便服務器的session文件存在也沒用,由於PHP不知道要讀取哪一個session文件。咱們知道PHP的cookie過時時間是在建立時設置的,那麼PHP在建立session的同時爲客戶端建立的cookie的生命週期是多久呢?這個在php.ini中有設置:session.cookie_lifetime 。這個值默認是0,表明瀏覽器一關閉SESSIONID就失效。那就是說咱們把session.gc_maxlifetime和session.cookie_lifetime設置成同一個值就能夠控制session的失效時間了。
6. php中session的客戶端存儲機制因爲cookie能夠被人爲的禁止,必須有其餘機制以便在cookie被禁止時仍然可以把session id傳遞迴服務器。解決辦法有:
一、URL重寫,就是把session id直接附加在URL路徑的後面,一種是做爲URL路徑的附加信息,表現形式爲http://…../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
二、另外一種是做爲查詢字符串附加在URL後面,表現形式爲http://…../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
這兩種方式對於用戶來講是沒有區別的,只是服務器在解析的時候處理的方式不一樣,採用第一種方式也有利於把session id的信息和正常程序參數區分開來。
爲了在整個交互過程當中始終保持狀態,就必須在每一個客戶端可能請求的路徑後面都包含這個session id。
三、表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時可以把session id傳遞迴服務器。好比下面的表單<form name=」testform」 action=」/xxx」><input type=」text」></form>在被傳遞給客戶端以前將被改寫成<form name=」testform」 action=」/xxx」><input type=」hidden」 name=」jsessionid」 value=」ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764″><input type=」text」></form>實際上這種技術能夠簡單的用對action應用URL重寫來代替。