如果网站访问量非常大,需要采用负载均衡技术搭载多台Web服务器协同工作,就需要进行Session同步处理。使用数据库处理Session会比使用NFS及SAMBA更占优势,可以专门建立一个数据库服务器存放Web服务器的Session信息,当用户不管访问集群中的哪个Web服务器,都会去这个专门的数据库,访问自己在服务器端保存的Session信息,以达到Session同步的目的。另外,使用数据库处理Session还可以给我们带来很多好处,比如统计在线人数等。如果mysql也做了集群,每个mysql节点都要有这张表,并且这张Session表的数据要实时同步
在使用默认的文件方式处理Session时,有3个比较重要的属性,分别是文件名称、文件内容及文件的修改时间:通过文件名称中包含的Session ID,用户可以找到自己在服务器端的Session文件;通过文件内容用户可以在各个脚本中存取$_session变量;通过文件的修改时间则可以清除所有过期的Session文件。所以使用数据表处理Session信息,也最少要有这三个字段(Session ID、修改时间、Session内容信息),当然如果考虑更多的情况,例如,用户改变了IP地址,用户切换了浏览器等,还可以再自定义一些其他字段。下面为Session设计的数据表结构包含5个字段,创建保存Session信息表session的SQL语句如下所示:
CREATE TABLE session(
sid CHAR(32) NOT NULL DEFAULT '',
update INT NOT NULL DEFAULT 0,
client_ip CHAR(15) NOT NULL DEFAULT '',
user_agent CHAR(200) NOT NULL DEFAULT '',
data TEXT,
PRIMARY KEY(sid)
);
<?php
class DBSession {
public static $pdo; //pdo的对象
public static $ctime; //当前时间
public static $maxlifetime; //最大的生存时间
public static $uip; //用户正在用的ip
public static $uagent; //用户正在用的浏览器
//开启和初使化使用的, 参数需要一个路
public static function start(PDO $pdo) {
self::$pdo = $pdo;
self::$ctime = time();
self::$maxlifetime = ini_get("session.gc_maxlifetime");
self::$uip = !empty($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : (!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "") );
filter_var(self::$uip, FILTER_VALIDATE_IP) && self::$uip = '';
self::$uagent = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "" ;
//注册过程, 让PHP自己处理session时,找这个函数指定的几个周期来完成
session_set_save_handler(
array(__CLASS__, "open"),
array(__CLASS__,"close"),
array(__CLASS__, "read"),
array(__CLASS__, "write"),
array(__CLASS__, "destroy"),
array(__CLASS__,"gc"));
session_start(); //开启会话
}
// 开启时, session_start()
public static function open($path