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進程