一个开发环境有多个网站,需要使用不同的session,解决方案很多。不过这次也高大上一把,用数据库存,方便以后扩展。
postgresql版
首先是数据库的部分
--drop table php_session
create unlogged table php_session
(
sess_id varchar(32) primary key,
modify_time timestamp with time zone not null,
sess_data varchar(3000) default ''
);
create index concurrently idx_php_session_modify_time on php_session(modify_time);
--set_session(id, data)
create or replace function set_session(varchar, varchar) returns void as $set_session$
with upsert as (
update php_session
set modify_time = current_timestamp, sess_data = $2
where sess_id = $1
returning 1
)
insert into php_session (sess_id, modify_time, sess_data)
select $1, current_timestamp, $2
where not exists (
select 1 from upsert
);
$set_session$ language sql;
--get_session(id)
create or replace function get_session(varchar) returns varchar as $get_session$
select sess_data from php_session where sess_id = $1
$get_session$ language sql;
--del_session
create or replace function del_session(varchar) returns void as $del_session$
delete from php_session where sess_id = $1
$del_session$ language sql;
--gc_session
create or replace function gc_session() returns void as $del_session$
delete from php_session where modify_time < current_timestamp - interval '30 days'
$del_session$ language sql;
然后是php的部分
<?php
session_set_save_handler(
function ($savepath, $sessionname) {//open
return true;
},
function () {//close
return true;
},
function ($id) {//read
$sql = "select get_session($1)";
$stmt = pg_query_params(session_conn, $sql, array($id));
$result = pg_fetch_row($stmt);
return $result[0];
},
function ($id, $data) {//write
$sql = "select set_session($1, $2)";
pg_query_params(session_conn, $sql, array($id, $data));
return true;
},
function ($id) {//destroy
$sql = "select del_session($1)";
pg_query_params(session_conn, $sql, array($id, $data));
return true;
},
function ($maxlifetime) {//gc
//php needn't control the global session gc
return true;
}
);
register_shutdown_function('session_write_close');
?>
然后只要在session_start之前调用这个就可以了
至于session_conn,那是我定义的一个常量,表示一个指向session数据库的链接而已。
mysql版
再总结一个针对mysql的集成更多基础功能的例子:
表结构:
create table if not exists `sessioninfo` ( `sid` varchar(255) not null, `value` text not null, `expiration` timestamp not null default current_timestamp on update current_timestamp, primary key (`sid`) ) engine=innodb default charset=utf8;
session信息存储到数据库的类:
class mysessionhandler implements sessionhandlerinterface {
/**
* @access private
* @var object 数据库连接
*/
private $_dblink;
/**
* @access private
* @var string 保存session的表名
*/
private $_sessiontable;
/**
* @access private
* @var string session名
*/
private $_sessionname;
/**
* @const 过期时间
*/
const session_expire = 10;
public function __construct($dblink, $sessiontable) {
if(!is_object($dblink)) {
return false;
}
$this->_dblink = $dblink;
$this->_sessiontable = $sessiontable;
}
/**
* 打开
* @access public
* @param string $session_save_path 保存session的路径
* @param string $session_name session名
* @return integer
*/
public function open($session_save_path, $session_name) {
$this->_sessionname = $session_name;
return 0;
}
/**
* 关闭
* @access public
* @return integer
*/
public function close() {
return 0;
}
/**
* 关闭session
* @access public
* @param string $session_id session id
* @return string
*/
public function read($session_id) {
$query = "select value from {$this->_sessiontable} where sid = {$session_id} and unix_timestamp(expiration) + " . self::session_expire . " > unix_timestamp(now())";
$result = $this->_dblink->query($query);
if(!isset($value) || empty($value)) {
$value = "";
return $value;
}
$this->_dblink->query("update {$this->_sessiontable} set expiration = current_timestamp() where sid = {$session_id}");
$value = $result->fetch_array();
$result->free();
return $value['value'];
}
/**
* 写入session
* @access public
* @param string $session_id session id
* @param string $session_data session data
* @return integer
*/
public function write($session_id, $session_data) {
$query = "select value from {$this->_sessiontable} where sid = '{$session_id}' and unix_timestamp(expiration) + " . self::session_expire . " > unix_timestamp(now())";
$result = $this->_dblink->query($query);
$result = $result->fetch_array();
if(!empty($result)) {
$result = $this->_dblink->query("update {$this->_sessiontable} set value = {$session_data} where sid = {$session_id}");
}
else{
$result = $this->_dblink->query("insert into {$this->_sessiontable} (sid, value) values ('{$session_id}', '{$session_data}')");
}
if($result){
return 0;
}
else{
return 1;
}
}
/**
* 销魂session
* @access public
* @param string $session_id session id
* @return integer
*/
public function destroy($session_id) {
$result = $this->_dblink->query("delete from {$this->_sessiontable} where sid = '{$session_id}'");
if($result){
return 0;
}
else{
return 1;
}
}
/**
* 垃圾回收
* @access public
* @param string $maxlifetime session 最长生存时间
* @return integer
*/
public function gc($maxlifetime) {
$result = $this->_dblink->query("delete from {$this->_sessiontable} where unix_timestamp(expiration) < unix_timestamp(now()) - " . self::session_expire);
if($result){
return 0;
}
else{
return 1;
}
}
}
$dblink = new mysqli("localhost", "root", "root", "test");
$sessiontable = "sessioninfo";
$handler = new mysessionhandler($dblink, $sessiontable);
session_set_save_handler($handler);
session_start();
$_session['name'] = "test";
echo $_session["name"];
//session_destroy();
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:)!