php中session的理解

一.Session是什么
Session一般译作会话,牛津词典对其的解释是进行某活动连续的一段时间。从不同的层面看待session,它有着类似但不完全同样的含义。比方,在web应用的用户看来,他打开浏览器訪问一个电子商务站点,登录、并完毕购物直到关闭浏览器,这是一个会话。

而在web应用的开发人员开来。用户登录时须要创建一个数据结构以存储用户的登录信息。这个结构也叫做session。

因此在谈论session的时候要注意上下文环境。


二.Session因何而来?
我们知道http协议是WEBserver与client(浏览器)相互通信的协议,它是一种无状态协议。所谓无状态,指的是不会维护http请求数据,http请求是独立的,非持久的,即此次连接无法得到上次连接的状态。这样。用户从A页面跳转到B页面会又一次发送一次http请求。而服务端在返回响应的时候是无法获知该用户在请求B页面之前做了什么。随着网络技术的蓬勃发展,人们再也不满足于死板乏味的静态HTML,他们希望web应用能动起来,于是client出现了脚本和DOM技术,HTML里添加了表单,而服务端出现了CGI等动态技术。而正是这样的web动态化的需求,给HTTP协议提出了一个难题:一个无状态的协议如何才干关联两次连续的请求呢?也就是说无状态的协议如何才干满足有状态的需求呢?这时候。Session/ Cookie这样的方案应需而生。Cookie我们不多说。它是将信息存储于client的一种机制。
三.Session的原理
Session的基本原理是服务端为每个session维护一份会话信息数据,而client和服务端依靠一个全局唯一的标识(也就是sessionid)来訪问会话信息数据。用户訪问web应用时,服务端程序决定何时创建session。创建session为session生命周期的第一部分,能够概括为三个步骤:
1、 生成全局唯一标识符(sessionid)
2、 开辟数据存储空间。通常会在内存中创建对应的数据结构,但这样的情况下,系统一旦掉电,全部的会话数据就会丢失。假设是电子商务站点,这样的事故会造成严重的后果。

只是也能够写到文件中甚至存储在数据库或者缓存中,这样尽管会添加I/O开销,但session能够实现某种程度的持久化,并且更有利于session的共享。
3、 将session的全局唯一标示符发送给client
在client有了sessionid后就能够通过这个id訪问在创建session时开辟的数据存储空间,进而能够在这个存储空间进行存取数据了。
值得注意的是,在session生命周期内产生的数据并不会实时地写入server端session数据的存储空间,而是通过一个全局变量寄存在内存中。在session的生命周期结束时才会将数据写入到session的存储空间中。


那么什么时候session的生命周期结束呢?归纳起来有下面3点:
1、server会把长时间没有活动的Session从server内存中清除。此时Session便失效。


2、session会在页面生命周期结束的时候,自己主动结束当前没有终止的session生命周期。
3、调用session的销毁方法时。
从上面的说明能够看出,session能够主动的失效,也能够被动的失效。这给开发人员带来了更加灵活的使用方式。


四.Sessionid的传递
client和服务端之间的通信是通过sessionid建立联系的,那么sessionid是怎样传递的呢?用户端与服务端的web通信协议是http协议。而通过http取得用户数据惯用的三种方法各自是:POST方法、GET方法还有Cookie。而PHP默认传递方法正是Cookie,也是最佳方法。

仅仅有在client不支持Cookie的时候(比方:浏览器禁用了Cookie功能)才会通过GET或POST方法来传递sessionid,即通过在URL的query_string部分传递sessionid。

可是不建议使用GET方法传递參数,由于那样easy泄露信息。
五.集群系统中Session的应用
如今的大规模站点应用中,很多採用集群的形式,即站点有一台负载均衡server,该server负责将请求指向后端不同的server,这样就会产生一个问题,比方:用户A訪问第一个页面时将session存到了SERVER01server上,在用户訪问该站点的第二个页面时,因为负载均衡有可能将这次请求指向到SERVER02server上,可是SERVER02server并没有存储用户A的信息。这时就会出现用户明明在第一个页面已经登录了。但在訪问第二个页面的时候还须要等录的现象。


