牛骨文教育服务平台(让学习变的简单)
博文笔记

数据库中存储Session信息

创建时间:2011-12-20 投稿人: 浏览次数:7089
 

大部分使用PHP的人一旦应用到Session都会使用Cookie。Cookie虽好可是它也会给我们带来一些隐患。

隐患一:

如果客户端机器的Cookie一旦因病毒而失效了,那么Session信息也就相当于没有了。

隐患二:

Session在PHP中默认的是以文件的形式保存在一个临时文件夹里面的,对于一个小型系统来说,这样做完全可以,可是对于一个大型而又被经常访问的系统来说,就不是很好的办法了。假设这个网站一天有1 000个人访问。一个月以后Session的临时文件夹就会有30 000个临时文件。想象一下计算机要从30 000里面找一条session_sid是要花费不少时间的。因此为了提高效率,使用用数据库来保存Session不失为解决这个矛盾的好方法。

 

 

 

 

 

Session在php中默认的是以文件的形式保存在一个临时文件夹里面的。可以通过修改php.ini文件的session.save_handler设置来改变Session的保存方式。默认为session.save_handler = files,必须将其修改为session.save_handler = user,即变为用户自定义方式。

完成这一步后,我们可以创建自己的用户级的Session的保存函数(打开、关闭、写入等),然后必须使用session_set_save_handler函数注册自己创建的Session的保存函数。使用session_set_save_handler函数前,必须先要配置php.ini文件,即session.save_hadler=user,否则,session_set_save_handler函数不会生效。

你如果想让这样的Session跨页面使用,还要在每一个用到Session的脚本文件中加入你自定的函数及用session_set_save_handler函数进行注册,所以,最好的方法是做成一个单独的文件,在每一个要用到Session的脚本中用include来包含进来。

目录结构

  1. /samples  
  2.   /chap3  
  3.    /savesession  
  4.     session_save.php        注册自己创建的session的保存函数  
  5.     set_session_test.php    session设置测试脚本  
  6.     get_session_test.php    session显示测试脚本 

数据库的表结构

表3-4  保存Session(db_session)

列名

数据类型

概要

sesskey

char(32)

Session关键字

expiry

int(11) unsigned

有效期限

value

text

Session值


本例代码

  1. Program 3-5 session_save.php  
  2. 1   <?php 

本节使用mysql扩展库来进行数据库操作,2行至5行定义数据库连接用的全局变量,分别为数据名、数据库用户名、密码、主机名(IP地址也可)。

  1. 2   $gb_DBname="samples";  
  2. 3   $gb_DBuser="root";  
  3. 4   $gb_DBpass="518";  
  4. 5   $gb_DBHOSTname="localhost"; 

变量为$SESS_DBH数据库连接对象,将在sess_open函数中初始化。

  1. 6   $SESS_DBH=""; 

调用get_cfg_var函数取得session的最大有效期。

  1. 7   $SESS_LIFE=get_cfg_var("session.gc_maxlifetime"); 

定义sess_open函数,带两个参数保存路径$save_path(文件保存方法时会用到),Session名称$session_name。这两个参数尽管没有在函数内使用,但必须以这种方式定义sess_open函数。所有Session处理函数都必须遵循此处所示的固定的定义方式。

  1. 8   function sess_open($save_path,$session_name){ 

global的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面。

  1. 9       global $gb_DBHOSTname,$gb_DBname,$gb_DBuser,$gb_DBpass, $SESS_DBH; 

 

 

建立数据库连接,并初始化数据库连接对象$SESS_DBH。mysql扩展库中有两种建立数据库连接的函数,mysql_pconnect用于建立与数据库的持久连接,而函数mysql_connect用于建立非持久连接。出现连接错误时,显示错误信息。

  1. 10      if(!$SESS_DBH=mysql_pconnect($gb_DBHOSTname,$gb_DBuser, $gb_DBpass)){  
  2. 11            echo "<li>MySql Error:".mysql_error()."<li>";  
  3. 12            die();  
  4. 13      } 

指定对象数据库,相当于执行"use 数据库名;"的命令。

  1. 14      if(!mysql_select_db($gb_DBname,$SESS_DBH)){  
  2. 15            echo "<li>MySql Error:".mysql_error()."<li>";  
  3. 16            die();  
  4. 17      }  
  5. 18      return true;  
  6. 19  } 

