1. 程式人生 > 程式設計 >通過程式碼例項解析PHP session工作原理

通過程式碼例項解析PHP session工作原理

這裡的介紹主要是基於php語言,其他的語言操作可能會有差別,但基本的原理不變。

1.在php中如何操作session:

session_start(); //使用該函式開啟session功能

$_SESSION  //使用預定義全域性變數操作資料

使用unset($_SESSION['key']) //銷燬一個session的值

簡單地操作,一切都是由伺服器實現;由於處理在後臺,一切看起來也很安全。但是session採用什麼樣機制,又是怎樣被實現,並且如何來保持會話的狀態的呢?

2.session實現與工作原理

瀏覽器和伺服器採用http無狀態的通訊,為了保持客戶端的狀態,使用session來達到這個目的。然而服務端是怎麼樣標示不同的客戶端或使用者呢?

這裡我們可以使用生活中的一個例子,假如你參加一個晚會,認識了很多人,你會採取什麼方式來區分不同的人呢!你可能根據臉型,也有可能根據使用者的名字,

或者人的身份證,即採用一個獨一無二的標示。在session機制中,也採用了這樣的一個唯一的session_id來標示不同的使用者,不同的是:瀏覽器每次請求都會帶上

由伺服器為它生成的session_id.

原理很簡單,假設你訪問網頁時就像逛澡堂,第一次進去你是沒有鑰匙的,這個時候你交了錢服務檯就分配一把鑰匙給你,你走到哪裡都要帶上,因為這是你身份的唯一標識,接下來你用這把鑰匙可以去開啟一個專有的儲物櫃儲存你的衣物,游完泳,你再用鑰匙去開啟櫃子拿出衣物,最後離開游泳池時,把鑰匙歸還,你的這次游泳的過程就是一次session,或者叫做會話,在這個例子中,鑰匙就是session的key,而儲物櫃可以理解為儲存使用者會話資訊的介質。

那麼在web server中如何實現session呢?想必看了上面的例子你會很容易理解,主要是解決兩個問題,一個是鑰匙的問題,一個是儲存使用者資訊的問題。對於第一個問題,即什麼東西可以讓你每次請求都會自動帶到伺服器呢?如果你比較瞭解http協議,那麼答案一目瞭然,就是cookie,如果你想為使用者建立一次會話,可以在使用者授權成功時給他一個cookie,叫做會話id,它當然是唯一的,比如php就會為建立會話的使用者預設set一個名為phpsessid,值看起來為一個隨機字串的cookie,如果下次發現使用者帶了這個cookie,伺服器就知道,哎呀,剛剛這位顧客來了。

剩下的是解決第二個問題,即如何儲存使用者的資訊,伺服器知道會話id為abc的使用者來了,那abc想儲存自己的私人資訊,比如購物車資訊,如何處理?這個時候可以用記憶體、也可以用檔案,也可以用資料庫了,但有個要求是,資料需要用使用者的會話id即可取到,比如php就預設會把會話id為abc的使用者會話資料儲存到/tmp/phpsess_abc的檔案裡面,每次讀取都要反序列化程式可以理解的資料,寫的時候又需要序列化為持久的資料格式。

較好理解的描述:

session被用於表示一個持續的連線狀態,在網站訪問中一般指代客戶端瀏覽器的程序從開啟到結束的過程。session其實就是網站分析的訪問(visits)度量,表示一個訪問的過程。

session的常見實現形式是會話cookie(session cookie),即未設定過期時間的cookie,這個cookie的預設生命週期為瀏覽器會話期間,只要關閉瀏覽器視窗,cookie就消失了。實現機制是當用戶發起一個請求的時候,伺服器會檢查該請求中是否包含sessionid,如果未包含,則系統會創造一個名為JSESSIONID的輸出 cookie返回給瀏覽器(只放入記憶體,並不存在硬碟中),並將其以HashTable的形式寫到伺服器的記憶體裡面;當已經包含sessionid是,服務端會檢查詢到與該session相匹配的資訊,如果存在則直接使用該sessionid,若不存在則重新生成新的 session。這裡需要注意的是session始終是有服務端建立的,並非瀏覽器自己生成的。 但是瀏覽器的cookie被禁止後session就需要用get方法的URL重寫的機制或使用POST方法提交隱藏表單的形式來實現。

簡單介紹一下流程:當客戶端訪問伺服器時,伺服器根據需求設定session,將會話資訊儲存在伺服器上,同時將標示session的session_id傳遞給客戶端瀏覽器,

瀏覽器將這個session_id儲存在記憶體中(還有其他的儲存方式,例如寫在url中),我們稱之為無過期時間的cookie。瀏覽器關閉後,這個cookie就清掉了,它不會存在使用者的cookie臨時檔案。

以後瀏覽器每次請求都會額外加上這個引數值,再伺服器根據這個session_id,就能取得客戶端的資料狀態。

如果客戶端瀏覽器意外關閉,伺服器儲存的session資料不是立即釋放,此時資料還會存在,只要我們知道那個session_id,就可以繼續通過請求獲得此session的資訊;但是這個時候後臺的session還存在,但是session的儲存有一個過期

時間,一旦超過規定時間沒有客戶端請求時,他就會清除這個session。

下面介紹一下session的儲存機制,預設的session是儲存在files中,即以檔案的方式儲存session資料。在php中主要根據php.ini的配置session.save_handler

來選擇儲存session的方式。

這裡順便說明一下,如果要做伺服器的lvs,即多臺server的話,我們一般使用memcached的方式session,否則會導致一些請求找不到session。

一個簡單的memcache配置:

session.save_handler = memcache

session.save_path = "tcp://10.28.41.84:10001"

當然如果一定要使用files檔案快取,我們可以將檔案作nfs

,將所有的儲存session檔案定位到一個地方。

剛才講返回給使用者的session-id最終儲存在記憶體中,這裡我們也可以設定引數將其儲存在使用者的url中。

3.例項問題

現有系統A,B; 假設A系統是可以獨立執行的web系統,即可以和瀏覽器直接處理session, B系統是基於mobile的,需要呼叫A系統的功能介面,

在保持A不改變的情況下,即登陸驗證,session儲存都不變的情況下,B系統能處理前端使用者的請求。

這裡提供的方案是使用PHP實現

在使用者登陸成功後,將儲存的session的session-id返回給B系統,然後B系統每次請求其他介面都帶session_id。

A系統在session_start前加上session_id(session_id);

這樣B系統就能安全的呼叫A

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。