您的位置:首页 > 编程语言 > PHP开发

PHP多台服务器跨域SESSION共享

2011-11-01 21:54 701 查看
稍微大一点的网站,通常都会有不只一个服务器,每个服务器运行着不同的功能模块或者不同的子系统,他们使用不同的二级域名,比如www.a.com、i.a.com、bbs.a.com。而一个整体性强的网站,用户系统是统一的,即一套用户名、密码在整个网站的各个子系统中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的,只需要在后端放个数据库服务器,各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题,就是用户在i.a.com登录之后,进入www.a.com时,仍然需要重新登录,基本的通行证的问题,映射到技术上,其实就是各个服务器之间如何实现共享
SESSION数据的问题。

为了解决这个问题,我们采用将SESSION的数据保存数据库的方式。关于PHPSESSION的扫盲这里就不在累赘。在默认情况下,各个服务器会各自分别对同一个客户端产生SESSIONID,如对于同一个用户浏览器,www.a.com系统产生的SESSIONID是a0211e9de3192ba6c22992d27a1b6a0a,而i.a.com生成的则是277003f262f0c366946a86a28ba431d8。另外,PHP的SESSION数据都是分别保存在本服务器的文件系统中。

想要共享SESSION数据,那就必须实现两个目标:www.a.com和i.a.com所产生的SESSIONID相同,并且可通过同一个COOKIE进行传递,也就是说各个服务器必须可以读取同一个名为PHPSESSID的COOKIE;另一个是SESSION数据必须存放在一个各个系统都能访问到的地方。简单地说就是多服务器共享客户端的
SESSIONID,同时还必须共享服务器端的SESSION数据。

第一个目标的实现其实很简单,只需要对COOKIE的域(domain)进行特殊地设置即可,默认情况下,COOKIE的域是当前服务器的域名/IP地址,而域不同的话,各个服务器所设置的COOKIE是不能相互访问的,如www.a.com的服务器是不能读写www.b.com服务器设置的COOKIE的。这里我们所说的同一网站的服务器有其特殊性,那就是他们同属于同一个一级域,如:www.a.com和i.a.com都属于域.a.com,那么我们就可以设置COOKIE的域为.a.com,这样
www.a.com、i.aaa.com等等都可以访问此COOKIE。PHP代码中的设置方法如下:

1
ini_set
(
'session.cookie_domain'
,
'.a.com'
);
这样各个系统共享同一客户端SESSIONID的目的就达到了,下面就是共享SESSION数据,我们就将SESSION数据放在数据库中,首先建立数据库表:

1
CREATE
TABLE
sessions
(
2
session_id
varchar
(32)
NOT
NULL
,
3
session_last_access
int
(10)
unsigned,
4
session_data
text,
5
PRIMARY
KEY
(session_id)
session_id为主键,保存SESSIONID,session_last_access是SESSION最后更新时间,session_data是SESSION数据。

PHP提供了session_set_save_handle()函数,可以用此函数自定义SESSION的处理过程,当然首先要先将session.save_handler改成user,可在PHP中进行设置:

接下来着重讲一下session_set_save_handle()函数,此函数有六个参数:

session_set_save_handler(stringopen,stringclose,stringread,stringwrite,stringdestroy,stringgc)

各个参数为各项操作的函数名,这些操作依次是:打开、关闭、读取、写入、销毁、垃圾回收。PHP手册中有详细的例子,详细代码如下:

view
source

print?

01
$gb_DBHOSTname
=
"127.0.0.1"
;
//主机的名称或是IP地址
02
$gb_DBname
=
"dbname"
;
//数据库名称
03
$gb_DBuser
=
"username"
;
//数据库用户名称
04
$gb_DBpass
=
"pwd"
;
//数据库密码
05
$gb_COOKIE_DOMAIN
=
'.a.com'
;
06
$SESS_DBH
=
""
;
07
$SESS_LIFE
=
get_cfg_var(
"session.gc_maxlifetime"
);
//得到session的最大有效期。
08
session_id();
//不使用
GET/POST变量方式
09
ini_set
(
'session.use_trans_sid'
,
0);
//设置垃圾回收最大生存时间
10
ini_set
(
'session.gc_maxlifetime'
,
13600);
//使用
COOKIE保存SESSIONID的方式
11
ini_set
(
'session.use_cookies'
,
1);
12
ini_set
(
'session.cookie_path'
,
'/'
);
//多主机共享保存
SESSIONID的COOKIE
13
ini_set
(
"session.cookie_domain"
,
$gb_COOKIE_DOMAIN
);
14
//将
session.save_handler设置为user,而不是默认的filessession_module_name('user');
15
function
sess_open(
$save_path
,
$session_name
)
{
16
global
$gb_DBHOSTname
,
$gb_DBname
,
$gb_DBuser
,
$gb_DBpass
,
$SESS_DBH
;
17
if
(!
$SESS_DBH
=
mysql_pconnect(
$gb_DBHOSTname
,
$gb_DBuser
,
$gb_DBpass
))
{
18
die
(
'MySQL
Error'
);
19
}
20
mysql_query(
"SET
character_set_connection=utf8,character_set_results=utf8,character_set_client=binary"
,
$SESS_DBH
);
21
if
(!mysql_select_db(
$gb_DBname
,
$SESS_DBH
))
{
22
die
(
'MySQL
Error'
);
23
}
24
return
true;
25
}
26
27
function
sess_close()
{
28
global
$SESS_DBH
;
29
//$SESS_DBH->Close();
30
return
true;
31
}
32
33
function
sess_read(
$key
)
{
34
global
$SESS_DBH
,
$SESS_LIFE
;
35
//
var_dump($SESS_DBH);
36
$qry
=
"select
session_datafromsessionswheresession_id='$key'"
;
37
$qid
=
mysql_query(
$qry
,
$SESS_DBH
);
38
//
var_dump($qid);
39
if
(list
(
$value
)
=mysql_fetch_row(
$qid
))
{
40
return
$value
;
41
}
42
return
false;
43
}
44
45
function
sess_write(
$key
,
$val
)
{
46
global
$SESS_DBH
,
$SESS_LIFE
;
47
$session_last_access
=
time();
48
$value
=
$val
;
49
$qry
=
"insert
intosessionsvalues('$key',$session_last_access,'$value')"
;
50
$qid
=
mysql_query(
$qry
,
$SESS_DBH
);
51
if
(!
$qid
)
{
52
$qry
=
"update
sessionssetsession_last_access=$session_last_access,session_data='$value'wheresession_id='$key'"
;
53
$qid
=
mysql_query(
$qry
,
$SESS_DBH
);
54
}
55
return
$qid
;
56
}
57
58
function
sess_destroy(
$key
)
{
59
global
$SESS_DBH
;
60
$qry
=
"delete
fromsessionswheresession_id='$key'"
;
61
$qid
=
mysql_query(
$qry
,
$SESS_DBH
);
62
return
$qid
;
63
}
64
65
function
sess_gc(
$maxlifetime
)
{
66
global
$SESS_DBH
;
67
$old
=
time()-
$maxlifetime
;
68
$old
=
mysql_real_escape_string(
$old
);
69
$qry
=
"delete
fromsessionswheresession_last_access<"
.
$old
;
70
$qid
=
mysql_query(
$qry
,
$SESS_DBH
);
71
return
mysql_affected_rows(
$SESS_DBH
);
72
}
73
session_module_name();
74
session_set_save_handler(
"sess_open"
,
"sess_close"
,
"sess_read"
,
"sess_write"
,
"sess_destroy"
,
"sess_gc"
);
75
session_start();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: