http协议是WEB服务器与客户端(浏览器)相互通信的协议,它是一种无状态协议。所谓无状态,指的是不会维护http请求数据,http请求是独立的,非持久的。而越来越复杂的WEB应用,需要保存一些用户状态信息。这时候,Session这种方案应需而生。PHP从4.1开始支持Session管理。
自 PHP 4.2.3 起用php启动 (文件修改时间)来代替了 atime,也就是说如果浏览器带有该session对应的cookie 该cookie的存活期中 在gc_maxlifetime设置的时间 间隔内刷新浏览器 则该session “永远”不会失效。由此还可以通过setcookie(session_name(),session_id(),time()+N)
来控制session生命周期,一旦cookie失效浏览器就“瞎”了,因为http本身是“无状态”协议,必须通过cookie来维持身份。
session相关概念
1) session id
用户session唯一标识符,随机生成的一串字符串,具有唯一性,随机性。主要用于区分其它用户的session数据。用户第一次访问web页面的时候,php的session初始化函数调用会分配给当前来访用户一个唯一的ID,也称之为session_id。
2) session data
我们把需要通过session保存的用户状态信息,称为用户session数据,也称为session数据。
3) session file
php默认将session数据存放在一个文件里。我们把存放session数据的文件称为session文件。它由特殊的php.ini设置session.save_path指定session文件的存放路径,centos5.3操作系统,php5.1默认存放在/var/lib/php/session目录中。用户session文件的名称,就是以sess_为前缀,以session_id为结尾命名,比如session id为vp8lfqnskjvsiilcp1c4l484d3,那么session文件名就是sess_vp8lfqnskjvsiilcp1c4l484d3。
4) session lifetime
我们把初始化session开始,直到注销session这段期间,称为session生命周期,这样有助于我们理解session管理函数。
与session存储相关php.ini设置
1) session.save_handler = file
用于读取/回写session数据的方式,默认是files。它会让PHP的session管理函数使用指定的文本文件存储session数据。
2) session.save_path =“/var/lib/php/session”
指定保存session文件的目录,可以指定到别的目录,但是指定目录必须要有httpd守护进程属主(比如apache或www等)写权限,否则无法回存session数据。当指定目录不存在时,php session环境初始化函数是不会帮你创建指定目录的,所以需要你手工建立指定目录。
它还可以写成这样session.save_path =“N;/path” 其中N是整数。这样使得不是所有的session文件都保存在同一个目录中,而是分散在不同目录。这对于服务器处理大量session文件是很有帮助的。(注:目录需要自己手工创建)
3) session.auto_start = 0
如果启用该选项,用户的每次请求都会初始化session。我们推荐不启用该设置,最好通过session_start()显示地初始化session。
与session回收相关的php.ini设置
1)session.gc_probability和session.gc_divisor
由这二个函数决定了启用GC的概率,默认是1/1000。也就是说,每一千次用户请求中有一次会启动GC回收session。启动GC进程不宜过于频繁。上面的例子,我们可以看到,它会每次检查session.save_path目录下每个文件的状态。这样会降低php的执行效率。
2) session.gc_maxlifetime = 1440
设置session存活时间,单位是秒。每次GC启动后, 会通过stat得到session文件最后访问的unix时间,通过现在时间减去文件最后访问时间之间大于session.gc_maxlifetime,则会删除该文件。
Session 是如何来判断客户端用户
它是通过 Session ID 来判断的, Session ID就是那个 Session 文件的文件名,Session ID 是随机生成的,因此能保证唯一性和随机性,确保Session 的安全。一般如果没有设置 Session 的生存周期,则 Session ID 存储在内存中,关闭浏览器后该 ID 自动注销,重新请求该页面后,重新注册一个 Session ID。如果客户端没有禁用 Cookie,则 Cookie 在启动 Session 会话的时候扮演的是存储 Session ID 和 Session 生存期的角色。我们来手动设置 Session 的生存期:<?php
session_start();
// 保存一天
$lifeTime = 24 * 3600;
setcookie(session_name(), session_id(), time() + $lifeTime, "/");
?>
其实PHP5 Session还提供了一个函数 session_set_cookie_params(); 来设置PHP5 Session的生存期的,该函数必须在 session_start() 函数调用之前调用:<?php
// 保存一天
$lifeTime = 24 * 3600;
session_set_cookie_params($lifeTime);
session_start();
?>
1, PHP使用Cookie的方法传递session id。尽量不要使用GET方法传递session id,因为这样很不安全。
2, 可以通过setcookie()的方法,将客户端的session id的Cookie记录删除。
3, PHP GC进程由session初始化启动。但不是每一次用户请求都会被启动,它的启动概率默认是1/1000。过于频繁访问的网站,并发量大的网站,可减小PHP GC的启动频率。PHP GC回收session会降低php的执行效率。
4, 通过下面代码,优化session回收<?php
session_start();
if (isset($_SESSION['SESS_TIMEOUT'])) {
if ($_SERVER['REQUEST_TIME'] > $_SESSION['SESS_TIMEOUT']) {
setcookie(session_name(), session_id(), -1, '/');
session_unset();
session_destroy();
}
} else {
$_SESSION['SESS_TIMEOUT'] = $_SERVER['REQUEST_TIME'] + 3600;
}