session即会话,指一种持续性的、双向的连接。Session和Cookie在本质上没有什么区别,都是针对HTTP协议的局限性而提出的一种保持 客户端和服务器间保持会话连接状态的机制。(session的实现可以有多重,如URL重写、cookie,通过在cookie中存储sessionID 实现session的传递)SESSION的实现遵照RFC2965、RFC2109等文档的建议,文档中仅给出了关于实现SESSION和COOKIE 存储内容、原理等的建议,并没有对具体实现做硬性规定。
SESSION的基本概念及设置:
和Cookie一样,Session也
是一个通用标准,但在不同语言中实现有所不同。针对Web网站来说,Session指用户在浏览某个网站时,从进入网站到浏览器关闭这段时间内的会话。由
此可知,session实际上是一个特定的时间概念。使用Session可以在网站的上下文不同页面间传递变量、用户身份认证、程序状态记录等。常见的形
式就是配合Cookie使用,实现保存用户登录状态功能。和Cookie一样,session_start()必须在程序最开始执行,前面不能出现任何输
出内容,否则就会报错。(有时候,确实需要输出或者不能控制前面是否有输出,可以这么做:
ob_start();
session_start(); $_SESSION['user'] = $row[1];
ob_end_flush();
)
PHP的Session默认通过文件的方式实现,即存储在服务器端的Session文件,每个Session一个文件。一般文件名如下:
"sess_adbjsf2q1ass26oootd163sf84"后面是随机的32位编码的字符串。用编辑器打开它,一般内容结构如下:
变量名 | 类型 : 长度 : 值 ;
SESSION的工作原理:
HTTP
协议本身并不能支持服务器端保存客户端的状态信息。为了解决这一问题,于是引入了Session的概念,用来保存客户端的状态信息。Session通过一
个称为PHPSESSID的Cookie和服务器联系。Session是同过sessionID判断客户端用户的,即Session文件的文件名。
形
象的比喻解释Session的工作方式。假设Web Server是一个商场的存包处,一个顾客(HTTP
Request)第一次来到存包处,管理员把顾客的物品存放在某柜子里面(这个柜子就相当与Session),把一个号码牌交给这个顾客,作为取保凭证
(这个号码牌就是sessionID)。顾客下一次来的时候,要把号码牌交给存包处的管理员。管理员根据号码牌找到相应的柜子,根据顾客的请求,取出、更
换、添加柜子中的物品,存包处也可以让顾客的号码牌和号码牌对应的柜子失效。顾客的忘性很大,管理员在顾客回去的时候都要提醒顾客记住自己的号码牌。这
样,顾客下次来的时候,就会带着号码牌回来。
sessionID实际上实在客户端和服务器之间通过HTTP Request 和 HTTP
Response传来传去。sessionID按照一定的算法生成,必须包含在HTTP
Request里面,保证唯一性和随机性,以确保Session的安全。如果没有设置Session的生存周期,sessionID存储在内存中,关闭浏
览器后该ID自动注销;重新请求该页面,会重新注册一个SessionID。如果客户端没有禁用Cookie,Cookie在启动Session会话的时
候扮演的是存储sessionID和Session生存期的角色。可以手动设置Session的生存期,代码如下:
$liftTime = 24 * 3600;
setcookie(session_name(),session_id(),time() + $liftTme,"/");
也可以使用session_set_cookie_params()函数设置Session的生存周期。Session过期后,PHP会对其进行回收。因此,Session并非都随着浏览器的关闭而消失。
假
设客户端禁用Cookie怎么办?没办法,所有生存期都是浏览器的进程,只要关闭浏览器,再次请求页面又要重新注册Session。那么怎么传递
SessionID呢?通过URL或者隐藏表单。也可以配置php.ini中session.use_trans_sid设置为1,那么连接地址后就会自
己加SessionID。
Session以文件的形式存放在本地硬盘的一个目录中,所以当Session比较多时,磁盘读取文件就会比较
慢。经验告诉我们,当一个目录的文件数超过2000时,读写这个目录就会很慢。于是想到把Session分目录存放。php.ini中有一
项:session.save_path =
"N;MODE;/path"。这项设置可以给Session存放目录进行多级行多级散列,其中"N"表示要设置的目录级数,“MODE”表示目录的权限
属性,默认为600。windows基本不用设置。“/path”表示Session文件存放的根目录路径。以下为案例:
session.save_path = “2;/tmp/phpsession”
上述设置把/tmp/phpsession 目录作为php的Session文件存放目录,在该目录下进行两级目录散列,每一级目录跟别以0~9和a~z共36个字符作为目录名。(这里的子目录需要手工创建)
session
的回收是被动的,为了保证过期的session能被正常回收,可以修改php配置文件中的session.gc_divisor参数以提高回收率(太大了
会增加负载),或者设置一个变量判断是否过期。对了设置分级目录存储的Session,php不会自动 回收,需要自己实现其回收机制。