首先,cookie和session是什么关系?
他们的关系很简单,利用和被利用的关系。
话说,由于http协议的无状态特性,同一client两个不同的请求之间完全独立,没有很好的办法进行一些数据共享,于是乎,http协议里引入了cookie,在协议层面可以进行一些数据共享,其原理是在客户端的电脑开辟某个空间,然后把cookie数据放入这个空间(空间通过域名进行隔离)。每个请求的时候,都在请求头带上这个域名的所有cookie数据 (相同path)
但由于数据在客户端进行存储,所以很容易被修改,安全性难与保证。所以更好的办法,是把数据放到服务器端,称之为session, 那问题来了?服务端怎么知道不同的请求是来自于同一个client了。于是乎,我们就可以利用cookie,只放一个标识,然后在服务器端通过标识去打到相应的session数据。这样,你改了标识就没用了。
所以,session利用了cookie, 但cookie不是必需,万一cookie被client禁用了,其实我们还可以利用 get, post。只不过相应复杂了。
那这个cookie是不是凭空产生的么?
服务器端又是如何通过cookie是找到session的呢?
那我们通过session_start()为例,
一步一步解开神秘的面纱。
当你第一次访问某网站的时候,服务端调用session_start();
他的大概步骤是:
1) 看cookie里有没有相应session_id的数据。(如果没有定义only_use_cookie,会依次找get,post里的参数,直到找到没止)
2) 1里面没有找到的话,这时在服务端会通过算法生成session_id的数据(通过与user-agent, ip,时间相关参数,保证唯一性),然后通过response头里进行set cookie,
3) 浏览器发现response里有setcookie的定义,在相应的空间里进行cookie存储 (与服务器无关)。
4) 那么下一个请求时,就会cookie里带上这个session_id, 服务器通过cookie里的session_id里的值,去服务器的某个位置(默认是/tmp下,文件名叫sess_{session_id}),把session数据读出来,然后填充到$_SESSION中,至此session_start完成。
所以cookie里的session_id不是凭空产生的,是通过服务端种的。cookie和session相当于一个key=>val的映射关系
了解了这个步骤,你就可以自己实现任何语言的session_start了
延伸问题,你们自己思考:
1) 如何严格的定义session过期
2) session是如何gc的
3) 为什么php默认的file session 会有性能问题。
严格定义session过期解答:$_SESSION[‘timestamp‘] = time();
为什么php默认的file session 会有性能问题解答:创建/打开/关闭/删除文件当然会有性能问题,而且所有的session文件全部保存在一个目录中,session文件 数量多了后找一个文件也是会存在相当的性能问题。