session_set_save_hander 理解不走
session_set_save_hander(open,close,read,write,destory,gc) : 总共有 open,close,read,write,destory,gc 这几个参数,且这几个参数 都是定义的函数名:
列如
function open($path,$name){}
function close($key){}
function read($key){}
function write($key,$value){}
function destory($key){}
function gc($key){}
注意: 以下说到的$key 指的是 PHPSESSIONID : hiuriq6kmr1mv5vf020djpbu869
方法的参数 是 session_set_save_hande通过php 获取得到的,方法的参数 名字 可以随便起,php获取到的PHPSESSSID 会自动指定到方法的参数上去。
方法体里 就是自己具体的逻辑了。
当你上面的方法体逻辑都写好时,通过session_start()的开启,回去调用上面的 open 方法 red方法 和 gc 方法 ,
1.可以理解成 open 找到session 的临时目录($path),然后通过phpsessionid拼接一个前缀(比如sess_hiuriq6kmr1mv5vf020djpbu869 ,这里的sess_ 就是所指的前缀) 得到 $name(也就是具体的临时文件),然后通过red方法传递一个$key 取到 具体的PHPSESSIONID的值$value,取到之后 由于不知道 当前的session 是否还有效 ,所以这时候启动了 gc 垃圾回收。
通过传递一个$key , 来查询当前时间是否大于设置的有效期时间,大于的话 删除,所以当你点击一个页面是,如果大于有效期的话,就可能把你的session文件删掉,这样的话
你通过前两个步骤取得值,就不能被注册到内存中,所以当你在这个时候取$_SESSION 时 可能返回空,因为 这次没有注册到内存中。
2.当此次脚本执行完时(不论当前脚本是否嵌套多少脚本,也就是说执行到脚本的最后一行时),通过调用write($key,$value)当当前的值在写到这个phpsessionid 的文件中去。然后通过close($key) 来关闭当前的session.执行完成。
3.当调用session_write_close ()时 会先 调用write($key,$value) ,在调用close ()
4.当调用session_destory_close()时 先删掉当前 sessionid的值将然后close ()
<?php
class SessionDB {
private $data=null;
private $session_id=null;
private $minutes_to_expire=3600;
public function __construct(){
global $SESSION;
if (isset($_COOKIE['session_id'])){
$this->session_id = $_COOKIE['session_id'];
} else {
$this->session_id = md5(microtime().rand(1,9999999999999999999999999)); // GENERATE A RANDOM ID
setcookie('session_id',$this->session_id);
$sql = "INSERT INTO `tb_session_db` (`session_id`, `updated_on`) VALUES ('{$this->session_id}', NOW())";
mysql_query($sql);
}
$sql = "SELECT `value` FROM `tb_session_db` WHERE `session_id`='{$this->session_id}'";
$query = mysql_query($sql);
$this->data = unserialize(mysql_result($query, 0, 'value'));
$SESSION = $this->data;
}
private function expire(){
$date_to_delete = date("Y-m-d H:i:s", time()-60*$this->minutes_to_expire);
$sql = "DELETE FROM `tb_session_db` WHERE `update_on` <= '$date_to_delete'";
mysql_query($sql);
}
public function __destruct(){
global $SESSION;
$this->data = serialize($SESSION);
$sql = "UPDATE `tb_session_db` SET `value`='{$this->data}', `updated_on`=NOW() WHERE `session_id`='{$this->session_id}'";
mysql_query($sql);
$this->expire();
}
}
/*
TABLE STRUCTURE
CREATE TABLE IF NOT EXISTS `tb_session_db` (
`session_id` varchar(32) NOT NULL,
`value` blob,
`updated_on` datetime DEFAULT NULL,
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
*/
?>
<?php
require_once('session_db.php');
define('MYSQL_HOST','mysql.example.com');
define('MYSQL_USER','.......');
define('MYSQL_PASS','.......');
define('MYSQL_BASE','.......');
mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) or die('Cannot connect');
mysql_select_db(MYSQL_BASE) or die('Cannot select DB');
mysql_set_charset('utf8_general_ci');
$SESSION = null;
global $SESSION;
$session_db = new SessionDB();
?>
class SessionDB {
private $data=null;
private $session_id=null;
private $minutes_to_expire=3600;
public function __construct(){
global $SESSION;
if (isset($_COOKIE['session_id'])){
$this->session_id = $_COOKIE['session_id'];
} else {
$this->session_id = md5(microtime().rand(1,9999999999999999999999999)); // GENERATE A RANDOM ID
setcookie('session_id',$this->session_id);
$sql = "INSERT INTO `tb_session_db` (`session_id`, `updated_on`) VALUES ('{$this->session_id}', NOW())";
mysql_query($sql);
}
$sql = "SELECT `value` FROM `tb_session_db` WHERE `session_id`='{$this->session_id}'";
$query = mysql_query($sql);
$this->data = unserialize(mysql_result($query, 0, 'value'));
$SESSION = $this->data;
}
private function expire(){
$date_to_delete = date("Y-m-d H:i:s", time()-60*$this->minutes_to_expire);
$sql = "DELETE FROM `tb_session_db` WHERE `update_on` <= '$date_to_delete'";
mysql_query($sql);
}
public function __destruct(){
global $SESSION;
$this->data = serialize($SESSION);
$sql = "UPDATE `tb_session_db` SET `value`='{$this->data}', `updated_on`=NOW() WHERE `session_id`='{$this->session_id}'";
mysql_query($sql);
$this->expire();
}
}
/*
TABLE STRUCTURE
CREATE TABLE IF NOT EXISTS `tb_session_db` (
`session_id` varchar(32) NOT NULL,
`value` blob,
`updated_on` datetime DEFAULT NULL,
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
*/
?>
<?php
require_once('session_db.php');
define('MYSQL_HOST','mysql.example.com');
define('MYSQL_USER','.......');
define('MYSQL_PASS','.......');
define('MYSQL_BASE','.......');
mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) or die('Cannot connect');
mysql_select_db(MYSQL_BASE) or die('Cannot select DB');
mysql_set_charset('utf8_general_ci');
$SESSION = null;
global $SESSION;
$session_db = new SessionDB();
?>
当执行一个程序完成时 ,才会调用 上面类的 __destruct() 的方法 这样好理解 因为这是析构函数,所有程序执行完时才执行(可以理解为 在一个程序的某一行给$_SESSION赋值时,不是赋值后就立即写到文件中,而是在程序执行完时再写入。)
浙公网安备 33010602011771号