sesion_set_save_hander 的 理解 步骤

来源:互联网 发布:java经典50例 编辑:程序博客网 时间:2024/04/30 00:24

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),所以当你在这个时候取$_SESSION 时 可能返回空,因为 这次没有注册到内存中。
2.当此次脚本执行完时(不论当前脚本是否嵌套多少脚本,也就是说执行到脚本的最后一行时),通过调用write($key,$value)当当前的值在写到这个phpsessionid 的文件中去。然后通过close($key) 来关闭当前的session.执行完成。
3.当调用session_write_close ()时 会先 调用write($key,$value) ,在调用close ()
4.当调用session_destory_close()时 先删掉当前 sessionid的值,然后close ()

==========================================

session_start()后 对应的session文件是被锁定的,直到当前脚本结束才会解锁。
在锁定期间,令一个进程访问相同session id 要等文件解锁后session_start()才会开始。
解决办法是在 session 设置好数据后调用 session_write_close() 将数据写入文件并且结束session

例如如下代码

PHP code
<?php
session_name("STEST");
session_id("TESTID");
session_start();
$_SESSION["count"]=0;
session_write_close();
sleep(10);
echo "success";
?>


如果不加入session_write_close();
并发3个进程访问该页面,第一个进程执行10秒 第二个执行20秒 第三个执行30秒。
加入session_write_close()后 
并发3个进程会同时在10秒后执行完成


=======================================



<?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赋值时,不是赋值后就立即写到文件中,而是在程序执行完时再写入。)


由此,我们可见: 当每个用户访问web, PHP的session初始化函数都会给当前来访用户分配一个唯一的session ID。并且在session生命周期结束的时候,将用户在此周期产生的session数据持久到session文件中。用户再次访问的时候,session初始化函数,又会从session文件中读取session数据,开始新的session生命周期。








0 0
原创粉丝点击