SESSION機制

一:Session與Cookie

Session:在服務器端建立並存放在服務器的內存中的,Session的內容存儲是鍵值對的列表,格式:名稱 | 類型:長度:值 
Session的生命週期:在php.ini中 session.gc_maxlifetime 爲session設置了生存時間(默認爲1440s) 客戶端關閉瀏覽器,不會影響服務器端對session的存儲。php

Cookie:在服務器端建立並寫回到客戶端瀏覽器,Cookie是http標頭的一部分,瀏覽器接到響應頭中關於寫Cookie的指令則在本地臨時文件夾中,建立了一個cookie文件,用來保存的Cookie內容。Cookie內容的存儲是鍵值對的方式 。web

Cookie的生命週期:能夠設置過時時間,若是不設置則是會話級別的,即關閉瀏覽器就會消失。redis

二:執行過程sql

        1.  過程:瀏 覽器首次訪問服務器,若是是登錄類型的網站,發送請求若是沒有帶身份,服務器檢測不到cookie會跳轉到登陸窗口,輸入用戶名和密碼後再次請求,用戶信 息後驗證經過後返回請求頁,並在HTTP頭中添加setcookie信息,瀏覽器接受到返回內容後會處理http頭部的相應信息,這裏會設置 cookie,第二次用戶訪問服務器時會瀏覽器會自動把cookie內容讀取出來並加到http頭部,服務器接受請求後驗證提交過來的 cookies是否正確,正確直接就返回相應的頁面,不正確則返回登陸頁面,其中會話是指從一個瀏覽器窗口打開到關閉這個期間。數據庫

        2. 原理: PHP默認的Session是基於Cookie的,在此期間首先調用session_start()函數,Session會先判斷當前$_COOKIE[session_name()]是否有值(session_name()返回保存session_id的COOKIE鍵名),這個值能夠從php.ini找到 session.name = PHPSESSID(默認值PHPSESSID)。若是沒有值,函數會建立一個惟一的SessionID,同時經過header頭(header(‘Set-Cookie: session_name()=session_id(); path=/’)) 將SessionID保存到客戶端的Cookie中,而且在服務器端生成Session文件,文件名規則是:sess_SESSION_ID(例 如:sess_sgj1k9pq1220g5l6ne283teld1,一個128位的哈希值),Session變量的值經php內部系列化後保存在服務 器機器上的文本文件中和客戶端的變量名(默認狀況下)爲PHPSESSID的Cookie進行對應交互。當再訪問這個網站其餘頁面時將經過http請求頭 將客戶端的Cookie中保存的SessionID攜帶過來,這時session_start()函數不會再分配新的SessionID而是在服務器端尋 找和這個SessionID 同名的Session文件將以前保存的信息取出來。apache

        3. 依賴性:PHP 中的Session在默認狀況下是使用客戶端的Cookie來保存session_id的,因此當客戶端的Cookie出問題或者禁用的時候就會影響 Session的使用了。可是Session不必定必須依賴cookie。當客戶端的Cookie被禁用或出現問題時,PHP會自動把 session_id附着在url中,這樣再經過session_id就能跨頁使用Session變量了。這種附着也是有必定條件的,即「php.ini 中的session.use_trans_sid = 1或者編譯時打開打開了--enable-trans-sid選項」。可是PHP5只能在Linux平臺能夠自動檢測Cookie的狀態而在window 平臺上沒有此功能。數組

三:Session的自動回收機制瀏覽器

    session_start() 是Session機制的開始,它有必定機率開啓垃圾回收,由於Session是存放在文件中,PHP自身的垃圾回收是無效的,Session的回收是要刪 文件的,這個機率是根據php.ini的配置決定的,有的系統的設置是 session.gc_probability =0,也就是機率是0,而是經過cron或者是其餘腳原本實現垃圾回收。默認配置是:服務器

1 session.gc_probability =12 session.gc_divisor     =1003 session.gc_maxlifetime =1440

過時時間 默認24分鐘,機率是 session.gc_probability/session.gc_divisor 結果 1/100,即session_start()函數被調用1000次纔會有一次調用垃圾回收程序,因此頁面訪問越頻繁機率就越小,建議值是1/(1000~5000)。不建議設置太小,由於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的失效時間了

四:Session操做

    例如:新添加一個值$_SESSION['name'] ='xiaoming'; 那麼這個SESSION

_SESSION的值寫入到session_id指定的文件夾中。這個階段有 可能執行更改session_id的操做,可能銷燬一箇舊的的session_id,生成一個全新的session_id,例如:角色的轉換,當它登陸後 須要換用新的session_id

