为什么要进行session共享?
因为一些大型网站,通常会有很多服务器,每个服务器运行不同的业务模块,并使用二级域名(或是完全不同的域名),而用户系统是统一的,通过登陆名、密码来登陆各模块。用户数据放在指定的数据库中,各模块都可访问。问题是,当用户登陆模块A时,再进入模块B时,模块B无法获取用户在模块A登陆时的session数据,那么用户又要在模块B重新登陆一次。所以就要用到了sesson共享。
php中session默认是保存在文件中的,在php.ini
session.save_handler = files
session_set_save_handler
open(string $savePath, string $sessionName) 自动会话开始或手动调用session_start()后第一个被调用回调函数 close() write回调函数调用之后调用 read(string $sessionId) 读取会话数据,如果没有则返回空字符串 write(string $sessionId, string $data) 保存会话数据 destroy($sessionId) 删除会话数据 gc($lifetime) PHP会不时的调用该函数进行垃圾收集, 调用周期由session.gc_probability和session.gc_divisor参数控制。 lifetime参数由session.gc_maxlifetime设置。 create_sid() 创建新的会话id
我们创建数据表来存储session数据
CREATE TABLE `session` ( `sid` varchar(32) NOT NULL DEFAULT '' COMMENT 'session_id', `expire` int(11) NOT NULL COMMENT '过期时间', `data` text COMMENT 'session数据', PRIMARY KEY (`sid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='session表';
<?php class DBSession { protected $db = null; protected $lifeTime = 0; protected $sessTable = ''; public function __construct($db, $sessTable) { $this->db = $db; $this->sessTable = $sessTable; $this->lifeTime = ini_get('session.gc_maxlifetime'); ini_set('session.save_handler', 'user'); session_set_save_handler( array($this, "open"), array($this, "close"), array($this, "read"), array($this, "write"), array($this, "destroy"), array($this, "gc") ); register_shutdown_function('session_write_close'); } public function open($savePath, $sessName) { return true; } public function close() { $this->gc($this->lifeTime); return true; } public function read($sessId) { $time = time(); $ret = mysql_query("SELECT `data` FROM `{$this->sessTable}` WHERE `sid`='{$sessId}' AND `expire` > {$time};", $this->db); if($ret) { $row = mysql_fetch_assoc($ret); return $row['data']; } return ''; } public function write($sessId, $sessData) { $expire = time() + $this->lifeTime; $sessData = mysql_real_escape_string($sessData); $ret = mysql_query("SELECT COUNT(*) AS cnt FROM `{$this->sessTable}` WHERE `sid`='{$sessId}';", $this->db); $row = mysql_fetch_assoc($ret); if($row['cnt']) { $sql = "UPDATE `{$this->sessTable}` SET `data`='{$sessData}', `expire`={$expire} WHERE `sid`='{$sessId}';"; } else { $sql = "INSERT INTO `{$this->sessTable}` (`sid`,`expire`,`data`) VALUES('{$sessId}',{$expire},'{$sessData}');"; } mysql_query($sql, $this->db); if(mysql_affected_rows($this->db)) { return true; } return false; } public function destroy($sessId) { mysql_query("DELETE FROM `{$this->sessTable}` WHERE `sid`='{$sessId}';", $this->db); if(mysql_affected_rows($this->db)) { return true; } return false; } public function gc($lifeTime) { $time = time(); mysql_query("DELETE FROM `{$this->sessTable}` WHERE `expire` < {$time};", $this->db); return mysql_affected_rows($this->db); } } $sessDb = mysql_connect('127.0.0.1', 'root', '') or die('connect error'); mysql_select_db('test', $sessDb) or ('select db error'); mysql_query('set names utf8', $sessDb); new DBSession($sessDb, 'session'); session_start();
我们创建三个虚拟主机分别为
www.a.com www.b.com www.c.com
分别在三个虚拟主机下创建index.php,来设置会话数据。
<?php require './DBSession.php'; $_SESSION['userinfo'] = array( 'name' => 'aaa', ); var_dump($_SESSION['userinfo']);
可以看到a,b ,c三个站的会话信息全部保存在了session表中了,只要拿到了session_id就可以共享的访问其他站设置的会话数据。
版权声明:博主文章,可以不经博主允许随意转载,随意修改,知识是用来传播的。