2019-03-05

session()到底是做什么的

session是啥?

首先淑翼,我大致的知道,session是一次瀏覽器和服務(wù)器的交互的會(huì)話品追,會(huì)話是啥呢玄括?就是我問(wèn)候你好嗎?你回恩很好肉瓦。就是一次會(huì)話遭京,那么對(duì)話完成后,這次會(huì)話就結(jié)束了泞莉,還有我也知道哪雕,我們可以將一個(gè)變量存入全部的$_SESSION['name']中,這樣php的各個(gè)頁(yè)面和邏輯都能訪問(wèn)到鲫趁,所以很輕松的用來(lái)判斷是否登陸斯嚎。

這是我之前理解的session,當(dāng)然也是對(duì)的,只是解釋的太膚淺堡僻,理解的太表面了糠惫,面試官如果聽(tīng)到這樣的答案其實(shí)是不太滿意的。我參考了其他的很多資料钉疫,徹底理解清楚session硼讽。

在說(shuō)session是啥之前,我們先來(lái)說(shuō)說(shuō)為什么會(huì)出現(xiàn)session會(huì)話牲阁,它出現(xiàn)的機(jī)理是什么固阁?我們知道,我們用瀏覽器打開(kāi)一個(gè)網(wǎng)頁(yè)城菊,用到的是HTTP協(xié)議您炉,學(xué)過(guò)計(jì)算機(jī)的應(yīng)該都知道這個(gè)協(xié)議,它是無(wú)狀態(tài)的役电,什么是無(wú)狀態(tài)呢赚爵?就是說(shuō)這一次請(qǐng)求和上一次請(qǐng)求是沒(méi)有任何關(guān)系的,互不認(rèn)識(shí)的法瑟,沒(méi)有關(guān)聯(lián)的冀膝。但是這種無(wú)狀態(tài)的的好處是快速。

所以就會(huì)帶來(lái)一個(gè)問(wèn)題就是霎挟,我希望幾個(gè)請(qǐng)求的頁(yè)面要有關(guān)聯(lián)窝剖,比如:我在www.a.com/login.php里面登陸了,我在www.a.com/index.php 也希望是登陸狀態(tài)酥夭,但是赐纱,這是2個(gè)不同的頁(yè)面,也就是2個(gè)不同的HTTP請(qǐng)求熬北,這2個(gè)HTTP請(qǐng)求是無(wú)狀態(tài)的疙描,也就是無(wú)關(guān)聯(lián)的,所以無(wú)法單純的在index.php中讀取到它在login.php中已經(jīng)登陸了讶隐!

那咋搞呢起胰?我不可能這2個(gè)頁(yè)面我都去登陸一遍吧∥籽樱或者用笨方法這2個(gè)頁(yè)面都去查詢數(shù)據(jù)庫(kù)效五,如果有登陸狀態(tài),就判斷是登陸的了炉峰。這種查詢數(shù)據(jù)庫(kù)的方案雖然可行畏妖,但是每次都要去查詢數(shù)據(jù)庫(kù)不是個(gè)事,會(huì)造成數(shù)據(jù)庫(kù)的壓力疼阔。

所以正是這種訴求戒劫,這個(gè)時(shí)候半夷,一個(gè)新的客戶端存儲(chǔ)數(shù)據(jù)方式出現(xiàn)了:cookie。cookie是把少量的信息存儲(chǔ)在用戶自己的電腦上谱仪,它在一個(gè)域名下是一個(gè)全局的玻熙,只要設(shè)置它的存儲(chǔ)路徑在域名www.a.com下 ,那么當(dāng)用戶用瀏覽器訪問(wèn)時(shí)疯攒,php就可以從這個(gè)域名的任意頁(yè)面讀取cookie中的信息嗦随。所以就很好的解決了我在www.a.com/login.php頁(yè)面登陸了,我也可以在www.a.com/index.php獲取到這個(gè)登陸信息了敬尺。同時(shí)又不用反復(fù)去查詢數(shù)據(jù)庫(kù)枚尼。

雖然這種方案很不錯(cuò),也很快速方便砂吞,但是由于cookie 是存在用戶端署恍,而且它本身存儲(chǔ)的尺寸大小也有限,最關(guān)鍵是用戶可以是可見(jiàn)的蜻直,并可以隨意的修改盯质,很不安全。那如何又要安全,又可以方便的全局讀取信息呢?于是龄毡,這個(gè)時(shí)候,一種新的存儲(chǔ)會(huì)話機(jī)制:session 誕生了王悍。

我擦,終于把session是怎么誕生的給圓清楚了餐曼,不容易把勾ⅰ!T雌集惋!

