实现多域名下共用一个SESSION

要实现多域名共享session,首先就得了解SESSION的运行机制。基本概念我就不说了。
session是这样运行的:
用户A访问站点Y,如果站点Y执行了session_start();(以下假定session_start()总是存在)那么会产生一个 session_id,这个session id一般会以COOKIE的形式保存到用户A(我们可以通过在php.ini里设置session.use_only_cookies为1,强制SESSION ID必须以COOKIE传递。)。这时候SESSION ID表现为$_COOKIE[’PHPSESSID’];(PHPSESSID可用session_name()函数来修改)
用户A接着访问,这个session id($_COOKIE[’PHPSESSID’])就会在A每次访问Y的时候传送到站点Y。
在站点Y上,会有这么一个目录,是用来保存SESSION的实际数据的。站点Y接收到session id,然后通过session id,来获得与SESSION数据的关联,并返回SESSION数据。
可能聪明的你已经想到了,既然服务器端和客户端之间的SESSION是通过一个SESSION ID来联系,并且SESSION数据是以普通文件的形式保存在一个特定的文件夹里。
那么我们要实现不同域名,只需要满足以下两个条件:
[color=Red]1)不同域名的SESSION数据目录统一到一起,或者同步更新。
2)对同一个客户,使用统一的一个SESSION ID [/color]
[color=Green]第一个条件的实现。
如果是同一台服务器,就不需要进行任何设置了。
如果是集群/分布式的,那么我想也不需要我来说了。。能做分布式应用的,在目录共享方面的经验应该比我丰富。我也没有进行过多服务器的测试,主客观条件的原因都有。
我在这里主要是想说一下第二个条件――使不同的域名,拥有统一的SESSION ID。
那我们应该怎么统一呢?
首先必须在不同域名之间传递这个SESSION ID,且由于 cookie必须是针对域名的,所以传递动作是由客户端来完成。如果传递过程不是由客户端来完成,那么接受传递的域名就不知道针对的是哪个客户。
其次就是修改接受传递的域名下的SESSION ID。[/color]
如何传递:
HTML里,我们可以使用很多种方法。例如
iframe

或者.js

或者是一个img html元素