1 if (isset($_COOKIE[session_name()])) {2        setcookie(session_name(),'',time() -40000,'/');  // session cookie過時3  }4 session_regenerate_id();  //這一步會生成新的session_id,再調用session_id()返回的是新的值

銷燬session的方法有2種

第一種是經過程序session_destory()方法清除全部session   unset(session['x'])來清除指定的session['x']。

第二種是經過關閉瀏覽器,關閉後會直接清除全部session。

設置session生命週期的也有2種方法。

第一種  setcookie() 直接用setcookie設置session id的生命週期。

1 $lifetime=60;//保存1分鐘2 session_start();3 setcookie(session_name(),session_id(),time()+$lifetime,"/");

 第 二種  session_set_cookie_params()   其中session_regenerate_id();方法用於改變當前session_id的值,並保留session中數組的值。參數默認爲 false,若是設置爲true則改變session_id的值,並清空當前session數組。

1 $lifetime=60;//保存1分鐘2 session_set_cookie_params($lifetime);3 session_start();4 session_regenerate_id(true);

session相關概念

1) session id

    用戶session惟一標識符,隨機生成的一串字符串,具備惟一性,隨機性。主要用於區分其它用戶的session數據。用戶第一次訪問web頁面的時 候,php的session初始化函數調用會分配給當前來訪用戶一個惟一的ID,也稱之爲session_id。

2) session data

   咱們把須要經過session保存的用戶狀態信息,稱爲用戶session數據,也稱爲session數據。

3) session file

   PHP默認將session數據存放在一個文件裏。咱們把存放session數據的文件稱爲session文件。它由特殊的php.ini設置 session.save_path指定session文件的存放路徑,CentOS5.3操做系統,PHP5.1默認存放在/var/lib/php /session目錄中。

4) session lifetime

     咱們把初始化session開始,直到註銷session這段期間,稱爲session生命週期,這樣有助於咱們理解session管理函數。

與session存儲相關php.ini設置

1) session.save_handler = file

  用於讀取/回寫session數據的方式,默認是files。它會讓PHP的session管理函數使用指定的文本文件存儲session數據。

2) session.save_path =「/var/lib/php/session」

   指定保存session文件的目錄,能夠指定到別的目錄,可是指定目錄必需要有httpd守護進程屬主(好比apache或www等)寫權限,不然沒法 回存session數據。當指定目錄不存在時,php session環境初始化函數是不會幫你建立指定目錄的,因此須要你手工創建指定目錄。

它還能夠寫成這樣session.save_path =「N;/path」 其中N是整數。這樣使得不是全部的session文件都保存在同一個目錄中,而是分散在不一樣目錄。這對於服務器處理大量session文件是頗有幫助的。(注:目錄須要本身手工建立)

3) session.auto_start = 0

  若是啓用該選項,用戶的每次請求都會初始化session。咱們推薦不啓用該設置,最好經過session_start()顯示地初始化session。

五:Session的同步與對影響系統性能

  1:session在大訪問量網站上確實影響系統性能,影響性能的緣由之一由文件系統設計形成,在同一個目錄下超過10000個文件時,文件的 定位將很是耗時,PHP支持Session目錄hash,咱們能夠經過修改php.ini中session.save_path = 「2;/path/to/session/dir」,那麼session將存儲在兩級子目錄中,每一個目錄有16個子目錄[0~f],PHP session不支持建立目錄,須要事先把那麼些目錄建立好 。       

     2:小文件的效率問題,通常咱們的Session數據都不會太大(1~2K),若是有大量這樣1~2K的文件在磁盤上,IO效率不好,PHP手冊上建議使用Reiserfs文件系統。   

六:同步問題(session共享)

       1:使用數據庫保存session, 使用數據庫來保存session,就算服務器宕機了也沒事,session照樣在。問題:程序須要定製;每次請求都進行數據庫讀寫開銷不小(使用內存數據 庫能夠提升性能,宕機就會丟失數據。可供選擇的內存數據庫有BerkeleyDB,Mysql的內存表);另外數據庫是一個單點,能夠作數據庫的ha來解 決這個問題。       

  2:使用 memcached來保存session, 這種方式跟數據庫相似,不過由於是內存存取的,性能天然要比數據庫好多了。固然存儲在redis也是比較理想 的選擇,方便存儲統計在線人數,那麼存儲在redis中也實現了這個要求,並且redis支持的數據類型多。問題:程序須要定製,增長 了工做量;存入memcached中的數據都須要序列化,效率較低;若是是文件形式的,你能夠用NFS統一存儲。

       3:還有一種方式是經過加密的cookie來實現,用戶在A服務器上登陸成功,在用戶的瀏覽器上添加一個加密的cookie,當用戶訪問B服務器時,檢查 有無Session,若是有固然沒問題,若是沒有,就去檢驗Cookie是否有效,Cookie有效的話就在B服務器上重建session。簡單,高效, 服務器的壓力減少了,由於session數據不存在服務器磁盤上。根本就不會出現session讀取不到的問題。。 問題:網絡請求佔用不少。每次請求時,客戶端都要經過cookie發送session數據給服務器,session中數據不能太多,瀏覽器對cookie 的大小存在限制。每一個瀏覽器限制是不一樣的,好比:Firefox 和Safari容許cookie 4097個字節,Opera容許cookie4096個字節,IE容許cookie4095個字節,因此不適合高訪問量的狀況,由於高訪問量的狀況下,每 次請求瀏覽器都要發送session數據給服務器,一個cookie大小2k左右。

相關文章
相關標籤/搜索