好,session 誕生了瓶佳,從上面的描述來(lái)講芋膘,它就是在一次會(huì)話中解決2次HTTP的請(qǐng)求的關(guān)聯(lián),讓它們產(chǎn)生聯(lián)系霸饲,讓2兩個(gè)頁(yè)面都能讀取到找個(gè)這個(gè)全局的session信息。session信息存在于服務(wù)器端臂拓,所以也就很好的解決了安全問(wèn)題厚脉。

session的運(yùn)行機(jī)制和是怎么保存的?

既然胶惰,它也是一種服務(wù)區(qū)存儲(chǔ)數(shù)據(jù)的方式傻工,肯定也是存在服務(wù)器的某個(gè)地方了。確實(shí),它存在服務(wù)器的/tmp 目錄下中捆,這一點(diǎn)我們接下來(lái)慢慢講鸯匹。

我們先說(shuō)下它的運(yùn)行機(jī)制,是怎么分配的泄伪。我們主要用PHP中session的機(jī)制殴蓬,其實(shí)各種語(yǔ)言都差不多。

如果這個(gè)時(shí)候蟋滴,我們需要用到session染厅,那我們第一步怎么辦呢?第一步是開(kāi)啟session:

session_start();

這是個(gè)無(wú)任何返回值的函數(shù)津函,既不會(huì)報(bào)錯(cuò)肖粮,也不會(huì)成功。它的作用是開(kāi)啟session尔苦,并隨機(jī)生成一個(gè)唯一的32位的session_id涩馆,類似于這樣:

4c83638b3b0dbf65583181c2f89168ec

session的全部機(jī)制也是基于這個(gè)session_id,它用來(lái)區(qū)分哪幾次請(qǐng)求是一個(gè)人發(fā)出的允坚。為什么要這樣呢魂那?因?yàn)镠TTP是無(wú)狀態(tài)無(wú)關(guān)聯(lián)的,一個(gè)頁(yè)面可能會(huì)被成百上千人訪問(wèn)屋讶,而且每個(gè)人的用戶名是不一樣的冰寻,那么服務(wù)器如何區(qū)分這次是小王訪問(wèn)的,那次是小名訪問(wèn)的呢皿渗?所以就有了找個(gè)唯一的session_id 來(lái)綁定一個(gè)用戶斩芭。一個(gè)用戶在一次會(huì)話上就是一個(gè)session_id,這樣成千上萬(wàn)的人訪問(wèn)乐疆,服務(wù)器也能區(qū)分到底是誰(shuí)在訪問(wèn)了划乖。

我們做個(gè)試驗(yàn),看看挤土,是不是這樣的:

我們?cè)趐hp.iyangyi.com 域名下的a.php 頁(yè)面中琴庵,輸入如下代碼:

session_start(); echo "SID: ".SID."
"; echo "session_id(): ".session_id()."
"; echo "COOKIE: ".$_COOKIE["PHPSESSID"];

我們?cè)L問(wèn)一下a.php頁(yè)面,看能輸出什么仰美?

image

我們看到居然還有一個(gè)警告迷殿。我們先一個(gè)一個(gè)的看。首先SID這個(gè)常量咖杂,我們沒(méi)有給它賦值庆寺,它居然能有輸出,其次session_id()這個(gè)系統(tǒng)方法是輸出本次生成的session_id诉字。最后$_COOKIE['PHPSESSIID'] 沒(méi)有值懦尝,這個(gè)我們接下來(lái)說(shuō)知纷。

好,我們?cè)俅嗡⑿逻@個(gè)頁(yè)面陵霉,我們能看到什么琅轧?

image

奇怪的事情發(fā)生了。SID 沒(méi)有值了踊挠,$_COOKIE['PHPSESSID']中有值了乍桂。而且,2次刷新止毕,session_id 都是一樣

的:bjvlo4p38cfqkr1hr7pe924ts3模蜡,實(shí)際情況下,只要不關(guān)閉網(wǎng)頁(yè)扁凛,怎么刷新都是一樣:

既然我們看到COOKIE中有值了忍疾,我們,打開(kāi)firebug開(kāi)看到底是什么:

image

而且這個(gè)PHPSESSID的過(guò)期時(shí)間是會(huì)話谨朝,什么意思呢卤妒?就是瀏覽器只要不關(guān)就一直不存,瀏覽器一關(guān)就過(guò)期字币,消失了则披。

好,我們關(guān)掉瀏覽器洗出,重新打開(kāi)a.php頁(yè)面士复,看看有沒(méi)有什么變化:

image

你看翩活,是不是又回到當(dāng)初第一次打開(kāi)時(shí)候的樣子阱洪。

OK,解惑的時(shí)候到了:

