关闭

php中session的理解

556人阅读 评论(0) 收藏 举报
分类:

一.Session是什么
Session一般译作会话,牛津词典对其的解释是进行某活动连续的一段时间。从不同的层面看待session,它有着类似但不全然相同的含义。比如,在web应用的用户看来,他打开浏览器访问一个电子商务网站,登录、并完成购物直到关闭浏览器,这是一个会话。而在web应用的开发者开来,用户登录时需要创建一个数据结构以存储用户的登录信息,这个结构也叫做session。因此在谈论session的时候要注意上下文环境。
二.Session因何而来?
我们知道http协议是WEB服务器与客户端(浏览器)相互通信的协议,它是一种无状态协议。所谓无状态,指的是不会维护http请求数据,http请求是独立的,非持久的,即此次连接无法得到上次连接的状态。这样,用户从A页面跳转到B页面会重新发送一次http请求,而服务端在返回响应的时候是无法获知该用户在请求B页面之前做了什么。随着网络技术的蓬勃发展,人们再也不满足于死板乏味的静态HTML,他们希望web应用能动起来,于是客户端出现了脚本和DOM技术,HTML里增加了表单,而服务端出现了CGI等动态技术。而正是这种web动态化的需求,给HTTP协议提出了一个难题:一个无状态的协议怎样才能关联两次连续的请求呢?也就是说无状态的协议怎样才能满足有状态的需求呢?这时候,Session/ Cookie这种方案应需而生。Cookie我们不多说,它是将信息存储于客户端的一种机制。
三.Session的原理
Session的基本原理是服务端为每一个session维护一份会话信息数据,而客户端和服务端依靠一个全局唯一的标识(也就是sessionid)来访问会话信息数据。用户访问web应用时,服务端程序决定何时创建session。创建session为session生命周期的第一部分,可以概括为三个步骤:
1、 生成全局唯一标识符(sessionid)
2、 开辟数据存储空间。一般会在内存中创建相应的数据结构,但这种情况下,系统一旦掉电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库或者缓存中,这样虽然会增加I/O开销,但session可以实现某种程度的持久化,而且更有利于session的共享;
3、 将session的全局唯一标示符发送给客户端
在客户端有了sessionid后就可以通过这个id访问在创建session时开辟的数据存储空间,进而可以在这个存储空间进行存取数据了。
值得注意的是,在session生命周期内产生的数据并不会实时地写入服务器端session数据的存储空间,而是通过一个全局变量寄存在内存中,在session的生命周期结束时才会将数据写入到session的存储空间中。
那么什么时候session的生命周期结束呢?归纳起来有以下3点:
1、服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。
2、session会在页面生命周期结束的时候,自动结束当前没有终止的session生命周期。
3、调用session的销毁方法时。
从上面的说明可以看出,session可以主动的失效,也可以被动的失效,这给开发者带来了更加灵活的使用方式。
四.Sessionid的传递
客户端和服务端之间的通信是通过sessionid建立联系的,那么sessionid是如何传递的呢?用户端与服务端的web通信协议是http协议。而通过http取得用户数据惯用的三种方法分别是:POST方法、GET方法还有Cookie。而PHP默认传递方法正是Cookie,也是最佳方法。只有在客户端不支持Cookie的时候(比如:浏览器禁用了Cookie功能)才会通过GET或POST方法来传递sessionid,即通过在URL的query_string部分传递sessionid。但是不建议使用GET方法传递参数,因为那样容易泄露信息。
五.集群系统中Session的应用
现在的大规模网站应用中,许多采用集群的形式,即网站有一台负载均衡服务器,该服务器负责将请求指向后端不同的服务器,这样就会产生一个问题,比如:用户A访问第一个页面时将session存到了SERVER01服务器上,在用户访问该网站的第二个页面时,由于负载均衡有可能将这次请求指向到SERVER02服务器上,但是SERVER02服务器并没有存储用户A的信息,这时就会出现用户明明在第一个页面已经登录了,但在访问第二个页面的时候还需要等录的现象。
有一种方法能解决这个问题,就是在负载均衡的时候按ip进行哈希,即同一个ip来的请求我们都指向到后端的同一台服务器,这样在访问的时候就能在同一台服务器上存取session了。但是一般的网站不会这样做,因为如果按ip哈希的话,一旦在某台服务器挂了的话会导致1/n(n为后端服务器数量)的用户不能访问该网站,这对于用户体验来讲是极其不好的。那么问题来了,如何能做到使多台服务器都能访问到用户所存的session呢?现在业内使用最多的方法就是集群的session共享机制,即将session存储在独立于服务器的第三方,比如数据库、cbase或者cookie中,这样在访问的时候,所有的服务器都在这个第三方去存取数据。
归纳起来大体有三种具体的实现方案:
(1)客户端存储方案:把session加密后存在cookie中,每次session信息被写在客户端,然后经浏览器再次提交到服务器.即使两次请求在集群中的两台服务器上完成,也可以到达session共享.这种解决方法的优点是session信息不用存放在服务器端,大大减轻了服务器的压力.另一个优点是一个session中的两次或多次请求可以在一个群集中的多个服务器上完成,可以避免单点故障.目前,淘宝是采用的这种解决方案.
 这个方案可能比较陌生,但它在大型网站中还是比较普遍被使用。原理是将全站用户的Session信息加密、序列化后以Cookie的方式,统一种植在根域名下(如:.host.com),利用浏览器访问该根域名下的所有二级域名站点时,会传递与之域名对应的所有Cookie内容的特性,从而实现用户的Cookie化Session 在多服务间的共享访问。
 这个方案的优点无需额外的服务器资源;缺点是由于受http协议头长度的限制,仅能够存储小部分的用户信息,同时Cookie化的 Session内容需要进行安全加解密(如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证),另外它也会占用一定的带宽资源,因为浏览器会在请求当前域名下任何资源时将本地Cookie附加在http头中传递到服务器。
(2)集中式session共享方案:提供一个群集保存session共享信息.其他应用统统把自己的session信息存放到session群集服务器组.当应用系统需要session信息的时候直接到session群集服务器上读取.这种方式具有第一种方式的第二个优点. 
(3)session复制方案:配置负载均衡服务器,让用户的一个session在一个服务器完成.定时的备份session信息到salve上面.一台服务器down掉后,通过均衡服务器透明把用户的请求转发到群集中的其他服务器上,此时需要从salve上读取备份的session信息.

 session是存储在服务器端的一些用户信息,存储方式默认为存储在文件中(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)在客户端浏览器中创建了一个cookie,如图所示,这里的value即为sessionid

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

   好,如果此时浏览器并没有关闭(因为关闭浏览器后,session即结束了生命周期),你可以打开一个新的脚本(例:add?xxx),在新的脚本中可以获取$_SESSION(记得首先一定要执行session_start();)为什么能获取到服务器中的值呢?它的执行过程应该是这样的:

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

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



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

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


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:36239次
    • 积分:767
    • 等级:
    • 排名:千里之外
    • 原创:42篇
    • 转载:3篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论