php多台服务器跨域session共享

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

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

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

1ini_set('session.cookie_domain', '.a.com');

这样各个系统共享同一客户端 SESSION ID 的目的就达到了,下面就是共享SESSION数据,我们就将SESSION数据放在数据库中,首先建立数据库表:

1CREATE 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为主键,保存SESSION ID ,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 ( string open, string close, string read, string write, string destroy, string gc )
各个参数为各项操作的函数名,这些操作依次是:打开、关闭、读取、写入、销毁、垃圾回收。PHP 手册中有详细的例子,详细代码如下:

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 变量方式
09ini_set('session.use_trans_sid', 0); //设置垃圾回收最大生存时间
10ini_set('session.gc_maxlifetime', 13600); //使用 COOKIE 保存 SESSION ID 的方式
11ini_set('session.use_cookies', 1);
12ini_set('session.cookie_path', '/'); //多主机共享保存 SESSION ID 的 COOKIE
13ini_set("session.cookie_domain", $gb_COOKIE_DOMAIN);
14//将 session.save_handler 设置为 user,而不是默认的 files session_module_name('user');
15function 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 
27function sess_close() {
28    global $SESS_DBH;
29    //$SESS_DBH->Close();
30    return true;
31}
32 
33function sess_read($key) {
34    global $SESS_DBH, $SESS_LIFE;
35//      var_dump($SESS_DBH);
36    $qry = "select session_data from sessions where session_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 
45function sess_write($key, $val) {
46    global $SESS_DBH, $SESS_LIFE;
47    $session_last_access = time();
48    $value = $val;
49    $qry = "insert into  sessions values('$key',$session_last_access,'$value')";
50    $qid = mysql_query($qry, $SESS_DBH);
51    if (!$qid) {
52        $qry = "update sessions set session_last_access=$session_last_access, session_data='$value' where session_id='$key' ";
53        $qid = mysql_query($qry, $SESS_DBH);
54    }
55    return $qid;
56}
57 
58function sess_destroy($key) {
59    global $SESS_DBH;
60    $qry = "delete from sessions where session_id = '$key'";
61    $qid = mysql_query($qry, $SESS_DBH);
62    return $qid;
63}
64 
65function sess_gc($maxlifetime) {
66    global $SESS_DBH;
67    $old = time() - $maxlifetime;
68    $old = mysql_real_escape_string($old);
69    $qry = "delete from sessions where session_last_access < " . $old;
70    $qid = mysql_query($qry, $SESS_DBH);
71    return mysql_affected_rows($SESS_DBH);
72}
73session_module_name();
74session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
75session_start();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
class Session { //mysql的主机地址 const db_host = "localhost"; //需要第三方指定ip地址 //数据库用户名 const db_user = "root"; //需要第三方指定自己的用户名 //数据库密码 const db_pwd = ""; //需要第三方指定自己的库据库密码 //数据库 const db_name = "thinkphp"; //需要第三方指定数据库 //数据库表 const db_table = "tbl_session"; //需要第三方指定数据表 //mysql-handle private $db_handle; //session-lifetime private $lifeTime; function open($savePath, $sessName) { // get session-lifetime $this--->lifeTime = get_cfg_var("session.gc_maxlifetime"); // open database-connection $db_handle = @mysql_connect(self::db_host, self::db_user, self::db_pwd); $dbSel = @mysql_select_db(self::db_name, $db_handle); // return success if(!$db_handle || !$dbSel) return false; $this->db_handle = $db_handle; return true; } function close() { $this->gc(ini_get('session.gc_maxlifetime')); // close database-connection return @mysql_close($this->db_handle); } function read($sessID) { // fetch session-data $res = @mysql_query("SELECT session_data AS d FROM ".self::db_table." WHERE session_id = '$sessID' AND session_expires > ".time(), $this->db_handle); // return data or an empty string at failure if($row = @mysql_fetch_assoc($res)) return $row['d']; return ""; } function write($sessID, $sessData) { // new session-expire-time $newExp = time() + $this->lifeTime; // is a session with this id in the database? $res = @mysql_query("SELECT * FROM ".self::db_table." WHERE session_id = '$sessID'", $this->db_handle); // if yes, if(@mysql_num_rows($res)) { // ...update session-data @mysql_query("UPDATE ".self::db_table." SET session_expires = '$newExp', session_data = '$sessData' WHERE session_id = '$sessID'", $this->db_handle); // if something happened, return true if(@mysql_affected_rows($this->db_handle)) return true; } else // if no session-data was found, { // create a new row @mysql_query("INSERT INTO ".self::db_table." ( session_id, session_expires, session_data) VALUES( '$sessID', '$newExp', '$sessData')", $this->db_handle); // if row was created, return true if(@mysql_affected_rows($this->db_handle)) return true; } // an unknown error occured return false; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值