每次我們?cè)L問(wèn)一個(gè)頁(yè)面菠镇,如果有開(kāi)啟session冗荸,也就是有session_start() 時(shí),就會(huì)自動(dòng)生成一個(gè)session_id 來(lái)標(biāo)注是這次會(huì)話的唯一ID利耍,同時(shí)也會(huì)自動(dòng)往cookie里寫入一個(gè)名字為PHPSESSID的變量蚌本,它的值正是session_id,當(dāng)這次會(huì)話沒(méi)結(jié)束隘梨,再次訪問(wèn)的時(shí)候程癌,服務(wù)器會(huì)去讀取這個(gè)PHPSESSID的cookie是否有值有沒(méi)過(guò)期,如果能夠讀取到轴猎,則繼續(xù)用這個(gè)session_id席楚,如果沒(méi)有,就會(huì)新生成一個(gè)session_id税稼,同時(shí)生成PHPSESSID這個(gè)cookie烦秩。由于默認(rèn)生成的這個(gè)PHPSESSID cookie是會(huì)話,也就是說(shuō)關(guān)閉瀏覽器就會(huì)過(guò)期掉郎仆,所以只祠,下次重新瀏覽時(shí),會(huì)重新生成一個(gè)session_id扰肌。

好抛寝,這個(gè)是session_id,就用來(lái)標(biāo)識(shí)綁定一個(gè)用戶的曙旭,既然session_id生成了盗舰。那么當(dāng)我們往session里面寫入數(shù)據(jù),是如何保存的桂躏,答案是保存在服務(wù)器的臨時(shí)目錄里钻趋,根據(jù)php.ini的配置,我機(jī)子上的這個(gè)session是存在D:\wamp\tmp 目錄里的剂习。我們先說(shuō)是存在這個(gè)目錄下蛮位,然后待會(huì)將如何修改。

那么它是怎么存的呢鳞绕?

同樣也是用到session_id失仁。session_id是32位的,服務(wù)器會(huì)用 sess_前綴 + session_id 的形式存在這個(gè)臨時(shí)目錄下们何,比如上面這個(gè)例子:

image

所以萄焦,每一次生成的session_id都會(huì)生成一個(gè)這樣的文件,用來(lái)保存這次會(huì)話的session信息冤竹。

我們往session里寫入些數(shù)據(jù)拂封,來(lái)看看session是怎么往這個(gè)文件里寫數(shù)據(jù)的,我們同樣在a.php頁(yè)面繼續(xù)加上寫入session的語(yǔ)句:

<pre style="font-family:Menlo, Monaco, Consolas, 'Courier New', monospace;font-size:14px;line-height:1.42857;color:rgb(51,51,51);border:1px solid rgb(204,204,204);">$_SESSION['hello'] = 123;</pre>

<pre style="font-family:Menlo, Monaco, Consolas, 'Courier New', monospace;font-size:14px;line-height:1.42857;color:rgb(51,51,51);border:1px solid rgb(204,204,204);">$_SESSION['word'] = 456;</pre>

然后贴见,我刷新頁(yè)面烘苹,由于我并沒(méi)有關(guān)閉頁(yè)面,就這是說(shuō)這次會(huì)話還沒(méi)結(jié)束片部,那么肯定還會(huì)是同樣的session_id : bjvlo4p38cfqkr1hr7pe924ts3

然后镣衡,我們 用編輯器打開(kāi)它的存儲(chǔ)文件sess_bgg20mcl86drbt3j08jg5h5h17這個(gè)文件,看看里面是啥?

<pre style="font-size:14px;line-height:22px;border:1px solid rgb(204,204,204);">hello|i:123;word|i:456;
</pre>

是序列化的數(shù)據(jù)档悠,我們?nèi)庋垡材茏x出來(lái)廊鸥。當(dāng)我們往$_SESSION全局變量里寫數(shù)據(jù)時(shí),它會(huì)自動(dòng)往這個(gè)文件里寫入辖所。讀取session的時(shí)候惰说,也會(huì)根據(jù)session_id 找到這個(gè)文件,然后讀取需要的session變量缘回。

這個(gè)sess文件不會(huì)隨著客戶端的PHPSESSID過(guò)期吆视,也一起過(guò)期掉典挑,它會(huì)一直存在,出息GC掃描到它過(guò)期或者使用session_destroy()函數(shù)摧毀啦吧,我們?cè)谙旅嬷v到session·回收的時(shí)候會(huì)說(shuō)到您觉。

我們大致總結(jié)下:

