2019-03-05

session()到底是做什么的

session是啥?

首先,我大致的知道,session是一次浏览器和服务器的交互的会话,会话是啥呢?就是我问候你好吗?你回恩很好。就是一次会话,那么对话完成后,这次会话就结束了,还有我也知道,我们可以将一个变量存入全部的$_SESSION['name']中,这样php的各个页面和逻辑都能访问到,所以很轻松的用来判断是否登陆。

这是我之前理解的session,当然也是对的,只是解释的太肤浅,理解的太表面了,面试官如果听到这样的答案其实是不太满意的。我参考了其他的很多资料,彻底理解清楚session。

在说session是啥之前,我们先来说说为什么会出现session会话,它出现的机理是什么?我们知道,我们用浏览器打开一个网页,用到的是HTTP协议,学过计算机的应该都知道这个协议,它是无状态的,什么是无状态呢?就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的。但是这种无状态的的好处是快速。

所以就会带来一个问题就是,我希望几个请求的页面要有关联,比如:我在www.a.com/login.php里面登陆了,我在www.a.com/index.php 也希望是登陆状态,但是,这是2个不同的页面,也就是2个不同的HTTP请求,这2个HTTP请求是无状态的,也就是无关联的,所以无法单纯的在index.php中读取到它在login.php中已经登陆了!

那咋搞呢?我不可能这2个页面我都去登陆一遍吧。或者用笨方法这2个页面都去查询数据库,如果有登陆状态,就判断是登陆的了。这种查询数据库的方案虽然可行,但是每次都要去查询数据库不是个事,会造成数据库的压力。

所以正是这种诉求,这个时候,一个新的客户端存储数据方式出现了:cookie。cookie是把少量的信息存储在用户自己的电脑上,它在一个域名下是一个全局的,只要设置它的存储路径在域名www.a.com下 ,那么当用户用浏览器访问时,php就可以从这个域名的任意页面读取cookie中的信息。所以就很好的解决了我在www.a.com/login.php页面登陆了,我也可以在www.a.com/index.php获取到这个登陆信息了。同时又不用反复去查询数据库。

虽然这种方案很不错,也很快速方便,但是由于cookie 是存在用户端,而且它本身存储的尺寸大小也有限,最关键是用户可以是可见的,并可以随意的修改,很不安全。那如何又要安全,又可以方便的全局读取信息呢?于是,这个时候,一种新的存储会话机制:session 诞生了。

我擦,终于把session是怎么诞生的给圆清楚了,不容易啊!!!

好,session 诞生了,从上面的描述来讲,它就是在一次会话中解决2次HTTP的请求的关联,让它们产生联系,让2两个页面都能读取到找个这个全局的session信息。session信息存在于服务器端,所以也就很好的解决了安全问题。

session的运行机制和是怎么保存的?

既然,它也是一种服务区存储数据的方式,肯定也是存在服务器的某个地方了。确实,它存在服务器的/tmp 目录下,这一点我们接下来慢慢讲。

我们先说下它的运行机制,是怎么分配的。我们主要用PHP中session的机制,其实各种语言都差不多。

如果这个时候,我们需要用到session,那我们第一步怎么办呢?第一步是开启session:

session_start();

这是个无任何返回值的函数,既不会报错,也不会成功。它的作用是开启session,并随机生成一个唯一的32位的session_id,类似于这样:

4c83638b3b0dbf65583181c2f89168ec

session的全部机制也是基于这个session_id,它用来区分哪几次请求是一个人发出的。为什么要这样呢?因为HTTP是无状态无关联的,一个页面可能会被成百上千人访问,而且每个人的用户名是不一样的,那么服务器如何区分这次是小王访问的,那次是小名访问的呢?所以就有了找个唯一的session_id 来绑定一个用户。一个用户在一次会话上就是一个session_id,这样成千上万的人访问,服务器也能区分到底是谁在访问了。

我们做个试验,看看,是不是这样的:

我们在php.iyangyi.com 域名下的a.php 页面中,输入如下代码:

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

我们访问一下a.php页面,看能输出什么?

image

我们看到居然还有一个警告。我们先一个一个的看。首先SID这个常量,我们没有给它赋值,它居然能有输出,其次session_id()这个系统方法是输出本次生成的session_id。最后$_COOKIE['PHPSESSIID'] 没有值,这个我们接下来说。

好,我们再次刷新这个页面,我们能看到什么?

image

奇怪的事情发生了。SID 没有值了,$_COOKIE['PHPSESSID']中有值了。而且,2次刷新,session_id 都是一样

