Session的執行機制及怎樣適用於微信小程式中

网风笔记开发者發表於2024-08-31

瀏覽器透過web訪問伺服器,伺服器的web服務開啟後,第一步就是開啟session,這也是session的第一階段:

session_start()

  這個函式的作用:開啟session,然後根據以前設定的session_name去讀取cookie資訊,判斷$_Cookies[$session_name]判斷是否有值,也就是是否存在session_id,如果存在就用這個session_id,如果沒有就會隨機生成一個唯一的32位的數值,將這個數值賦值給session_id。這個session_id就代表當前訪問的使用者。然後初始化$SESSION這個變數,根據session_id讀取session檔案中的內容(如果有session_id所對應的儲存檔案的話),把內容反序列化之後賦值到$SESSION這個變數中,這個階段還有一個特別關鍵的作用,還會判斷那些session檔案已經過期,呼叫gc程序,刪除掉過期的session檔案。gc如何判斷檔案是否過期,如何操作後面再說

session_start(); echo "SID: ".SID.""; echo "session_id(): ".session_id().""; echo "COOKIE: ".$_COOKIE["PHPSESSID"];
輸出:
SID:PHPSESSID=bjjwfoo45hajsjv89trsgtiertbuiwom
session_id():bjjwfoo45hajsjv89trsgtiertbuiwom
cookie:提示Notice:undefined index:PHPSESSID
這個因為瀏覽器第一次請求還沒有在cookie中儲存session_id,這個cookie的一個特性,只有當第一次請求之後,伺服器接收到請求才在伺服器端設定cookie,儲存session_id。
注意:cookie中儲存的session_id預設是會話時間

SID:是系統常量,SID包含著會話名以及會話ID的常量,格式為“name=ID”,如果cookie中已經存在session_id,SID就為一個空字串,不然就是"name=ID"

第二階段就是指令碼執行期間:
php只是對$_SESSION這個變數進行增刪改查的操作,需要注意:這個階段並沒有影響到session檔案裡面的內容,除非你在這個階段session_destroy()了,除此之外,該階段不會對session檔案有任何影響

第三階段:指令碼執行結束
在這個階段才會對session檔案進行操作,也就是這個階段才會把$_SESSION陣列中的資料序列化然後儲存到session檔案。

session的儲存方式

預設會儲存在伺服器的臨時目錄,以檔案的形式儲存,檔名為(sess_+session_id),這些都可以在php.ini檔案中配置,檔案內容為序列化的資料,如下:

$_SESSION['name'] = ‘張三'
$_SESSION['age'] = 18
session檔案為:
    name|i:張三;age|i:18

下面是常用的php.ini檔案中sessionde相關配置:

session.save_handler = files    #規定session的儲存方式,預設是檔案,還可以是redis或者是memcache,提升效率
session.save_path = "d:/wamp/tmp"    #規定session檔案的儲存目錄
session.use_cookies = 1    #是否使用cookie儲存session_id
session.name = PHPSESSID    #客戶端儲存session_id的會話名
session.auto_start = 0    #是否自動開啟session
session.cookie_lifetime = 0    #設定客戶端中儲存的session_id的過期時間,注意session的過期時間是間隔的,比如20分鐘過期,重新訪問了,session的過期時間會重新計算,cookie的過期時間是累記的
session.serialize_handler = php
session.gc_divisor = 1000
session.gc_probability = 1
session.gc_maxlifetime = 1440    #設定session檔案的過期時間

session的垃圾回收機制

一個使用者訪問伺服器會產生一個session檔案,關閉瀏覽器,然後在訪問伺服器又會產生一個新的session檔案,這樣session的垃圾檔案就會很多,長時間不清理就會佔用大量的磁碟空間,訪問session檔案的速度也會降低,gc程序垃圾回收就很有必要了
先提一下PHP的一些清理session的函式

unset($_SESSION['name'])    清理某個變數
session_unset()    不傳引數,清除所有的session變數,但是session檔案還在
session_destroy()    清除session檔案
setcookie(session_name(), '', time()-1000, '/')    設定cookie檔案過期

注意:一般做了session_destroy()操作之後,setcookie(session_name(), '', time()-1000, '/')也是必須的,不然使用者重新重新整理頁面,又會設定一樣的session_id,產生session檔案

然後就是gc自動刪除垃圾檔案:

session.gc_divisor = 1000
session.gc_probability = 1
session.gc_maxlifetime = 1440    #設定session檔案的過期時間

刪除session垃圾檔案的機率是,session.gc_probability/session.gc_divisor=1/1000,也就是說每次session_start()都會有1/1000的機率觸發gc程序,但是1000次中必會有一次,如果session.gc_probalility = 1000,就是100%的機率,也就說每次session_start()都會觸發gc程序

微信小程式中的session應用

微信小程式中並沒有cookie機制,因此除非你在微信小程式中模擬cookie機制的實現,否則你要專門設定程式碼用來傳送session_id。

wx.request({
url: 'https://your_domain.com/api/function',
header: {
'content-type': 'application/json', // 預設值
'session_id': wx.getStorageSync('session_id') // 讀取本地快取中的session_id值
},
success: function(res) {
console.log(res.data)
}
})

後端獲取3rd_session的方式也非常簡單,只需要讀取HTTP Header中的3rd_session欄位即可。PHP程式碼示例如下:

session_id($_SERVER["session_id"]); // 將讀取到的前端session_id設定成伺服器端的session_id
session_start();
if(isset($_SESSION['session_key'])&&($_SESSION['openid']==$openid)){
// 3rd_session驗證透過
}

相關文章