只要能调用某个地址,就行。
在wml里,由于wml script的特点,我们无法使用script这样的形式来调用,而wml里也没iframe..但是我们还是可以通过img来实现传递的。
如何修改:
既然SESSION ID一般情况下是通过COOKIE来传递,那么我们只需要通过传递$_COOKIE[’PHPSESSID’];即可。但是如果PHPSESSID被session_name改变了,我们又得修改setcookie中的PHPSESSID..这样就会变得很麻烦。。所以我们可以选择一个session特有的[color=Red]函数session_id来修改$_COOKIE[’PHPSESSID’];[/color]
需要注意的几点:
[color=Red]如果session.use_only_cookies为0(PHP默认),那么session id有可能会以url或其他形式传递 [/color]
[color=Red]session_id()和session_name必须在session_start()前使用 [/color]
以下是我写的一个简单的实现多域名的类。如果上面的看不太明白,可以看看我的这个多域名类。这个类是在HTML下以iframe形式实现的。
class mdSession
{
/*

使用:
服务器A,服务器B,在A的index.php登陆,在B里建立一个接收SESSION的文件,例如ses_get.php
A的index.php做如下修改
最开始加上session_start();
里,任意一个地方写上:mdSession::_set('B/ses_get.php')
而ses_get.php则在开头写上mdSession::_get();
@作者:[email protected] http://www.sacredmagic.51.com/
function mdSession()
{

}
function set($urls)
{
if (!is_array($urls))
{
$urls=array($urls);
}
foreach ($urls as $value)
{
echo '';
}
return true;
}
function get()
{
session_id($_SERVER['QUERY_STRING']);
session_start();
return true;
}
function _set($urls)
{
$obj=new mdSession();
return $obj->set($urls);
}
function _get()
{
$obj=new mdSession();
return $obj->get();
}
}
?>#2楼发布者:webptr时间:2007-09-26 11:05:46
      在很多时候,我们需要跟踪浏览者在整个网站的活动,对他们身份进行自动或半自动的识别(也就是平时常说的网站登陆之类的功能),这时候,我们常采用一组变量来"追随"访客。实现变量"追随"有很多种方法,比较用得多的是cookie和session。下面我们用时下很流行的PHP为大家讲解一下它们的使用。
一.Cookie的使用
  Cookie是网站保存在浏览器客户端的信息,也就是说保存在访客的机器里的变量,一般随着HTTP 头发送到客户端。在Cookie生效之后及失效之前,客户每次发出页面请求的时候,都会把Cookie一块发送到服务器,只要我们针对它进行相应的处理,就可以实现变量"追随"。
1. 设置一个Cookie变量
  设置一个Cookie变量,PHP使用的函数是:
int setcookie(string name, string value, int expire,
string path, string domain, int secure);

  其中name是Cookie变量名称标识,你在PHP中将可以象使用普通变量名一样来用它引用Cookie变量。value是Cookie变量的初始值,expire 表示该Cookie变量的有效时间;path 为该Cookie变量的相关路径;domain 表示Cookie变量的网站;secure 则需在 https 的安全传输时才有效。
  例如我们要设置一个变量username,它的值是字符串"bluewind",我们可以这么写代码:
setcookie ("username","bluewind"); //这两个参数是setcookie必要的。

  我们还想给这个变量设置有效时间来限制操作超时等,比如说10分钟:
setcookie ("username","bluewind", 600000); //有效时间的单位是毫秒。

  注意:setcookie和header函数一样,需要放在任何能向客户端输出的语句之前。
2. 销毁一个变量
  销毁Cookie变量只要将它的value设为空("")就可以了,如想销毁上面那个变量只要再写一次:
setcookie ("username" ,"");

  就可以了。这常用作安全退出之用。
3. Cookie的有效范围和生存期
  Cookie的有效范围(也就是说在这个范围的页面都能得到这个Cookie变量)默认的是该目录及其子目录,当然你可以用setcookie的 path和domain参数进行修改。如果你不对cookie的expire进行设置(参见1. 设置一个Cookie变量中的例子),那么当你离开网站的页面,cookie也同时得到自动销毁。
  http://www.netscape.com/newsref/std/cookie_spec.html是 cookie 原创者 Netscape 所提供的完整介绍信息。
二,session的使用
  session变量,也就是会话级变量,是访客在整个和网站交互的过程中都存在的公有变量。在客户端不支持有可能不支持cookie的时候(比如 linux下的lynx......呵呵,惨了点),我们为了保证数据正确安全,就需要采用session变量。Session在各种网页语言中的实现方式不一样,PHP在4.0后也开始支持它了。首先,让我们来看看一个简单的例子:
test.php
-----------
session_start();
session_register(var); //注册变量var
$var="这是SESSION变量的值"; //var变量已经被作为session变量
?>
test1.php
------
session_start();
session_register(var);
echo $var; //输出:"这是SESSION变量的值"
?>

1、初始一个session
  如果PHP的设置自动session并没有开启的话,需要使用session_start()函数来初始化一个session,这个函数的用法如下:
: boolean session_start(void);

  它的作用是初始化一个新的 Session,若该客户已在 Session 之中,则连上原 Session。本函数没有参数,且返回值均为 true。
2、在session中注册一个变量
  你要在session保存的变量都必须使用下列函数对变量进行注册:
boolean session_register(string name);

  本函数在全局变量中增加一个变量到目前的 Session 之中。参数 name 即为欲加入的变量名。成功则返回true 值。
  然后你就可以直接使用变量名对它进行赋值,这个值就会被保存下来。
3、使用session变量的值
  如上例所示,只要你再在新的页面重复上两个步骤(除了赋值外),就可以直接使用session变量。
4、session的销毁
  如果你只是想注销一个变量而不是摧毁整个变量的话,那需要使用函数:
boolean session_unregister(string name);

  用法很简单,参数 name 即为欲删除的变量名。成功则返回 true 值。
  但是,如果要整个"摧毁"session变量的话,比如说安全退出什么的,使用函数:
boolean session_destroy(void);

  本函数结束目前的 Session。本函数没有参数,且返回值均为 true。
5、其它有用的session函数
a、 检查变量是否注册
boolean session_is_registered(string name);

  本函数可检查目前的 Session 之中是否已有指定的变量注册。参数 name 即为欲检查的变量名。成功则返回true 值。
b、 给注册变量归null
void session_unset(void);

  这个函数可以把当然注册的所有的session变量置为空。注意它不是unregister,也不同于destroy。 下面这个例子,对此函数做了很好的说明。
session_register(a,b,c); //auto-session-start
$a=1;
$b=2;
$c=3;
session_unregister(a); //unregistrered $a
echo "A: $a - reg:".session_is_registered(a)." ";
// but the global $a remains
session_unset(); // unsets $b und $c
echo "B:$b - reg:".session_is_registered(b)." ";
// the registration remains !
echo "C:$c - reg:".session_is_registered(c)." ";
echo session_encode();
?>
输出:
A: 1 - reg:
B: - reg:1
C: - reg:1
!b|!c|

c、定制你自己的session处理方法
void session_set_save_handler (string open, string close, string read,
string write, string destroy, string gc)

  这个函数可以定义用户级的session的保存函数(打开、关闭、写入等)。比如,我们想把session保存在本地的一个数据库中时,本函数就很有用了。缺省情况下,每个session存贮在系统临时目录的一个个独立文件中(例如在unix系统中为/tmp)。这适合或不适合,依你的需求而言。例如: 如果你的支持php的web服务器分布在不同的机器上,你不能很容易地共享它们之间的session(当然,你也可以将sessions保存在NFS共享中)。另一个潜在的问题是你机器上的数千或数百万个session文件使你的文件系统变得散乱。注意:这个函数是在4.0b4版本后才出现的。使用本函数前,先要配置php.ini文件,session.save_hadler=user ,否则,session_set_save_handler()不会生效。
  此外,根据我的测试,你如果想让这样的session 跨页面使用,还要在每一个用到session的脚本文件中加入你自定的函数及session_set_save_handler,所以,最好的方法是做成一个单独的文件,在每一个要用到session的脚本中用include来包含进来。
  下面这个例子提供了一个最基本的session保存法,类似于默认的files方法。如果你想用数据库来实现,这也是很容易做到的。
Example:session_set_save_handler() example
function open ($save_path, $session_name) {
global $sess_save_path, $sess_session_name;
$sess_save_path = $save_path;
$sess_session_name = $session_name;
return(true);
}
function close() {
return(true);
}
function read ($id) {
global $sess_save_path, $sess_session_name;
$sess_file = "$sess_save_path/sess_$id";
if ($fp = @fopen($sess_file, "r")) {
$sess_data = fread($fp, filesize($sess_file));
return($sess_data);
} else {
return("");
}
}
function write ($id, $sess_data) {
global $sess_save_path, $sess_session_name;
$sess_file = "$sess_save_path/sess_$id";
if ($fp = @fopen($sess_file, "w")) {
return(fwrite($fp, $sess_data));
} else {
return(false);
}
}
function destroy ($id) {
global $sess_save_path, $sess_session_name;
$sess_file = "$sess_save_path/sess_$id";
return(@unlink($sess_file));
}
/*********************************************
* WARNING - You will need to implement some *
* * sort of garbage collection routine here. *
* *********************************************/
function gc ($maxlifetime) {
return true;
}
session_set_save_handler
("open", "close", "read", "write", "destroy", "gc");
session_start();
// proceed to use sessions normally
// 现在你就可以象往常一样地使用session了。
?> 

/// 原文此处解释错误
我们还想给这个变量设置有效时间来限制操作超时等,比如说10分钟:
setcookie ("username","bluewind", 600000); //有效时间的单位是毫秒,这里可能是原作者参考了javascript。
CODE:// 设置一小时候后失效
setcookie ("TestCookie", "", time() - 3600);
setcookie ("TestCookie", "", time() - 3600, "/~rasmus/", ".example.com", 1);
?>#3楼发布者:webptr时间:2007-09-26 11:05:59
      以下和 session 有关的设定值,都在 PHP 4.x 以上的版本方支援。在 php.ini 的设定档中。

session.save_handler
定义 session 储存资料的档案名称。内定值为 files。
session.save_path
定义 session 储存资料的档案路径。内定值为 /tmp。
session.name
设定 session 所使用的 cookie 名称。内定值为 PHPSESSID。
session.auto_start
设定 session 是否自动开启。内定值为 0 (否)。
session.lifetime
设定 cookie 送到浏览器后的保存时间,单位为秒。内定值为 0,表示直到浏览器关闭。
session.serialize_handler
定义连续/解连续资料的标头,本功能只有 WDDX 模组或 PHP 内部使用。内定值为 php。
session.gc_probability
设定每笔要求回应时的废物商集 (gc, garbage collection) 处理机率。内定值为 1。
session.gc_maxlifetime
设定废物被清除前的存活秒数。
session.extern_referer_check
决定参照到客户端的 Session 代码是否要删除。有时在安全或其它考量时,会设定不删除。内定值为 0。
session.entropy_file
设定 session 代码建立时,使用外部高熵值资源或档案来建立,例如 UNIX 系统上的 /dev/random 或 /dev/urandom。
session.entropy_length
设定 session 从高熵值资源读取的位元组数。内定值为 0。
session.use_cookies
设定是否要将 session 变成 cookie 存在使用者端。内定值为 1,表是开启本功能。#4楼发布者:webptr时间:2007-09-26 11:06:15
      [color=Red]if(isset($_COOKIE[PHPSESSID])) {session_id($_COOKIE[PHPSESSID]);}
$PHPSESSID = session_id();
setcookie('PHPSESSID',$PHPSESSID,time() + $Session_Limit_Time );[/color]

你可能感兴趣的:(PHP)