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();
?>
 
当执行一个程序完成时 ,才会调用 上面类的   __destruct() 的方法 这样好理解 因为这是析构函数,所有程序执行完时才执行(可以理解为 在一个程序的某一行给$_SESSION赋值时,不是赋值后就立即写到文件中,而是在程序执行完时再写入。)
posted @ 2014-03-28 01:25  superhosts  阅读(62)  评论(0)    收藏  举报