帖子来源:http://hi.baidu.com/isnono/blog/item/6048479060d0e089a877a446.html
之前的文章《自定义SESSION(一)——文件 》,详细说明测试了session的一些原理,以及如何使用文件来自定义保存session。
这里打算使用数据库来保存session,应该说用数据库来保存是更加有效而且更方便共享的一种方法。
首先,说明下session_set_save_handler()里面的每个函数。
记住一点:session数据都是在你的代码运行完后才写入代码的
<?function open($save_path, $session_name)
{
//打开session文件,用来设计保存路径,一般直接return true 就好了
//在session_start()中会调用到。
}
function close()
{
//关闭session连接
}
function read($id)
{
//读取session数据,在session_start()中调用。
}
function write($id, $sess_data)
{
//写session到文件或者数据库
//记住$_SESSION['var']='test'这种对session赋值并不调用该方法。该方法是在代码结束后或者调用session_write_close()调用的时候才运行的。
}
function destroy($id)
{
//注销session,删除一条session记录
}
function gc($maxlifetime)
{
//删除过时的session记录
}
?>
然后,使用mysql来保存。详细了解了每个函数的作用,这样用数据库来保存就很简单了。这里我给一个例子。
mysql_session.php
<?
/**
*CREATE TABLE `session` (
`sid` char(32) NOT NULL,
`expiry` int(10) NOT NULL,
`value` mediumtext NOT NULL,
PRIMARY KEY (`sid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
*
*/
function init_db(){
$db["host"]='localhost';//
$db["database"]="pcti";
$db["user"]="root";
$db["password"]="admin";
$db=new PDO('mysql:host='.$db['host'].';dbname='.$db['database'],$db['user'],$db['password']);
$db->query("set names 'utf8'");
return $db;
}
class session{
private $db;
function __construct($db){
$this->db=$db;
}
public function open($save_path,$session_name){
return true;
}
public function close(){
$this->db=null;
return true;
}
public function read($sid){
$rs=$this->db->query('select * from session where sid=''.$sid.''');
foreach ($rs as $row){
return $row['value'];
}
return null;
}
public function write($sid,$value){
if(is_null($old_value=$this->read($sid))){
//insert
return $this->db->query("insert into session (sid,expiry,value)values('".$sid."','".time()."','".$value."')");
}else{
//update
return $this->db->query("update session set expiry='".time()."',value='".$value."' where sid='".$sid."'");
}
}
public function destroy($sid){
return $this->db->query('delete from session where sid=''.$sid.''');
}
public function gc($max_life_time){
return $this->db->query('delete from session where expiry+'.$max_life_time.'<'.time());
}
}
$session=new session(init_db());
session_set_save_handler(array($session,'open'),
array($session,'close'),
array($session,'read'),
array($session,'write'),
array($session,'destroy'),
array($session,'gc'));
session_start();
里面有相应的创建数据库的语句。
然后写一个测试文件看看。
创建session:mysql_session_test.php
<?
include('mysql_session.php');
$_SESSION['test']='mysql session test';
?> <a href="mysql_session_check.php">next</a>
运行下,然后看看数据库中是不是多了条记录?呵呵,如果是,恭喜测试成功。
查看session:mysql_session_check.php
<?
include('mysql_session.php');
print_r($_SESSION);
?><a href="mysql_session_exit.php">exit</a>
注销session测试:mysql_session_exit.php
<?
include('mysql_session.php');
session_destroy();
header('location:mysql_session_check.php');
?>
呵呵,再次测试都没有问题。测试环境winxp+php5.2+apache 2.2 +mysql 5.0
总结
之前我完全脱离PHP内置的session机制,使用数据库和cookie来模拟。现在发现直接使用自定义session更加简单,方便。但两者之间谁更加可取还有待商榷。
PS:DISCUZ好像使用的数据库和cookie来模拟!