的:bjvlo4p38cfqkr1hr7pe924ts3,实际情况下,只要不关闭网页,怎么刷新都是一样:

既然我们看到COOKIE中有值了,我们,打开firebug开看到底是什么:

image

而且这个PHPSESSID的过期时间是会话,什么意思呢?就是浏览器只要不关就一直不存,浏览器一关就过期,消失了。

好,我们关掉浏览器,重新打开a.php页面,看看有没有什么变化:

image

你看,是不是又回到当初第一次打开时候的样子。

OK,解惑的时候到了:

每次我们访问一个页面,如果有开启session,也就是有session_start() 时,就会自动生成一个session_id 来标注是这次会话的唯一ID,同时也会自动往cookie里写入一个名字为PHPSESSID的变量,它的值正是session_id,当这次会话没结束,再次访问的时候,服务器会去读取这个PHPSESSID的cookie是否有值有没过期,如果能够读取到,则继续用这个session_id,如果没有,就会新生成一个session_id,同时生成PHPSESSID这个cookie。由于默认生成的这个PHPSESSID cookie是会话,也就是说关闭浏览器就会过期掉,所以,下次重新浏览时,会重新生成一个session_id。

好,这个是session_id,就用来标识绑定一个用户的,既然session_id生成了。那么当我们往session里面写入数据,是如何保存的,答案是保存在服务器的临时目录里,根据php.ini的配置,我机子上的这个session是存在D:\wamp\tmp 目录里的。我们先说是存在这个目录下,然后待会将如何修改。

那么它是怎么存的呢?

同样也是用到session_id。session_id是32位的,服务器会用 sess_前缀 + session_id 的形式存在这个临时目录下,比如上面这个例子:

image

所以,每一次生成的session_id都会生成一个这样的文件,用来保存这次会话的session信息。

我们往session里写入些数据,来看看session是怎么往这个文件里写数据的,我们同样在a.php页面继续加上写入session的语句:

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

然后,我刷新页面,由于我并没有关闭页面,就这是说这次会话还没结束,那么肯定还会是同样的session_id : bjvlo4p38cfqkr1hr7pe924ts3

然后,我们 用编辑器打开它的存储文件sess_bgg20mcl86drbt3j08jg5h5h17这个文件,看看里面是啥?

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

是序列化的数据,我们肉眼也能读出来。当我们往$_SESSION全局变量里写数据时,它会自动往这个文件里写入。读取session的时候,也会根据session_id 找到这个文件,然后读取需要的session变量。

这个sess文件不会随着客户端的PHPSESSID过期,也一起过期掉,它会一直存在,出息GC扫描到它过期或者使用session_destroy()函数摧毁,我们在下面讲到session·回收的时候会说到。

我们大致总结下:

HTTP请求一个页面后,如果用到开启session,会去读cookie中的PHPSESSID是否有,如果没有,则会新生成一个session_id,先存入cookie中的PHPSESSID中,再生成一个sess_前缀文件。当有写入$SESSION的时候,就会往sess文件里序列化写入数据。当读取的session变量的时候,先会读取cookie中的PHPSESSID,获得session_id,然后再去找这个sess_sessionid文件,来获取对应的数据。由于默认的PHPSESSID是临时的会话,在浏览器关闭后,会消失,所以,我们重新访问的时候,会新生成session_id和sess_这个文件。

好。session生成和保存将清楚了。我们再来看前面提到的几个变量:

<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 是一个系统常量,SID包含着会话名以及会话 ID 的常量,格式为 "name=ID",或者如果会话 ID 已经在适cookie 中设定时则为空字符串,第一次显示的时候输出的是SID的值,当你刷新的时候,因为已经在cookie中存在,所以显示的是一个空字符串。

session_id() 函数用来返回当前会话的session_id,它会去读取cookie中的name,也就是PHPSESSID值。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • session原理总结[转] 之前在学校的时候,只知道session与cookie的区别在于:session是保存...
    foolgry阅读 562评论 0 1
  • 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Se...
    chinariver阅读 5,593评论 1 49
  • 为什么会出现Session: 用浏览器打开一个网页,用到的是HTTP协议。它是无状态的,也就是说这一次请求和上一次...
    40巨盗阅读 776评论 0 3
  • 背景在HTTP协议的定义中,采用了一种机制来记录客户端和服务器端交互的信息,这种机制被称为cookie,cooki...
    时芥蓝阅读 2,353评论 1 17
  • 作者:晚晴幽草轩www.jeffjade.com/2016/10/31/115-summary-of-cookie...
    饥人谷_Dylan阅读 1,222评论 0 51