HTTP請(qǐng)求一個(gè)頁(yè)面后,如果用到開(kāi)啟session授滓,會(huì)去讀cookie中的PHPSESSID是否有琳水,如果沒(méi)有,則會(huì)新生成一個(gè)session_id般堆,先存入cookie中的PHPSESSID中在孝,再生成一個(gè)sess_前綴文件。當(dāng)有寫入$SESSION的時(shí)候淮摔,就會(huì)往sess文件里序列化寫入數(shù)據(jù)私沮。當(dāng)讀取的session變量的時(shí)候,先會(huì)讀取cookie中的PHPSESSID噩咪,獲得session_id顾彰,然后再去找這個(gè)sess_sessionid文件,來(lái)獲取對(duì)應(yīng)的數(shù)據(jù)胃碾。由于默認(rèn)的PHPSESSID是臨時(shí)的會(huì)話涨享,在瀏覽器關(guān)閉后,會(huì)消失仆百,所以厕隧,我們重新訪問(wèn)的時(shí)候,會(huì)新生成session_id和sess_這個(gè)文件俄周。

好吁讨。session生成和保存將清楚了。我們?cè)賮?lái)看前面提到的幾個(gè)變量:

<pre style="font-family:Menlo, Monaco, Consolas, 'Courier New', monospace;font-size:14px;line-height:1.42857;color:rgb(51,51,51);border:1px solid rgb(204,204,204);">echo "SID: ".SID."
";

echo "session_id(): ".session_id()."
";

echo "COOKIE: ".$_COOKIE["PHPSESSID"];
</pre>

SID 是一個(gè)系統(tǒng)常量峦朗,SID包含著會(huì)話名以及會(huì)話 ID 的常量建丧,格式為 "name=ID",或者如果會(huì)話 ID 已經(jīng)在適cookie 中設(shè)定時(shí)則為空字符串波势,第一次顯示的時(shí)候輸出的是SID的值翎朱,當(dāng)你刷新的時(shí)候,因?yàn)橐呀?jīng)在cookie中存在尺铣,所以顯示的是一個(gè)空字符串拴曲。

session_id() 函數(shù)用來(lái)返回當(dāng)前會(huì)話的session_id,它會(huì)去讀取cookie中的name凛忿,也就是PHPSESSID值澈灼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子叁熔,更是在濱河造成了極大的恐慌委乌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件者疤,死亡現(xiàn)場(chǎng)離奇詭異福澡,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)驹马,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)除秀,“玉大人糯累,你說(shuō)我怎么就攤上這事〔岵龋” “怎么了泳姐?”我有些...
    開(kāi)封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)暂吉。 經(jīng)常有香客問(wèn)我胖秒,道長(zhǎng),這世上最難降的妖魔是什么慕的? 我笑而不...
    開(kāi)封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任阎肝,我火速辦了婚禮,結(jié)果婚禮上肮街,老公的妹妹穿的比我還像新娘风题。我一直安慰自己,他們只是感情好嫉父,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布沛硅。 她就那樣靜靜地躺著,像睡著了一般绕辖。 火紅的嫁衣襯著肌膚如雪摇肌。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天仪际,我揣著相機(jī)與錄音围小,去河邊找鬼。 笑死弟头,一個(gè)胖子當(dāng)著我的面吹牛吩抓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赴恨,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼疹娶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了伦连?” 一聲冷哼從身側(cè)響起雨饺,我...
    開(kāi)封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤钳垮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后额港,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體饺窿,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年移斩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肚医。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡向瓷,死狀恐怖肠套,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情猖任,我是刑警寧澤你稚,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站朱躺,受9級(jí)特大地震影響刁赖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜长搀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一宇弛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盈滴,春花似錦涯肩、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至症汹,卻和暖如春硫朦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背背镇。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工咬展, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瞒斩。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓破婆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親胸囱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子祷舀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • session原理總結(jié)[轉(zhuǎn)] 之前在學(xué)校的時(shí)候,只知道session與cookie的區(qū)別在于:session是保存...
    foolgry閱讀 563評(píng)論 0 1
  • 會(huì)話(Session)跟蹤是Web程序中常用的技術(shù),用來(lái)跟蹤用戶的整個(gè)會(huì)話裳扯。常用的會(huì)話跟蹤技術(shù)是Cookie與Se...
    chinariver閱讀 5,599評(píng)論 1 49
  • 為什么會(huì)出現(xiàn)Session: 用瀏覽器打開(kāi)一個(gè)網(wǎng)頁(yè)抛丽,用到的是HTTP協(xié)議。它是無(wú)狀態(tài)的饰豺,也就是說(shuō)這一次請(qǐng)求和上一次...
    40巨盜閱讀 776評(píng)論 0 3
  • 背景在HTTP協(xié)議的定義中亿鲜,采用了一種機(jī)制來(lái)記錄客戶端和服務(wù)器端交互的信息,這種機(jī)制被稱為cookie冤吨,cooki...
    時(shí)芥藍(lán)閱讀 2,355評(píng)論 1 17
  • 作者:晚晴幽草軒www.jeffjade.com/2016/10/31/115-summary-of-cookie...
    饑人谷_Dylan閱讀 1,222評(píng)論 0 51