【PHP基础知识】——Session的详解与使用

一、前言

        之前的文章已经介绍了Cookie可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,这无形地增加了客户端与服务端的数据传输量,为了解决这个问题,Session就出现了。

二、概念

Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
相比于保存在客户端的Cookie,Session将用户交互信息保存在了服务器端,使得同一个客户端每次和服务端交互时,不需要每次都传回所有的Cookie值,而是只要传回一个ID,这个ID是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样就实现了一个ID就能在服务器取得所有的用户交互信息


三、Session的工作流程

1、session的创建:session是在客户端与服务器交互的过程中,由服务器创建的,并且会返回一个session的Id给客户端,一个会话只能有一个session对象;
2、在此后的交互过程中,客户端在请求中带上这个ID;
3、服务器可根据此Session ID获取到对应的保存在服务器内存中的session内容,以便于识别用户并提取用户信息。

                     【PHP基础知识】——Session的详解与使用

             (图片来自于http://blog.csdn.net/happyguys12345/article/details/74910595)

注:一般情况下客户端session的ID都是通过Cookie的方式与服务器交互的,对于客户端禁用了Cookie的情况,可以通过在请求的Url中带上这个Session ID达到使用Session的目的。(也有一些在页面表单隐藏字段添加session id的,但是需要请求有提交表单的行为时才可实现session交互)

四、Session的生命周期

Session在以下情况会被删除失效:
1、Session超时:超时指的是连续一定时间服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间;
2、程序调用方法主动销毁session;
3、服务器关闭或服务停止。


五、Session的作用范围

一般来说,每次请求不同的域都会新创建一个session:

对于多标签的浏览器来说,在一个浏览器窗口中,多个标签同时访问一个页面,session是一个。

对于多个浏览器窗口之间,同时或者相隔很短时间访问一个页面,session是多个的,和浏览器的进程有关。

对于一个同一个浏览器窗口,直接录入url访问同一应用的不同资源,session是一样的。

比如PHP写的服务端,每次打开同一个域名网站的页面都是一样的session,在多个标签里面也是一样;但在多个窗口就是不一样的(可能有些浏览器不是),访问不同的域也是不一样的,除非做了Session同步机制。

六、PHP操作Session方法

php的session默认情况下是使用客户端Cookie。当客户端的Cookie被禁用时,会自动通过URL的Query_String传递。 

(必须在php.ini中做以下配置:

session.use_trans_sid=1   //是否开启url传递PHPSESSION ID
session.use_only_cookies=0 //是否只允许使用Cookie 传递PHPSESSION ID
session.use_cookies=1 //是否开启Cookie传递PHPSESSION ID

需要保证服务器有session.save_path路径的必要权限。
)


1、session创建:在PHP中创建Session是用session_start()方法,同Cookie一样,必须将这个函数置于最先,而且在它之前不能有任何输出,否则会报错。同理可以用之前文章介绍过的输出缓冲的方法避免。

2、清空session:session_destroy()方法,此函数没有参数,且返回值均为true。
3、获取Session:PHP中获取session用$_SESSION[$name]变量获取,该变量在接收到请求时会自动获取到请求里面带有的Session id,并以数组的格式提取保存着该ID所带有的在服务器端的session数据(session的数据也是采用Key/Value的格式,value格式可支持多种);
4、Session值的修改更新:

可直接通过给$_SESSION[$name]变量赋值的格式更新session值,并且可以立即生效。

【PHP基础知识】——Session的详解与使用

七、实际应用中session存在的问题与不足

1、为了弥补http协议的无状态的特点,服务端会占用一定的内存和cpu用来存储和处理session计算的开销,在大流量大访问量的网站中,这会导致大量的占用服务器内存和计算速度
2、有些高访问量的站点,需要部署多个服务器,多台服务器对外提供的服务是等价的,这样可以减少每台服务器的压力,但是同一个用户的多次请求可能会访问到多台服务器,每台服务器的同一个Session ID必须对应同一个Session内容,这就需要Session在多台服务器之间实现同步
3、每个用户在每台服务器之间的Session ID都应该标识用户自己,所以多个服务器之间的不同session必须是相互独立的


八、Session同步的方案

多台服务器之间必须共享session,所以session同步到各个服务器的方式就是把session保存起来,让各个服务器都可以访问到这个保存的地方;可以保存到文件、数据库、内存等,由于文件和数据库是IO读写,效率比较低,所以目前最好的方案是将Session保存在内存中。
很多大型企业采用的方案是在单独的缓存服务器如memcache或者Redis里面保存Session,同步到各个服务器这种方案。


当然Session还有很多值得我们学习和探讨的问题,例如:
1、Session 存储的多元化;
2、Session 配置的动态修改;
3、Session 加密 key 的定期修改。