Session原理简述

Session存在的意义,估计每个做web开发的人都是了解的,就为了解决HTTP是无状态协议所带来的问题,不多说了。这里主要想说的是服务端与客户端是如何利用session进行交互的。

工作流程

先看下面这幅流程图:

当用户第一次访问站点时,PHP会用session_start()函数为用户创建一个session ID,这就是针对这个用户的唯一标识,每一个访问的用户都会得到一个自己独有的session ID,这个session ID会存放在响应头里的cookie中,之后发送给客户端。这样客户端就会拥有一个该站点给他的session ID。

当用户第二次访问该站点时,浏览器会带着本地存放的cookie(里面存有上次得到的session ID)随着请求一起发送到服务器,服务端接到请求后会检测是否有session ID,如果有就会找到响应的session文件,把其中的信息读取出来;如果没有就跟第一次一样再创建个新的。

通常站点的退出功能,实际上就是调用一下session_destroy()函数(也有可能更复杂些),把该用户的session文件删除,再把用户的cookie清除。这样客户端和服务端就算没有联系了。

图中的红框部分就是一次完整的HTTP请求,因为HTTP是无状态的,所以一次请求完成后客户端和服务端就不再有任何关系了,谁也不认识谁。但由于一些需要(如保持登录状态等),必须让服务端和客户端保持联系,session ID就成了这种联系的媒介了。

客户端的工作

通过上面的分析我们可以知道session实际上是依赖与cookie的,当用户访问某一站点时,浏览器会根据用户访问的站点自动搜索可用的cookie,如果有可用的就随着请求一起发送到了服务端。每次接收到服务端的响应时又会更新本地的cookie信息。

当然也可以用GET方式来传递session ID,但不推荐用GET,这样不安全。

服务端的工作

由上面的流程图可以看到,服务端实际上是把产生的一些数据存放在了session文件中,该文件的名字就是”sess“加上session ID,这些文件的存放位置就是phpinfo()查到的session.savepath值。

由上图我们可以很清楚的看到,服务端和客户端保存着同样的session ID信息,这就是两者保持联系的钥匙。

反面影响

有好处必然也有坏处,session带来的最主要问题就是对性能的影响,可以想象一下,对于一个千万用户级的web站点,如果每个用户都保存session文件,那每次用户访问光寻找相应的session文件就要耗掉不少系统资源的。所以这时就要对session的存储做一些自定义的设定了,如分目录或哈希等等。除了保存到session文件,也可以抛弃PHP自带的session功能,自己实现session,将session信息存放到数据库当中,这样做最好对数据库进行一下缓存的设置了,不然对上千万的数据进行太频繁的检索,也是蛮耗资源的。

定时清除

客户端和服务端的这种联系必然是需要有时间的规定的,所以需要定期清除session。这个问题就需要在两方面考虑了,一个是清除服务端session文件,一个是清除客户端的cookie信息,因为两者都各保存着一半的信息。

PHP GC进程可以扫描session存放目录清除session文件,但这个进程是特别耗资源的,所以PHP默认是1%的几率在一个session启动时去清理一次过期的session,所以并不是说一个用户session过期了,他对应的session文件就马上被清除,99%的几率是没被清除的。这就需要我们程序员自己动手了。可以在session信息中存放一个过期时间,值为用户最后一次访问的时间。当用户一访问,就用当前时间减去上次访问时间看是否超时,如果超时了就删除相应session文件,并设置cookie的Expires属性为负值,使其客户端的cookie信息也过期,这样浏览器就自动把它删掉了。

PHP关于Session的常用函数

  • session_start(): 启动session,这个没什么说的了。根据session ID打开session文件,如果没有session ID就创建一个ID和对应的session文件
  • $SESSION[]:存放用户信息的全局数组,session文件中除了存放$SESSION中的数据实际也会存放其他的信息,如id等
  • sessionunset(): 清空$SESSION数组,它是把数组里的值清空了,而$SESSION这个变量还是存在的,和unset($SESSION)是完全不同的概念
  • sessioncommit():提交session数据并结束session,把$SESSION数据写到文件里并结束session。实际上当一个页面执行结束后,php会自动执行与这个函数相同的操作。所以这个函数也很少能用上
  • session_destroy():注销session,这个就是关闭session,并删除掉相应的session文件了。切断了客户端和服务端的联系。

原文发布于微信公众号 - php(phpdaily)

原文发表时间:2017-09-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏owent

atsf4g完整游戏工程示例

近期仍然在搭建完整的游戏服务器架构。基于atsf4g(asynchronously-tree server framework fo game)的完整解决方案终...

431
来自专栏开源优测

[快学Python3]INI文件读写

概述 ini是我们常见到的配置文件格式之一。 ini是微软Windows操作系统中的文件扩展名(也常用在其他系统)。 ini“初始化(Initial)”的缩写。...

2717
来自专栏Vamei实验室

Python应用01 原始Python服务器

之前我的Python教程中有人留言,表示只学Python没有用,必须学会一个框架(比如Django和web.py)才能找到工作。而我的想法是,掌握一个类似于框架...

19410
来自专栏北京马哥教育

十个免费的 Web 压力测试工具

本文列举了是十个免费工具,可以用来进行Web的负载/压力测试的。这样你就可以知道你的服务器以及你的WEB应用能够扛得住多少的并发量,以及网站性能。 0. Gr...

4946
来自专栏蛋未明的专栏

十个免费的 Web 压力测试工具(转)

1303
来自专栏熊二哥

快速入门系列--Log4net日志组件

Log4net是阿帕奇基金会的非常流行的开源日志组件,是log4j的.NET移植版本,至今已经有11年的历史,使用方便并且非常稳定,此外很重要的一点是其和很多开...

18410
来自专栏代码GG之家

android native 代码内存泄露 定位方案

android native 代码内存泄露 定位方案 ? java代码的内存定位,暂时我们先不关注。此篇文章,主要围绕c c++代码的内存泄露。 欢迎留言,交...

38110
来自专栏纯洁的微笑

springcloud(九):配置中心和消息总线

我们在springcloud(七):配置中心svn示例和refresh中讲到,如果需要客户端获取到最新的配置信息需要执行 refresh,我们可以利用webho...

34512
来自专栏菩提树下的杨过

silverlight:wcf双工通讯学习笔记

一直觉得SL中的wcf双工通讯方式有点鸡肋,如果是以http方式实现则效率太低,如果用SL4中的tcp方式实现,又跟socket太雷同,所以一直没去研究,不过这...

1895
来自专栏FreeBuf

内核漏洞利用:通过WARBIRD在Windows 10上提升权限

在这篇文章中,我想谈一谈通过基于Windows内核的exploit来提升权限。之所以没有使用像HackSys Extreme Vulnerable Window...

2298

扫描关注云+社区