php session_set_save_handler 函数的用法(mysql)(转)

  1. <?php   
  2. /*============================文件说明========================================  
  3. @filename:     session.class.php  
  4. @description:  数据库保存在线用户session,实现在线用户功能!  
  5. @notice:       session过期时间一个小时,因为我们的站点是使用cookie(有效时间是1小时)登录。                  
  6.            因此我们只记录用户登录的时间,而不是刷新一次更新一次                  
  7.                删除数据库中session记录的动作发生在用户超时后执行这个文件或正常退出(session_destory)   
  8. @database:     database:sessions  field:sessionid(char32),uid(int10),last_visit(int10)  
  9. @author:       duanjianbo           
  10. @adddate       2008-8-29 =============================================================================*/  
  11. class session {   
  12.   
  13.   
  14.      private $db;   
  15.      private $lasttime=3600;//超时时间:一个小时  
  16.        
  17.      function session(&$db) {   
  18.          $this->db = &$db;  
  19.          session_module_name('user'); //session文件保存方式,这个是必须的!除非在Php.ini文件中设置了  
  20.          session_set_save_handler(   
  21.              array(&$this'open'), //在运行session_start()时执行  
  22.              array(&$this'close'), //在脚本执行完成或调用session_write_close() 或 session_destroy()时被执行,即在所有session操作完后被执行   
  23.              array(&$this'read'), //在运行session_start()时执行,因为在session_start时,会去read当前session数据  
  24.              array(&$this'write'), //此方法在脚本结束和使用session_write_close()强制提交SESSION数据时执行  
  25.              array(&$this'destroy'), //在运行session_destroy()时执行  
  26.              array(&$this'gc'//执行概率由session.gc_probability 和 session.gc_divisor的值决定,时机是在open,read之后,session_start会相继执行open,read和gc  
  27.          );   
  28.          session_start(); //这也是必须的,打开session,必须在session_set_save_handler后面执行  
  29.      }   
  30.        
  31.      function unserializes($data_value) {   
  32.          $vars = preg_split(   
  33.              '/([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*)|/',   
  34.              $data_value, -1, PREG_SPLIT_NO_EMPTY |   
  35.              PREG_SPLIT_DELIM_CAPTURE   
  36.          );   
  37.          for ($i = 0; isset($vars[$i]); $i++) {   
  38.              $result[$vars[$i++]] = unserialize($vars[$i]);   
  39.          }   
  40.          return $result;   
  41.      }    
  42.        
  43.      function open($path$name) {   
  44.          return true;   
  45.      }   
  46.        
  47.      function close() {   
  48.          $this->gc($this->lasttime);  
  49.          return true;   
  50.      }   
  51.        
  52.      function read($SessionKey){  
  53.          $sql = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1";   
  54.          $query =$this->db->query($sql);  
  55.          if($row=$this->db->fetch_array($query)){  
  56.            return $row['uid'];  
  57.          }else{  
  58.              return "";   
  59.          }  
  60.      }  
  61.         
  62.      function write($SessionKey$VArray) {   
  63.           
  64.         require_once(MRoot.DIR_WS_CLASSES .'db_mysql_class.php');  
  65.         $db1=new DbCom();  
  66.        // make a connection to the database... now  
  67.         $db1->connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);  
  68.         $db1->query("set names utf8");  
  69.         $this->db=$db1;  
  70.         $SessionArray = addslashes($VArray);  
  71.         $data=$this->unserializes($VArray);     
  72.         $sql0 = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1";   
  73.         $query0 =$this->db->query($sql0);  
  74.         if($this->db->num_rows($query0) <= 0){  
  75.              if (isset($data['webid']) && !empty($data['webid'])) {   
  76.                 $this->db->query("insert into `sessions` set `session_id` = '$SessionKey',uid='".$data['webid']."',last_visit='".time()."'");  
  77.              }      
  78.                
  79.              return true;  
  80.          }else{  
  81.              /*$sql = "update `sessions` set ";  
  82.              if(isset($data['webid'])){ 
  83.              $sql .= "uid = '".$data['webid']."', " ; 
  84.              } 
  85.              $sql.="`last_visit` = null "  
  86.                    . "where `session_id` = '$SessionKey'";  
  87.                                $this->db->query($sql); */  
  88.              return true;   
  89.          }      
  90.      }   
  91.      function destroy($SessionKey) {   
  92.         $this->db->query("delete from `sessions` where `session_id` = '$SessionKey'");   
  93.         return true;   
  94.      }  
  95.         
  96.      function gc($lifetime) {  
  97.         $this->db->query("delete from `sessions` where unix_timestamp(now()) -`last_visit` > '".$this->lasttime."'");  
  98.         return true;  
  99.      }   
  100. }  
  101.    
  102. ?>   

