PHP中的session機制詳解


Session是什么?

首先,我們大概知道session是瀏覽器與服務器之間的一次交互會話。
那么會話又是什么呢?顧名思義就是瀏覽器與服務器之間的對話,瀏覽器一關閉,會話就結束了。

說session不得不說的就是HTTP協議和cookie了
我們都知道http協議是一個無狀態的協議,就是說本次請求和上次請求沒有任何關系。這就會帶了一個問題,如果請求的頁面有關聯,比如登錄后訪問首頁,那么在首頁怎么判斷是登錄狀態呢?

所以此時cookie就出現了,cookie是把少量的信息存儲在用戶自己的瀏覽器上,當用戶用瀏覽器訪問服務器時,PHP就可以讀取cookie中的信息,在任何頁面中都可以使用。
但是cookie存在缺陷,cookie存儲在客戶端,存儲大小有限制,一個域名下存儲個數也有限制,最關鍵的是用戶是可見的,不安全,用戶可以修改甚至禁用cookie
這個時候session就出現了,session存儲在服務器端,不用每次請求客戶端都隨身攜帶cookie
所以:session的作用就是:解決HTTP協議請求的無狀態問題,讓多次的HTTP請求產生聯系

Session的運行機制

我們要使用session,第一步就是開啟session,這也是session的第一階段:

session_start() 階段

這個函數的作用就是開啟session,開啟之后讀取cookie信息判斷是否存在session_id,如果存在就是用這個session_id,如果沒有就會隨機生成一個唯一的32位的session_id。通過這個session_id就可以綁定一個唯一的用戶。
這個過程還會初始化$SESSION這個變量,讀取session文件中的內容,把內容反序列化之后賦值到$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進程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM