PHP Session学习笔记
在web开发中,session是个非常重要的概念。Session一般译作会话,Session是一种基于HTTP协议的用以增强web应用能力的机制或者说一种方案,它不是单指某种特定的动态页面技术,而这种能力就是保持状态,也可以称作保持会话。
在许多动态网站的开发者看来,session就是一个变量,而且其表现像个黑洞,他只需要将东西在合适的时机放进这个洞里,等需要的时候再把东西取出来。这是开发者对session最直观的感受,但是黑洞里的景象或者说session内部到底是怎么工作的呢?
web应用是基于HTTP协议的,而HTTP协议是一种无状态协议。也就是说,用户从A页面跳转到B页面会重新发送一次HTTP请求,而服务端在返回响应的时候是无法获知该用户在请求B页面之前做了什么的。解决HTTP协议自身无状态的方式有cookie和session。二者都能记录状态,前者是将状态数据保存在客户端,后者则保存在服务端。
关于Cookie的介绍可以查看这两篇文章:Cookie简介或Cookie与Session的区别。今天主要讲的是Session的实现原理。
session的基本原理是服务端为每一个session维护一份会话信息数据,而客户端和服务端依靠一个全局唯一的标识来访问会话信息数据。用户访问web应用时,服务端程序决定何时创建session,创建session可以概括为三个步骤:
关于服务器如何将session的唯一标识发送个客户端,主要有两种方式:cookie和URL重写。Cookie与Session的区别中也有写到,这里不再详述。下面就开始说说PHP中的Session。
PHP中session方案包含的信息
由此,我们可见:当每个用户访问web, PHP的session初始化函数都会给当前来访用户分配一个唯一的session ID。并且在session生命周期结束的时候,将用户在此周期产生的session数据持久到session文件中。用户再次访问的时候,session初始化函数,又会从session文件中读取session数据,开始新的session生命周期。
php.ini中与Session相关的设置:
Session相关PHP函数和事件
通过session_destroy()注销session,除了结束session生命周期外,它还会删除sesion文件,但不会影响当前$_SESSION变量。即它会产生一个IO操作。
Session ID 是如何传递的?
session终究是因为管理用户状态信息才存在的。session id是用户表明身份的一种标识,就像入场券一样。用户一旦从被分配了session id之后的每次访问(http请求)都会携带这个session id给服务端,用于加载该用户的session数据。
用户端与服务端的web通信协议是http。而PHP通过http取得用户数据惯用的三种方法分别是:POST方法、GET方法还有Cookie。而PHP默认传递方法正是Cookie,也是最佳方法。只有在客户端不支持Cookie的时候(浏览器禁用了Cookie功能)才会通过GET方法来传递session_id,即通过在URL的query_string部分传递session id。
确定了传递方法,我们还有必要清楚一下session id的传递过程。用户通过浏览器访问网页,将URL输入地址栏回车,浏览器发出请求,在调用sockect send之前浏览器引擎会搜索有效的Cookies记录封装在http请求头的Cookie字段一同发送出去。服务端器接收到请求后,交给PHP处理。这时session初始化函数如果在$_COOKIE中没有找到以session_name()作为键值存储的生素(值为session id),则会以为用户是第一次访问web。作为第一次访问的用户,session初始化函数总会随机生成一个session_id并且通过setcookie()函数调用将新生成的session_id以”sesseson_name = session_id”的格式填入http响应头Set-Cookie字段,发送给客户端(这样接下来的请求,http请求头Cookie字段都会携带该Cookie记录给web服务器)。如果初始化函数发现用户端Cookies中已定义了存在$_COOKIE[‘sess_name’],则会加载与$_COOKIE[‘sess_name’]相对应的session文件($_COOKIE[‘sess_name’]就是session ID)。如果用户Cookie记录过期,则会被浏览器删除。之后的下一次请求,服务器会以为用户又是第一次访问,如此循环。
php.ini中Session ID 相关设置
Session的回收
我们知道session数据存放在服务端指定的session.save_path目录中,同时会在用户端存放一条Cookie用以记录分配给用户的session id。所以,session数据失效分服务端和客户端,要删除(回收)的对象也很清楚:
服务端:删除过期的session文件
PHP GC进程被启动以后,则会扫描session.save_path,找出过期的session,并删除该session文件。所谓,过期的session,是指操作系统当前时间与session文件最后访问时间之差大于session.gc_maxlifetime的话,该session认为是过期了。注意:有时候,你会发现,即便是文件过期了,有可能也没有被及时地删除掉。这是因为,每次session初始化的时候,并不会都启动PHP GC进程的,启动GC进程会大大降低php的运行效率。所有一个启动概率,这个概率由php.ini设定session.gc_probability / session.gc_divisor二个设置决定,默认概率是1%(1/1000)。这意味着,每1000次用户请求中,会启动1次PHP GC回收session文件。
客户端:删除过期session id的cookie记录
如果用户发现session已经过期,但是服务端的GC还没有启动,服务端可以手通过手工代码setcookie的方式要求用户端浏览器删除键值为session_name()的Cookie记录。这样,下回访问的时候,浏览器以为用户是第一次访问,并且重新给访问用户分配一个新的session_id。
php.ini中与session相关的设置
参考资料:PHP5 Session解析I 和 PHP5 Session解析II
建议继续学习:
- 浅析http协议、cookies和session机制、浏览器缓存 (阅读:16043)
- cookie窃取和session劫持 (阅读:13044)
- 你必须了解的Session的本质 (阅读:10295)
- 如何设置一个严格30分钟过期的Session (阅读:4425)
- 关于session和memcache的若干问题 (阅读:4337)
- 深入浅出Session攻击方式之一 – 固定会话ID (阅读:4472)
- Php session内部执行流程的再次剖析 (阅读:3696)
- (oracle)11g与10g中alter session权限差异 (阅读:3466)
- 深入理解PHP原理之Session Gc的一个小概率Notice (阅读:3349)
- 在Express和Socket.IO中使用session (阅读:2965)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:标点符 来源: 标点符
- 标签: Session
- 发布时间:2011-09-13 23:30:00
-
[61] ABTest 平台设计 - 如何进行流量分桶
-
[47] 如何拿下简短的域名
-
[44] 图书馆的世界纪录
-
[43] android 开发入门
-
[42] 【社会化设计】自我(self)部分――欢迎区
-
[42] Oracle MTS模式下 进程地址与会话信
-
[41] 流程管理与用户研究
-
[41] Twitter/微博客的学习摘要
-
[40] WEB系统需要关注的一些点
-
[40] Go Reflect 性能