有一种方法能解决问题。就是在负载均衡的时候按ip进行哈希,即同一个ip来的请求我们都指向到后端的同一台server,这样在訪问的时候就能在同一台server上存取session了。

可是一般的站点不会这样做,由于假设按ip哈希的话,一旦在某台server挂了的话会导致1/n(n为后端server数量)的用户不能訪问该站点,这对于用户体验来讲是极其不好的。那么问题来了。怎样能做到使多台server都能訪问到用户所存的session呢?如今业内使用最多的方法就是集群的session共享机制,即将session存储在独立于server的第三方,比方数据库、cbase或者cookie中,这样在訪问的时候,全部的server都在这个第三方去存取数据。


归纳起来大体有三种详细的实现方案:
(1)client存储方案:把session加密后存在cookie中,每次session信息被写在client,然后经浏览器再次提交到server.即使两次请求在集群中的两台server上完毕,也能够到达session共享.这样的解决方法的长处是session信息不用存放在server端,大大减轻了server的压力.还有一个长处是一个session中的两次或多次请求能够在一个群集中的多个server上完毕,能够避免单点故障.眼下,淘宝是採用的这样的解决方式.
 这个方法可能比較陌生,但它在大型站点中还是比較普遍被使用。

原理是将全站用户的Session信息加密、序列化后以Cookie的方式,统一种植在根域名下(如:.host.com)。利用浏览器訪问该根域名下的全部二级域名站点时,会传递与之域名相应的全部Cookie内容的特性,从而实现用户的Cookie化Session 在多服务间的共享訪问。
 这个方法的长处无需额外的server资源;缺点是由于受http协议头长度的限制。仅可以存储小部分的用户信息。同一时候Cookie化的 Session内容须要进行安全加解密(如:採用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证),另外它也会占用一定的带宽资源,由于浏览器会在请求当前域名下不论什么资源时将本地Cookie附加在http头中传递到server。
(2)集中式session共享方案:提供一个群集保存session共享信息.其它应用统统把自己的session信息存放到session群集server组.当应用系统须要session信息的时候直接到session群集server上读取.这样的方式具有第一种方式的第二个长处. 
(3)session复制方案:配置负载均衡server,让用户的一个session在一个server完毕.定时的备份session信息到salve上面.一台serverdown掉后,通过均衡server透明把用户的请求转发到群集中的其它server上,此时须要从salve上读取备份的session信息.

 session是存储在server端的一些用户信息,存储方式默觉得存储在文件里(session.save_handler = files),存储路径为(session.save_path = "/letv/sessions")

六. Php中Session存取的相关介绍

    在php中session的起始创建为运行session_start();时,这段代码有这么几个功能:1)创建了$_SESSION变量(假设没有这段代码的话var_dump($_SESSION);时会显示NULL)2)     在指定的session.save_path文件夹中创建了一个sess_xxx(sessionid)的文件(假设之前没有这个文件)3)在client浏览器中创建了一个cookie,如图所看到的,这里的value即为sessionid

    然后我们能够使用$_SESSION变量进行一些操作了,比方赋值($Name = "this is test session";$_SESSION['Name'] = $Name;)、运算等等,在脚本运行结束后,server会将        $_SESSION中的变量序列化后存放到相应的文件里去,如图所看到的

   好,假设此时浏览器并没有关闭(由于关闭浏览器后,session即结束了生命周期),你能够打开一个新的脚本(例:add?xxx),在新的脚本中能够获取$_SESSION(记得首先一定要运行session_start();)为什么能获取到server中的值呢?它的运行过程应该是这种:

   在运行新的脚本的时候,请求中会带有浏览器中种的session的cookie值,如图

   在进行session_start();的时候会获取到传过来的sessionid,然后验证一下session的保存路径中有无sess_sessionid文件,假设有的话就将该文件里的内容拿出来,整理后存入$_SESSION变量中,假设没有的话就创建这个文件,同一时候将$_SESSION = array();



以上是个人对php中session的理解。欢迎拍砖~!

~

推荐有关php session的一篇极好的文章 :http://blog.163.com/lgh_2002/blog/static/4401752620105246517509/ 


posted @ 2017-05-04 20:12  clnchanpin  阅读(1070)  评论(1编辑  收藏  举报