发新话题
打印

用数据库管理PHP会话

用数据库管理PHP会话

<?php
/*
// =======================================
用数据库来管理会话的最大动机:
通过部署多个Web服务器,可以平衡HTTP负载并利用数据库服务器,也可以解决服务器的性能瓶颈问题。
// =======================================
*/


/*
// 会话表结构
// 有一个附加的索引,它允许使用后面描述的自定义垃圾收集代码快速删除未使用的会话。
create talbe phpsession(
session_id varchar(50) not null,
session_variable text,
last_accessed decimal(15,3) not null,
primary key(session_id),
key last_acc (last_acessed)
)
*/



function getMicroTime(){
  // microtime()返回自格林威治时间


  // 1970年1月1日0:00:00起计算的秒数


  // 作为微秒部分和一个秒部分


  // 例如: 0.08344800 100952237


  
  // 将这两部分转换到一个数组中


  $mtime = explode(" ", microtime());
  
  // 返回这两部分之和


  // 例如: 100952237.08344800


  return($mtime[1]+$mtime[0]);
}

/*
// 每当初试化一个会话时由PHP调用会话打开处理器
// 总是返回true
*/

function sessionOpen($database_name, $table_name){
  // 数据库连接


  // $connection


  // 保存表名称的全局变量


  // $session_table


  
  // 将数据库名保存在一个全局变量中


  global $connection;
  global $hostname;
  global $username;
  global $password;
  
  if(!($connection = @mysql_connect($hostname, $username, $password))){
    showerror();
  }
  
  if(!mysql_select_db($database_name, $connection)){
    showerror();
  }
  
  // 将表名保存在一个全局变量中


  global $session_table;
  $session_table = $table_name;
  return true;
}


/*
// 每当调用session_start()和读会话变量时
// 调用该函数
// 当会话不存在时返回""
// 当会话存在时返回(串行化的)字符串
*/

function sessionRead($sess_id){
  // 访问DBMS连接


  global $connection;
  
  // 访问保存表名称的全局变量


  // 该表保存会话变量


  global $session_table;
  
  // 组织一个查询以找到由$session_id识别的会话


  $search_query = "SELECT * FROM $sesson_table WHERE session_id= '$sess_id'";
  
  // 执行查询


  if(!($result = @mysql_query($search_query, $connection))){
    showerror();
  }
  
  if(mysql_num_rows($result) == 0){
    // 没有找到会话,返回一个空字符串


    return '';
  }else{
    // 找到一个会话,返回串行字符串


    $row = mysql_fetch_array($result);
    return $row["session_variable"];
  }
  
}


/*
// 当利用session_start()调用初试化一个会话时,
// 当注册或注销变量时和当修改会话变量时,
// 调用该函数。成功则返回true
*/

function sessionWrite($sess_id,$val){
  global $connection;
  global $session_table;
  $time_stamp = getMicroTime();
  $search_query = "SELECT session_id FROM $session_table
                     WHERE session_id = '$sess_id'"
;
  
  // 执行查询


  if(!($result = @mysql_query($search_query, $connection))){
    showerror();
  }
  
  if(mysql_num_rows($result) == 0){
    // 没有找到会话,则插入一个新的会话


    $insert_query =
     "INSERT INTO $session_table
     (session_id, session_variable, last_accessed)
     VALUES ('$sess_id', '$val', $time_stamp)"
;
    if(!($result = @mysql_query($insert_query, $connection))){
      showerror();
    }
   
  }else{
    // 找到存在的会话,更新会话变量


    $update_query = "
     UPDATE $session_table
     SET session_variable = '$val',
     last_accessed = $time_stamp
      WHERE session_id = '$sess_id'"
;
    //


    if(!($result = @mysql_query($update_query, $connection))){
      showerror();
    }
  }
  return true;
}

/*
// 在关闭会话时执行函数
// 总是返回true
*/

function sessionClose(){
  return true;
}


/*
// 每当发出session_destroy()函数调用时
// 就会调用该函数。如果会话已经成功地删除则返回true
*/

function sessionDestroy($sess_id){
  global $connection;
  global $session_table;
  $delete_query = "
    DELETE FROM $session_table
    WHERE session_id = '$sess_id'"
;
  if(!($result = @mysql_query($update_query, $connection))){
    showerror();
  }
  return true;
}


/*
// 垃圾收集处理器
// 利用session.gc_probability中指定的可能性
// 在会话开始时调用该函数
// 通过删除所有已经有最后$max_lifetime秒未使用的
// 会话来执行垃圾收集,其中$max_lifetime在
// session.gc_maxlifetime中设置
// 如果DELELTE查询成功则返回true
*/

function sessionGC($max_lifetime){
  global $connection;
  global $session_table;
  $time_stamp = getMicroTime();
  $delete_query = "
    DELETE FROM $session_table
    WHERE last_accessed < ($time_stamp - $max_lifetime)"
;
  if(!($result = @mysql_query($delete_query, $connection))){
    showerror();
  }
  return true;
}


?>



利用PHP来注册用户定义的会话处理器


<?php

// 调用来注册用户回调函数


session_set_save_handler (
  "sessionOpen",
  "sessionClose",
  "sessionRead",
  "sessionWrite",
  "sessionDestroy",
  "sessionGC");

?>
换个头像,看见广告就眼红,直接封ID。

TOP

发新话题