在客户端登录网站时,被访问的PHP页面可以使用session_start()打开session,这样就会产生客户端的唯一标识session id(可以通过session_id()获取/设置)。Session id可以通过两种方式保留在客户端。一种是自动加入到get的url中,或者POST的表单中,默认情况下变量名为PHPSESSID;另一种是通过COOKIE,,默认情况下,这个COOKIE的名字为PHPSESSID.
多服务器共享session
必须实现两个目标:一个是各个服务器对同一个客户端产生的session id必须相同,并且可通过同一个cookie进行传递,也就是说各个服务器必须可以读取同一个名为PHPSESSID的COOKIE;另一个是session数据的存储方式/位置必须保证各个服务器都能够访问到,简单地说就是多服务器共享客户端的session id,同时还必须共享服务器端的session数据。
实现方案
首先创建数据库表
Create table sess(
'sesskey' varchar(32) not null default '',
'expiry' bigint(20) not null default "0",
'data' longtext not null,
primary key ('sesskey'),
key 'expiry' ('expiry')
)type=MyISAM;
sesskey为SESSION ID,expiry为session过期时间,data用于保存session数据
默认情况下session数据是以文件方式保存,想要使用数据库方式保存,就必须重定义SESSION各个操作的处理函数。Php提供了session_set_save_handle()函数,可以用此函数自定义session处理过程,首先要先将session.save_handler改成user.在php中进行设置
Session_module_name('user')
Session_module_name()见帮助文档
面向对象的代码:
<?php
define('MY_SESS_TIME',3600);//SESSION生存时间
//类定义
Class My_Sess
{
function init()
{
$domain = '.inform.com';
ini_set("session.use_trans_sid",0);//不使用get/post变量方式
ini_set('session.gc_maxlifetime',MY_SESS_TIEME);//session生存时间
ini_set("session.user_cookies",1);//使用cookie保存session id的方式
ini_set("session.cookie_path","/");
ini_set("session.cookie_domain",$domian);//多主机共享保存session id的cookie
session_module_name('user');//将session.save_handler设置为user,默认为files
session_set_save_handler(//定义session各项操作所对应的方法名
array("My_Sess","open"),//对应于静态方法My_Sess::open()下同
array("My_Sess","close"),
array("My_Sess","read"),
array("My_Sess","write"),
array("My_Sess","destroy"),
array("My_Sess","gc"),
);
}
function open($save_path,$session_name)
{
return true;
}
function close()
{
global $MY_SESS_CONN;
if($MY_SESS_CONN)
{
$MY_SESS_CONN->Close();//关闭数据连接
}
return true;
}
funcion read($sesskey)
{
global $MY_SESS_CONN;
$sql = "select data from sess where sesskey=".$MY_SESS_CONN->qstr($sesskey)." and expiry>=".time();
$rs = &$MY_SESS_CONN->Execute($sql);
if($rs)
{
return '';
}
else
{
$v =$rs->fields[0];
$rs->close();
return $v;
}
return '';
}
function write($sesskey,$data)
{
global $MY_SESS_CONN;
$qkey = $MY_SESS_CONN->qstr($sesskey);
$expiry = time() + My_SESS_TIME;//设置过期时间
$arr = array(//写入session
"sesskey" => $qkey,
"expiry" => $expiry,
"data" => $data);
$MY_SESS_CONN->Replace("sess", $arr, "sesskey", $autoQuote = true);
return true;
}
function destroy($sesskey) {
global $MY_SESS_CONN;
$sql = "DELETE FROM sess WHERE sesskey=".$MY_SESS_CONN->qstr($sesskey);
$rs =& $MY_SESS_CONN->Execute($sql);
return true;
}
function gc($maxlifetime = null) {
global $MY_SESS_CONN;
$sql = "DELETE FROM sess WHERE expiry<".time();
$MY_SESS_CONN->Execute($sql); //由于经常性的对表 sess 做删除操作,容易产生碎片
$sql = "OPTIMIZE TABLE sess"; //所以在垃圾回收中对该表进行优化操作。
$MY_SESS_CONN->Execute($sql);
return true;
}
}
/使用 ADOdb 作为数据库抽象层。
require_once("adodb/adodb.inc.php");
//数据库配置项,可放入配置文件中(如:config.inc.php)。
$db_type = "mysql";
$db_host = "192.168.212.1";
$db_user = "sess_user";
$db_pass = "sess_pass";
$db_name = "sess_db";
//创建数据库连接,这是一个全局变量。
$GLOBALS["MY_SESS_CONN"] =& ADONewConnection($db_type);
$GLOBALS["MY_SESS_CONN"]->Connect( $db_host, $db_user, $db_pass, $db_name);
//初始化 SESSION 设置,必须在 session_start() 之前运行!!
My_Sess::init();
?>