定义关闭session方法。

  1. 20  function sess_close(){  
  2. 21      return true;  
  3. 22  } 

读取session函数,参数为session关键字名(随机产生的乱码)。

  1. 23  function sess_read($key){  
  2. 24      global $SESS_DBH,$SESS_LIFE; 

以session关键字为条件,从表db_session检索出在有效期限内的session信息。

  1. 25      $qry="select value from db_session where  sesskey = "$key" and expiry > ".time(); 

mysql_query函数执行一条 MySQL 查询。第二个参数为数据库连接,省略时使用上一个打开的连接。

  1. 26      $qid=mysql_query($qry,$SESS_DBH); 

mysql_fetch_row从结果集中以数字数组的形式取得一行。依次调用 mysql_fetch_row() 将返回结果集中的下一行,如果没有更多行则返回 FALSE。成功时,此行的执行结果是将取出来的值放在变量$value中。

  1. 27      if(list($value)=mysql_fetch_row($qid)){  
  2. 28            return $value;  
  3. 29      }  
  4. 30      return false;  
  5. 31  } 

向数据库中保存Session信息。

  1. 32  function sess_write($key,$val){  
  2. 33      global $SESS_DBH,$SESS_LIFE; 

Session的期限是当前时间加上最大有效期后的时间。

  1. 34      $expiry=time()+$SESS_LIFE;  
  2. 35      $value=$val;  
  3. 36      $qry="insert into db_session values("$key",$expiry,"$value")";  
  4. 37      $qid=mysql_query($qry,$SESS_DBH); 

插入失败,意味着数据库中已有Session记录,则对Session进行更新处理。

  1. 38      if(!$qid){  
  2. 39           $qry="update db_session set expiry=$expiry,  
  3. value="$value" where sesskey="$key" and expiry >".time();  
  4. 40           $qid=mysql_query($qry,$SESS_DBH);  
  5. 41      }  
  6. 42      return $qid;  
  7. 43  } 

定义删除Session信息的sess_destroy函数,关闭画面时会执行。

  1. 44  function sess_destroy($key){  
  2. 45      global $SESS_DBH;  
  3. 46      $qry="delete from db_session where sesskey = "$key"";  
  4. 47      $qid=mysql_query($qry,$SESS_DBH);  
  5. 48      return $qid;  
  6. 49  } 

定义自动删除过期的Session信息的函数sess_gc。

  1. 50  function sess_gc($maxlifetime){  
  2. 51      global $SESS_DBH;  
  3. 52      $qry="delete from db_session where expiry < ".time();  
  4. 53      $qid=mysql_query($qry,$SESS_DBH);  
  5. 54      return mysql_affected_rows($SESS_DBH);  
  6. 55  } 

不带参数的session_module_name函数用于获取目前Session的模块。

  1. 56  session_module_name(); 

注册自定义session函数,包括打开、关闭、写入等。

  1. 57  session_set_save_handler("sess_open","sess_close","
    sess_read", "sess_write","sess_destroy","sess_gc");  
  2. 58  ?> 
  3.  
  4. Program 3-6 set_session_test.php  
  5. 1   <?php

 

包含进行自定义Session处理文件。在所有使用自定义Session处理(本节即数据库保存方式)的页面中都必须包含此文件。

  1. 2   include ("session_save.php"); 

调用session_start函数,session处理开始。

  1. 3   session_start(); 

设置session变量。

  1. 4   $_SESSION["message"]= "Can I Help you?";  
  2. 5   $_SESSION["message1"]= "No,Thanks ";  
  3. 6   $_SESSION["from"]= "Tom";  
  4. 7   echo "<a href="get_session_test.php">显示SESSION</a>";  
  5. 8   ?> 
  6.  
  7. Program 3-7 get_session_test.php  
  8. 1   <?php 
  9. 2   include ("session_save.php");  
  10. 3   session_start(); 

显示session变量。

  1. 4   echo $_SESSION["message"];  
  2. 5   echo "<br>";  
  3. 6   echo $_SESSION["message1"];  
  4. 7   echo "<br>";  
  5. 8   echo $_SESSION["from"];  
  6. 9   $_SESSION["addMess"]="Hello";  
  7. 10  ?> 
 
 
 
 
 
 
 
 
 
 
 
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。