数据库中存储Session信息
大部分使用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来包含进来。
目录结构
- /samples
- /chap3
- /savesession
- session_save.php 注册自己创建的session的保存函数
- set_session_test.php session设置测试脚本
- get_session_test.php session显示测试脚本
数据库的表结构
表3-4 保存Session(db_session)
列名 |
数据类型 |
概要 |
sesskey |
char(32) |
Session关键字 |
expiry |
int(11) unsigned |
有效期限 |
value |
text |
Session值 |
本例代码
- Program 3-5 session_save.php
- 1 <?php
本节使用mysql扩展库来进行数据库操作,2行至5行定义数据库连接用的全局变量,分别为数据名、数据库用户名、密码、主机名(IP地址也可)。
- 2 $gb_DBname="samples";
- 3 $gb_DBuser="root";
- 4 $gb_DBpass="518";
- 5 $gb_DBHOSTname="localhost";
变量为$SESS_DBH数据库连接对象,将在sess_open函数中初始化。
- 6 $SESS_DBH="";
调用get_cfg_var函数取得session的最大有效期。
- 7 $SESS_LIFE=get_cfg_var("session.gc_maxlifetime");
定义sess_open函数,带两个参数保存路径$save_path(文件保存方法时会用到),Session名称$session_name。这两个参数尽管没有在函数内使用,但必须以这种方式定义sess_open函数。所有Session处理函数都必须遵循此处所示的固定的定义方式。
- 8 function sess_open($save_path,$session_name){
global的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面。
- 9 global $gb_DBHOSTname,$gb_DBname,$gb_DBuser,$gb_DBpass, $SESS_DBH;
建立数据库连接,并初始化数据库连接对象$SESS_DBH。mysql扩展库中有两种建立数据库连接的函数,mysql_pconnect用于建立与数据库的持久连接,而函数mysql_connect用于建立非持久连接。出现连接错误时,显示错误信息。
- 10 if(!$SESS_DBH=mysql_pconnect($gb_DBHOSTname,$gb_DBuser, $gb_DBpass)){
- 11 echo "<li>MySql Error:".mysql_error()."<li>";
- 12 die();
- 13 }
指定对象数据库,相当于执行"use 数据库名;"的命令。
- 14 if(!mysql_select_db($gb_DBname,$SESS_DBH)){
- 15 echo "<li>MySql Error:".mysql_error()."<li>";
- 16 die();
- 17 }
- 18 return true;
- 19 }
定义关闭session方法。
- 20 function sess_close(){
- 21 return true;
- 22 }
读取session函数,参数为session关键字名(随机产生的乱码)。
- 23 function sess_read($key){
- 24 global $SESS_DBH,$SESS_LIFE;
以session关键字为条件,从表db_session检索出在有效期限内的session信息。
- 25 $qry="select value from db_session where sesskey = "$key" and expiry > ".time();
mysql_query函数执行一条 MySQL 查询。第二个参数为数据库连接,省略时使用上一个打开的连接。
- 26 $qid=mysql_query($qry,$SESS_DBH);
mysql_fetch_row从结果集中以数字数组的形式取得一行。依次调用 mysql_fetch_row() 将返回结果集中的下一行,如果没有更多行则返回 FALSE。成功时,此行的执行结果是将取出来的值放在变量$value中。
- 27 if(list($value)=mysql_fetch_row($qid)){
- 28 return $value;
- 29 }
- 30 return false;
- 31 }
向数据库中保存Session信息。
- 32 function sess_write($key,$val){
- 33 global $SESS_DBH,$SESS_LIFE;
Session的期限是当前时间加上最大有效期后的时间。
- 34 $expiry=time()+$SESS_LIFE;
- 35 $value=$val;
- 36 $qry="insert into db_session values("$key",$expiry,"$value")";
- 37 $qid=mysql_query($qry,$SESS_DBH);
插入失败,意味着数据库中已有Session记录,则对Session进行更新处理。
- 38 if(!$qid){
- 39 $qry="update db_session set expiry=$expiry,
- value="$value" where sesskey="$key" and expiry >".time();
- 40 $qid=mysql_query($qry,$SESS_DBH);
- 41 }
- 42 return $qid;
- 43 }
定义删除Session信息的sess_destroy函数,关闭画面时会执行。
- 44 function sess_destroy($key){
- 45 global $SESS_DBH;
- 46 $qry="delete from db_session where sesskey = "$key"";
- 47 $qid=mysql_query($qry,$SESS_DBH);
- 48 return $qid;
- 49 }
定义自动删除过期的Session信息的函数sess_gc。
- 50 function sess_gc($maxlifetime){
- 51 global $SESS_DBH;
- 52 $qry="delete from db_session where expiry < ".time();
- 53 $qid=mysql_query($qry,$SESS_DBH);
- 54 return mysql_affected_rows($SESS_DBH);
- 55 }
不带参数的session_module_name函数用于获取目前Session的模块。
- 56 session_module_name();
注册自定义session函数,包括打开、关闭、写入等。
- 57 session_set_save_handler("sess_open","sess_close","
sess_read", "sess_write","sess_destroy","sess_gc"); - 58 ?>
- Program 3-6 set_session_test.php
- 1 <?php
包含进行自定义Session处理文件。在所有使用自定义Session处理(本节即数据库保存方式)的页面中都必须包含此文件。
- 2 include ("session_save.php");
调用session_start函数,session处理开始。
- 3 session_start();
设置session变量。
- 4 $_SESSION["message"]= "Can I Help you?";
- 5 $_SESSION["message1"]= "No,Thanks ";
- 6 $_SESSION["from"]= "Tom";
- 7 echo "<a href="get_session_test.php">显示SESSION</a>";
- 8 ?>
- Program 3-7 get_session_test.php
- 1 <?php
- 2 include ("session_save.php");
- 3 session_start();
显示session变量。
- 4 echo $_SESSION["message"];
- 5 echo "<br>";
- 6 echo $_SESSION["message1"];
- 7 echo "<br>";
- 8 echo $_SESSION["from"];
- 9 $_SESSION["addMess"]="Hello";
- 10 ?>