本文摘自:http://wqss.2008.blog.163.com/blog/static/912428082011823104218806/?suggestedreading
 
 
  1. <?php  
  2. function _session_open($save_path,$session_name)  
  3. {  
  4. global $handle;  
  5. $handle = mysql_connect('localhost','root','root'or die('数据库连接失败');  // 连接MYSQL数据库  
  6. mysql_select_db('db_database11',$handleor die('数据库中没有此库名');    // 找到数据库  
  7. return(true);  
  8. }  
  9. function _session_close()  
  10. {  
  11. global $handle;  
  12. mysql_close($handle);  
  13. return(true);  
  14. }  
  15. function _session_read($key)  
  16. {  
  17. global $handle;       // 全局变量$handle 连接数据库  
  18. $time = time();       // 设定当前时间  
  19. $sql = "select session_data from tb_session where session_key = '$key' and session_time > $time";  
  20. $result = mysql_query($sql,$handle);  
  21. $row = mysql_fetch_array($result);  
  22. if ($row)  
  23. {  
  24.   return($row['session_data']);   // 返回Session名称及内容  
  25. }else  
  26. {  
  27.   return(false);  
  28. }  
  29. }  
  30. function _session_write($key,$data)  
  31. {  
  32. global $handle;  
  33. $time = 60*60;          // 设置失效时间  
  34. $lapse_time = time() + $time;      // 得到Unix时间戳  
  35. $sql = "select session_data from tb_session where session_key = '$key' and session_time > $lapse_time";  
  36. $result = mysql_query($sql,$handle);  
  37. if (mysql_num_rows($result) == 0 )    // 没有结果  
  38. {  
  39.   $sql = "insert into tb_session values('$key','$data',$lapse_time)";  // 插入数据库sql语句  
  40.   $result = mysql_query($sql,$handle);  
  41. }else  
  42. {  
  43.   $sql = "update tb_session set session_key = '$key',session_data = '$data',session_time = $lapse_time where session_key = '$key'";            // 修改数据库sql语句  
  44.   $result = mysql_query($sql,$handle);  
  45. }  
  46. return($result);  
  47. }  
  48. function _session_destroy($key)  
  49. {  
  50. global $handle;  
  51. $sql = "delete from tb_session where session_key = '$key'";     // 删除数据库sql语句  
  52. $result = mysql_query($sql,$handle);  
  53. return($result);  
  54. }  
  55. function _session_gc($expiry_time)  
  56. {  
  57. global $handle;  
  58. $lapse_time = time();         // 将参数$expiry_time赋值为当前时间戳  
  59. $sql = "delete from tb_session where expiry_time < $lapse_time"// 删除数据库sql语句  
  60. $result = mysql_query($sql,$handle);  
  61. return($result);  
  62. }  
  63. session_set_save_handler('_session_open','_session_close','_session_read','_session_write','_session_destroy','_session_gc');  
  64. session_start();  
  65. $_SESSION['user'] = 'mr';  
  66. $_SESSION['pwd'] = 'mrsoft';  
  67. ?>   

  1. session_set_save_handler  
  2. session_set_save_handler---设置用户级 session 存储函数  
  3.   
  4. 函数原型   
  5. void session_set_save_handler (string open, string close, string read, string write, string destroy, string gc)  
  6.   
  7. session_set_save_handler() 设置用户级 session 存储函数,用于存储和取回 session 相关的数据. 用于那些使用不同于 PHP Session 指定的存储方式的情况. 例如,在本地数据库存储 session 数据.   
  8.   
  9. 注意: 你必须设置 php.ini 里面的 session.save_handler配置参数来让 session_set_save_handler() 正常工作.   
  10.   
  11. 下面的例子提供了类似于 PHP 默认的保存文件句柄的基于文件的 session storage 方式. 这个例子可以很简单的扩展到使用熟悉的数据库引擎来进行数据库存储.   
  12. 例子:  
  13. 程序代码:[session_inc.php]  
  14. <?php   
  15. $SESS_DBHOST = "yourhost"/* database server hostname */   
  16. $SESS_DBNAME = "yourdb"/* database name */   
  17. $SESS_DBUSER = "youruser"/* database user */   
  18. $SESS_DBPASS = "yourpassword"/* database password */   
  19.   
  20. $SESS_DBH = "";   
  21. $SESS_LIFE = get_cfg_var("session.gc_maxlifetime");   
  22.   
  23. function sess_open($save_path$session_name) {   
  24.     global $SESS_DBHOST$SESS_DBNAME$SESS_DBUSER$SESS_DBPASS$SESS_DBH;   
  25.   
  26.     if (! $SESS_DBH = mysql_pconnect($SESS_DBHOST$SESS_DBUSER$SESS_DBPASS)) {   
  27.         echo "<li>Can't connect to $SESS_DBHOST as $SESS_DBUSER";   
  28.         echo "<li>MySQL Error: " . mysql_error();   
  29.         die;   
  30.     }   
  31.   
  32.     if (! mysql_select_db($SESS_DBNAME$SESS_DBH)) {   
  33.         echo "<li>Unable to select database $SESS_DBNAME";   
  34.         die;   
  35.     }   
  36.   
  37.     return true;   
  38. }   
  39.   
  40. function sess_close() {   
  41.     return true;   
  42. }   
  43.   
  44. function sess_read($key) {   
  45.     global $SESS_DBH$SESS_LIFE;   
  46.   
  47.     $qry = "SELECT value FROM session_tbl WHERE sesskey = '$key' AND expiry > " . time();   
  48.     $qid = mysql_query($qry$SESS_DBH);   
  49.   
  50.     if (list($value) = mysql_fetch_row($qid)) {   
  51.         return $value;   
  52.     }   
  53.   
  54.     return false;   
  55. }   
  56.   
  57. function sess_write($key$val) {   
  58.     global $SESS_DBH$SESS_LIFE;   
  59.   
  60.     $expiry = time() + $SESS_LIFE//过期时间   
  61.     $value = addslashes($val);   
  62.   
  63.     $qry = "INSERT INTO session_tbl VALUES ('$key', $expiry, '$value')";   
  64.     $qid = mysql_query($qry$SESS_DBH);   
  65.   
  66.     if (! $qid) {   
  67.         $qry = "UPDATE session_tbl SET expiry = $expiry, value = '$value' WHERE sesskey = '$key' AND expiry > " . time();   
  68.         $qid = mysql_query($qry$SESS_DBH);   
  69.     }   
  70.   
  71.     return $qid;   
  72. }   
  73.   
  74. function sess_destroy($key) {   
  75.     global $SESS_DBH;   
  76.   
  77.     $qry = "DELETE FROM session_tbl WHERE sesskey = '$key'";   
  78.     $qid = mysql_query($qry$SESS_DBH);   
  79.   
  80.     return $qid;   
  81. }   
  82.   
  83. function sess_gc($maxlifetime) {   
  84.     global $SESS_DBH;   
  85.   
  86.     $qry = "DELETE FROM session_tbl WHERE expiry < " . time();   
  87.     $qid = mysql_query($qry$SESS_DBH);   
  88.   
  89.     return mysql_affected_rows($SESS_DBH);   
  90. }   
  91.   
  92. session_set_save_handler(   
  93. "sess_open",   
  94. "sess_close",   
  95. "sess_read",   
  96. "sess_write",   
  97. "sess_destroy",   
  98. "sess_gc");   
  99.   
  100. session_start();   
  101. ?>  
  102. 完成以上步骤后,在程序中使用require("session_inc.php")来代替session_start()即可,其他的session函数还是象以前一样的方法调用  
//PHP Session Handle

利用redis解决web集群session共享的Qeephp助手类

折腾了一天,简单了实现了把session存储到redis中,依托于Qeephp。

<?php class Helper_Session{

static private $connect = FALSE; private $redis = NULL; private $redis_host; private $redis_port;

function __construct(){ $this->redis_host=Q::ini(“appini/redis_session/redis_host”); $this->redis_port=Q::ini(“appini/redis_session/redis_port”); $this->is_sso=Q::ini(“appini/redis_session/is_sso”); }

function open($sess_path = ”, $sess_name = ”) { if ( class_exists(‘redis’) ){ $redis = new Redis(); $conn = $redis->connect( $this->redis_host , $this->redis_port ); } else { throw new QException(‘服务器没有安装PHP-Redis扩展!’); } if ( $conn ){ $this->redis = $redis ; } else { throw new QException(‘无法正常连接缓存服务器!’); } return true; }

function close(){ return true; }

function read($sess_id){ return $this->redis->get(‘session:’.$sess_id); }

function write($sess_id, $data){ $sess_data=$this->redis->get(‘session:’.$sess_id); if(empty($sess_data)){ $this->redis->set(‘session:’.$sess_id,$data); } $life_time=get_cfg_var(“session.gc_maxlifetime”); $this->redis->expire(‘session:’.$sess_id,$life_time); return true; }

function destroy($sess_id){ $this->redis->delete(‘session:’.$sess_id); return true; }

function gc($sess_maxlifetime){ return true; }

function init(){ session_set_save_handler(array($this,’open’),array($this,’close’),array($this,’read’),array($this,’write’),array($this,’destroy’),array($this,’gc’)); }

} $redis_session = new Helper_Session(); $redis_session->init();

使用,先看一下qeephp的myapp.php里面。

// 导入类搜索路径 Q::import($app_config['APP_DIR']); Q::import($app_config['APP_DIR'] . ‘/model’); // 设置 session 服务 if (Q::ini(‘runtime_session_provider’)) { Q::loadClass(Q::ini(‘runtime_session_provider’)); }

// 打开 session if (Q::ini(‘runtime_session_start’)) { session_start(); // #IFDEF DEBUG QLog::log(‘session_start()’, QLog::DEBUG); QLog::log(‘session_id: ‘ . session_id(), QLog::DEBUG); // #ENDIF }

从这段代码可以知道qeephp是留有接口的,方便我们扩展,这里以helper助手类的方式体现的,放到了 app文件夹的helper里面,所以将导入类搜索路径放到了设置 session服务的上面。

在environment.yaml加入

# 设置session服务 runtime_session_provider:       helper_session

在app.yaml中加入

redis_session: redis_host:          127.0.0.1 redis_port:          6379

在有redis的情况下现在就可以利用redis存储session。

需要将次方法修改

function cleanCurrentUser() { session_destroy(); //unset($_SESSION[$this->_acl_session_key]); }

由于对redis还不是太熟悉,没有实现单点登录,慢慢会完善的。

sohu技术部实习

  1. <?php  
  2.   
  3. /** 
  4.  * 定义 RedisSessionHandler的基础类,并完成session的初始化 
  5.  *  
  6.  * @copyright   Copyright ©:2012  
  7.  * @author      Tian Mo <motian@sohu-inc.com> 
  8.  * @version     2012-07-16 14:52;00  
  9.  *  
  10.  */  
  11.   
  12. // ****************************************************************************  
  13. // This class saves the PHP session data in redis.  
  14. // ****************************************************************************  
  15. class RedisSessionHandler  
  16. {  
  17.   
  18.     //the redis object  
  19.     private $_redis;  
  20.       
  21.     // ****************************************************************************  
  22.     // class constructor  
  23.     // ****************************************************************************  
  24.     function RedisSessionHandler ($host = '127.0.0.1'$port = 8359, $db = 15)  
  25.     {  
  26.         if(!extension_loaded('redis'))  
  27.             throw new Exception("Redis Extension needed!");  
  28.   
  29.         $_redis = new Redis();  
  30.   
  31.         //connnect to the redis  
  32.         $_redis->connect($host$portor die("Can't connect to the Redis!");  
  33.         $_redis->auth("TechIpd.Sohu");  
  34.   
  35.         $this->_redis = $_redis;  
  36.          
  37.         //select the db  
  38.         $this->_redis->select($db);   
  39.           
  40.     } // php_Session  
  41.   
  42.     function open ($save_path$session_name)  
  43.     // open the session.  
  44.     {  
  45.         // do nothing  
  46.         return TRUE;  
  47.           
  48.     } // open  
  49.   
  50.     function close ()  
  51.     // close the session.  
  52.     {  
  53.         return $this->gc();      
  54.           
  55.     } // close  
  56.   
  57.     function read ($session_id)  
  58.     // read any data for this session.  
  59.     {     
  60.         return $this->_redis->get($session_id);  
  61.                        
  62.     } // read  
  63.   
  64.     function write ($session_id$session_data)  
  65.     // write session data to redis.  
  66.     {             
  67.         $this->_redis->setnx($session_id$session_data);  
  68.   
  69.         //Be careful,we must be the life time all right.  
  70.         $this->_redis->expire($session_id/*get_cfg_var("session.gc_maxlifetime")*/3600 * 24);    
  71.         return TRUE;  
  72.           
  73.     } // write  
  74.   
  75.     function destroy ($session_id)  
  76.     // destroy the specified session.  
  77.    {  
  78.         $this->_redis->delete($session_id);  
  79.         return TRUE;  
  80.           
  81.     } // destroy  
  82.       
  83.     function gc ()  
  84.     // perform garbage collection.  
  85.     {                 
  86.         return TRUE;  
  87.           
  88.     } // gc  
  89.       
  90.     function __destruct ()  
  91.     // ensure session data is written out before classes are destroyed  
  92.     // (see http://bugs.php.net/bug.php?id=33772 for details)  
  93.     {  
  94.         @session_write_close();  
  95.   
  96.     } // __destruct  
  97.   
  98.   
  99.     //redis session start  
  100.     function init(&$sessionObject)  
  101.     {     
  102.         //set in my handler  
  103.         ini_set('session.save_handler''user');  
  104.   
  105.         session_set_save_handler(array(&$sessionObject'open'),  
  106.                                  array(&$sessionObject'close'),  
  107.                                  array(&$sessionObject'read'),  
  108.                                  array(&$sessionObject'write'),  
  109.                                  array(&$sessionObject'destroy'),  
  110.                                  array(&$sessionObject'gc'));  
  111.   
  112.         // the following prevents unexpected effects when using objects as save handlers  
  113.         register_shutdown_function('session_write_close');  
  114.   
  115.         // proceed to set and retrieve values by key from $_SESSION  
  116.         session_start();  
  117.           
  118.     }     
  119. }  
  120.   
  121. //@test redis  
  122. #$session_class = new RedisSessionHandler();  
  123. #$session_class->init($session_class);  
  124. #$_SESSION['nn'] = 'successful';  
  125.   
  126. ?>  
<?php


/**
 * 定义 RedisSessionHandler的基础类,并完成session的初始化
 * 
 * @copyright   Copyright &copy:2012 
 * @author      Tian Mo <motian@sohu-inc.com>
 * @version     2012-07-16 14:52;00 
 * 
 */


// ****************************************************************************
// This class saves the PHP session data in redis.
// ****************************************************************************
class RedisSessionHandler
{


//the redis object
private $_redis;
    
    // ****************************************************************************
    // class constructor
    // ****************************************************************************
    function RedisSessionHandler ($host = '127.0.0.1', $port = 8359, $db = 15)
    {
if(!extension_loaded('redis'))
            throw new Exception("Redis Extension needed!");


$_redis = new Redis();


        //connnect to the redis
        $_redis->connect($host, $port) or die("Can't connect to the Redis!");
        $_redis->auth("TechIpd.Sohu");


$this->_redis = $_redis;
       
//select the db
$this->_redis->select($db); 
   
} // php_Session


    function open ($save_path, $session_name)
    // open the session.
    {
        // do nothing
        return TRUE;
        
    } // open


    function close ()
    // close the session.
    {
return $this->gc();    
        
    } // close


    function read ($session_id)
    // read any data for this session.
    {
   return $this->_redis->get($session_id);
            
    } // read


    function write ($session_id, $session_data)
    // write session data to redis.
    {
$this->_redis->setnx($session_id, $session_data);


        //Be careful,we must be the life time all right.
$this->_redis->expire($session_id, /*get_cfg_var("session.gc_maxlifetime")*/3600 * 24);  
        return TRUE;
        
    } // write


    function destroy ($session_id)
    // destroy the specified session.
   {
$this->_redis->delete($session_id);
return TRUE;
        
    } // destroy

    function gc ()
    // perform garbage collection.
    {               
        return TRUE;
        
    } // gc

    function __destruct ()
    // ensure session data is written out before classes are destroyed
    // (see http://bugs.php.net/bug.php?id=33772 for details)
    {
        @session_write_close();


    } // __destruct




//redis session start
function init(&$sessionObject)
{
//set in my handler
ini_set('session.save_handler', 'user');


session_set_save_handler(array(&$sessionObject, 'open'),
                        array(&$sessionObject, 'close'),
                          array(&$sessionObject, 'read'),
                        array(&$sessionObject, 'write'),
                          array(&$sessionObject, 'destroy'),
                        array(&$sessionObject, 'gc'));


// the following prevents unexpected effects when using objects as save handlers
register_shutdown_function('session_write_close');


// proceed to set and retrieve values by key from $_SESSION
session_start();

}
}


//@test redis
#$session_class = new RedisSessionHandler();
#$session_class->init($session_class);
#$_SESSION['nn'] = 'successful';


?>
原文地址:https://www.cnblogs.com/xingmeng/p/3223043.html