PHP–将session信息存储到mysql数据库中

前几天有朋友说他网站上有人刷虚拟物品,导致他损失太大,问我有没有什么简单的办法解决,他提出的要求是:同时只能由一个人登陆这个账号来避免多点同时登陆,同时刷新,于是我想到了将session信息存储到mysql数据库中,通过控制session信息到达单点登陆的目的,下面是关于将将session信息存储到mysql数据库中的一个测试。

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_save.php           注册自己创建的session的保存函数

set_session_test.php      session设置测试脚本

get_session_test.php      session显示测试脚本

数据库的表结构

列名类型说明
sesskeychar(32)Session关键字
expiryint(11) unsigned有效期限
valuetextSession

 

session_save.php代码:

  1. <?php      
  2. $gb_DBname="samples";      
  3. $gb_DBuser="root";      
  4. $gb_DBpass="123456";      
  5. $gb_DBHOSTname="localhost";      
  6. $SESS_DBH="";                  //变量为$SESS_DBH数据库连接对象,将在sess_open函数中初始化。      
  7.      
  8. $SESS_LIFE=get_cfg_var("session.gc_maxlifetime");   //调用get_cfg_var函数取得session的最大有效期      
  9.      
  10. //定义sess_open函数,带两个参数保存路径$save_path(文件保存方法时会用到),Session名称$session_name。这两个参数尽管没有在函数内使用,但必须以这种方式定义sess_open函数。所有Session处理函数都必须遵循此处所示的固定的定义方式。      
  11.      
  12.   function sess_open($save_path,$session_name)      
  13. {      
  14.     global $gb_DBHOSTname,$gb_DBname,$gb_DBuser,$gb_DBpass$SESS_DBH;  //global的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面      
  15.      
  16.  ///建立数据库连接,并初始化数据库连接对象$SESS_DBH。mysql扩展库中有两种建立数据库连接的函数,mysql_pconnect用于建立与数据库的持久连接,而函数mysql_connect用于建立非持久连接。出现连接错误时,显示错误信息:      
  17.  if(!$SESS_DBH=mysql_pconnect($gb_DBHOSTname,$gb_DBuser$gb_DBpass))             
  18. {      
  19.  echo "<li>MySql Error:".mysql_error()."<li>";      
  20.  die();      
  21.  }      
  22.      
  23.   if(!mysql_select_db($gb_DBname,$SESS_DBH))   //指定对象数据库,相当于执行“use 数据库名;”的命令。     
  24. {      
  25.   echo "<li>MySql Error:".mysql_error()."<li>";      
  26.       die();      
  27.    }      
  28.     return true;      
  29.  }      
  30.      
  31.    function sess_close()  //定义关闭session方法。      
  32. {         
  33.     return true;      
  34.   }      
  35.      
  36.  function sess_read($key)    //读取session函数,参数为session关键字名(随机产生的乱码)      
  37.  {      
  38.      
  39.     global $SESS_DBH,$SESS_LIFE;      
  40.      
  41. //session关键字为条件,从表db_session检索出在有效期限内的session信息。      
  42.  $qry="select value from db_session where sesskey = '$key' and expiry > ".time();      
  43.      
  44.  $qid=mysql_query($qry,$SESS_DBH);  //#mysql_query函数执行一条 MySQL 查询。第二个参数为数据库连接,省略时使用上一个打开的连接      
  45.      
  46. //#mysql_fetch_row从结果集中以数字数组的形式取得一行。依次调用 mysql_fetch_row() 将返回结果集中的下一行,如果没有更多行则返回 FALSE。成功时,此行的执行结果是将取出来的值放在变量$value中:      
  47.      
  48. if(list($value)=mysql_fetch_row($qid)){      
  49.           return $value;      
  50.      }      
  51.    return false;      
  52.  }      
  53.      
  54.  function sess_write($key,$val)   //##向数据库中保存Session信息。      
  55. {      
  56.      global $SESS_DBH,$SESS_LIFE;      
  57.      $expiry=time()+$SESS_LIFE;   //###Session的期限是当前时间加上最大有效期后的时间。      
  58.      $value=$val;      
  59.      $qry="insert into db_session values('$key',$expiry,'$value')";      
  60.      $qid=mysql_query($qry,$SESS_DBH);      
  61.      
  62.      if(!$qid)       //插入失败,意味着数据库中已有Session记录,则对Session进行更新处理。      
  63. {      
  64.        $qry="update db_session set expiry=$expiry,  
  65.        value='$value' where sesskey='$key' and expiry >".time();      
  66.        $qid=mysql_query($qry,$SESS_DBH);      
  67.       }      
  68.      return $qid;      
  69.  }      
  70.      
  71.   function sess_destroy($key)    //定义删除Session信息的sess_destroy函数,关闭画面时会执行      
  72. {      
  73.   global $SESS_DBH;      
  74.   $qry="delete from db_session where sesskey = '$key'";      
  75.   $qid=mysql_query($qry,$SESS_DBH);      
  76.    return $qid;      
  77.   }      
  78.      
  79.  function sess_gc($maxlifetime)  //定义自动删除过期的Session信息的函数sess_gc。      
  80. {      
  81.     global $SESS_DBH;      
  82.     $qry="delete from db_session where expiry < ".time();      
  83.     $qid=mysql_query($qry,$SESS_DBH);      
  84.     return mysql_affected_rows($SESS_DBH);      
  85.  }      
  86.      
  87. session_module_name();  //不带参数的session_module_name函数用于获取目前Session的模块。      
  88.      
  89. session_set_save_handler("sess_open","sess_close","sess_read""sess_write","sess_destroy","sess_gc");      
  90.  //注册自定义session函数,包括上面定义的所有函数      
  91. ?>    

 

set_session_test.php代码

  1. <?php   
  2.   
  3. //进行自定义Session处理文件。在所有使用自定义Session处理(本节即数据库保存方式)的页面中都必须包含此文件。   
  4.   
  5. include ("session_save.php");   
  6.   
  7. //session_start函数,session处理开始。   
  8. session_start();   
  9.   
  10. //下面三行设置session变量   
  11. $_SESSION['message']= " How do session store into database?";   
  12. $_SESSION['message1']= "Just read this note ";   
  13. $_SESSION['from']= "LAMPBO.org";   
  14. echo "显示SESSION</a>";   
  15. ?>

 

get_session_test.php代码

  1. <?php   
  2. include ("session_save.php");   
  3. session_start();   
  4. echo $_SESSION['message']; //显示session变量   
  5. echo "<br>";   
  6. echo $_SESSION['message1'];   
  7. echo "<br>";   
  8. echo $_SESSION['from'];   
  9. $_SESSION['addMess']="Hello";   
  10. ?>  

 

经过测试,session信息完全可以保存到数据库中,通过检查当前用户的session信息是否存在,或者是否过期,来判断该用户是否已经登陆 或者登陆超时,来更新数据库;再说说开题的需求,如果再每个需要验证用户的页面中加入,session信息是否存在的验证就可以实现单点登陆,我修改了朋友程序的代码,顺利的实现的了他的功能,再也没有人能刷虚拟商品了,不过本来他的程序漏洞太大,也没有空给他重编程序,他暂时就这么用了,以后有空还要研究下其他的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值