11.2 Session管理
视频讲解:光盘TMlx11Session管理.exe
对比Cookie,会话文件中保存的数据是在PHP脚本中以变量的形式创建的,创建的会话变量在生命周期(20分钟)中可以被跨页的请求所引用。另外,Session是存储在服务器端的会话,相对安全,并且不像Cookie那样有存储长度的限制。
11.2.1 了解Session
1.什么是Session
Session译为“会话”,其本义是指有始有终的一系列动作/消息,如打电话时从拿起电话拨号到挂断电话这一系列过程可以称为一个Session。
在计算机专业术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统所经过的时间。因此,Session实际上是一个特定的时间概念。
2.Session工作原理
当启动一个Session会话时,会生成一个随机且唯一的session_id,也就是Session的文件名,此时session_id存储在服务器的内存中,当关闭页面时此id会自动注销,重新登录此页面,会再次生成一个随机且唯一的id。
3.Session的功能
Session在web技术中非常重要。由于网页是一种无状态的连接程序,因此无法得知用户的浏览状态。通过Session则可记录用户的有关信息,以供用户再次以此身份对Web服务器提交要求时作确认。例如,在电子商务网站中,通过Session记录用户登录的信息,以及用户所购买的商品,如果没有Session,那么用户每进入一个页面都需要登录一次用户名和密码。
另外,Session会话适用于存储信息量比较少的情况。如果用户需要存储的信息量相对较少,并且对存储内容不需要长期存储,那么使用Session把信息存储到服务器端比较合适。
11.2.2 创建会话
创建一个会话需要通过以下步骤:启动会话→注册会话→使用会话→删除会话。
1.启动会话
启动PHP会话的方式有两种:一种是使用session_start()函数,另一种是使用session_register()函数,为会话登录一个变量来隐含地启动会话。
注意
通常,session_start()函数在页面开始位置调用,然后会话变量被登录到数据$_SESSION。
在PHP中有两种方法可以创建会话。
通过session_start()函数创建会话。
语法格式如下:
bool session start(void) ;
说明
使用session_start()函数之前浏览器不能有任何输出,否则会产生类似于如图11.6所示的错误。
图11.6 在使用session_start()函数前输出字符串产生的错误
注意
使用session_register()函数时,不需要调用session_start()函数,PHP会在注册变量之后隐含地调用session_start()函数。
2.注册会话
会话变量被启动后,全部保存在数组$_SESSION中。通过数组$_SESSION创建一个会话变量很容易,只要直接给该数组添加一个元素即可。
例如,启动会话,创建一个Session变量并赋予空值,代码如下:
<?php session_start(); //启动Session $_SESSION["admin"]=null; //声明一个名为admin的变量,并赋空值 ?>
3.使用会话
首先需要判断会话变量是否有一个会话ID存在,如果不存在,就创建一个,并且使其能够通过全局数组$_SESSION进行访问。如果已经存在,则将这个已注册的会话变量载入以供用户使用。
例如,判断存储用户名的Session会话变量是否为空,如果不为空,则将该会话变量赋给$myvalue,代码如下:
<?php if(! empty($_SESSION['session_name'])) //判断用于存储用户名的Session会话变量是否为空 $myvalue=$_SESSION['session_name']; //将会话变量赋给一个变量$myvalue ?>
4.删除会话
删除会话的方法主要有删除单个会话、删除多个会话和结束当前会话3种,下面分别进行介绍。
(1)删除单个会话
删除会话变量,同数组的操作一样,直接注销$_SESSION数组的某个元素即可。
例如,注销$_SESSION['user']变量,可以使用unset()函数,代码如下:
unset ( $_SESSION['user'] ) ;
注意
使用unset()函数时,要注意$_SESSION数组中某元素不能省略,即不可以一次注销整个数组,这样会禁止整个会话的功能,如unset($_SESSION)函数会将全局变量$_SESSION销毁,而且没有办法将其恢复,用户也不能再注册$_SESSION变量。如果要删除多个或全部会话,可采用下面的两种方法。
(2)删除多个会话
如果想要一次注销所有的会话变量,可以将一个空的数组赋值给$_SESSION,代码如下:
$_SESSION = array() ;
(3)结束当前会话
如果整个会话已经结束,首先应该注销所有的会话变量,然后使用session_destroy()函数清除结束当前的会话,并清空会话中的所有资源,彻底销毁Session,代码如下:
session_destroy() ;
11.2.3 Session设置时间
在大多数论坛中都可在登录时对登录时间进行选择,如保存一个星期、保存一个月等。这时就可以通过Cookie设置登录的失效时间。
1.客户端没有禁止Cookie
(1)使用session_set_cookie_params()设置Session的失效时间,此函数是Session结合Cookie设置失效时间,如要让Session在1分钟后失效,实例关键代码如下:
<?php $time=1*60; //设置Session失效时间 session_set_cookie_params($time); //使用函数 session_start(); //初始化Session $_SESSION[username] = 'mr'; ?>
注意
session_set_cookie_params()必须在session_start()之前调用。
说明
不推荐使用session_set_cookie_params()函数,此函数在一些浏览器上会出现问题。所以一般手动设置失效时间。
(2)使用setcookie()函数可对Session设置失效时间,如让Session在1分钟后失效,实例关键代码如下:
<?php session_start(); $time=1*60; //给出Session失效时间 setcookie(session_name(), session_id(), time()+$time, "/"); //使用setcookie()手动设置Session失效时间 $_SESSION['user'] = "mr"; ?>
说明
session_name是Session的名称,session_id是判断客户端用户的标识,因为session_id是随机产生的唯一名称,所以Session是相对安全的。失效时间和Cookie的失效时间一样,最后一个参数为可选参数,是放置Cookie的路径。
2.客户端禁止Cookie
当客户端禁用Cookie时,Session页面间传递会失效,可以将客户端禁止Cookie想象成一家大型连锁超市,如果在其中一家超市内办理了会员卡,但是超市之间并没有联网,那么会员卡就只能在办理的那家超市使用。解决这个问题有4种方法:
(1)在登录之前提醒用户必须打开Cookie,这是很多论坛的做法。
(2)设置php.ini文件中的session.use_trans_sid = 1,或者编译时打开-enable-trans-sid选项,让PHP自动跨页面传递session_id。
(3)通过GET方法,隐藏表单传递session_id。
(4)使用文件或者数据库存储session_id,在页面传递中手动调用。
第2种情况不作详细讲解,因为用户不能修改服务器中的php.ini文件。第3种情况我们就不可以使用Cookie设置保存时间,但是登录情况没有变化。第4种也是最为重要的一种,在开发企业级网站时,如果遇到Session文件使服务器速度变慢,就可以使用。在Session高级应用中会作详细解说。
第3种情况使用GET方式传输,实例关键代码如下:
<form id="form1" name="form1" method="post" action="common.php? <? =session_ name(); ?>= <? =session_id(); ?>">
接收页面头部详细代码:
<?php $sess_name=session_name(); //取得Session名称 $sess_id=$_GET[$sess_name]; //取得session_id GET方式 session_id($sess_id); //关键步骤 session_start(); $_SESSION['admin'] = 'mrsoft'; ?>
运行结果如图11.7所示。
图11.7 使用GET方式传递session_id
说明
Session原理为请求该页面之后会产生一个session_id,如果这个时候禁止了Cookie就无法传递session_id,在请求下一个页面时将会重新产生一个session_id,这样就造成了Session在页面间传递失效。
11.2.4 通过Session判断用户的操作权限
在大多数网站的开发过程中,需要对管理员和普通用户操作网站的权限进行划分。下面通过具体的实例进行讲解。
首先通过用户登录页面提交的用户名来验证用户操作网站的权限。
【例11.3】本例通过Session技术实现如何判断用户的操作权限。(实例位置:光盘TMsl113)
具体开发步骤如下:
(1)设计登录页面,添加一个表单form1,应用POST方法进行传参,action指向的数据处理页为default.php,添加一个用户名文本框并命名为user,添加一个密码域文本框并命名为pwd,关键代码如下:
<form name="form1" method="post" action="default.php"> <table width="521" height="394" border="0" cellpadding="0" cellspacing="0"> <tr> <td valign="top" background="images/login.jpg"> <table width="521" border="0" cellspacing="0" cellpadding="0"> <tr> <td height="24" align="right">用户名:</td> <td height="24"align="left"><input name="user"type="text"id="user"size="20"></td> </tr> <tr> <td height="24" align="right">密  ;码:</td> <td height="24"align="left"><input name="pwd"type="password"id="pwd"size="20"></td> </tr> <tr align="center"> <td height="24" colspan="2"><input type="submit" name="Submit" value="提交" onClick= "return check(form); "><input type="reset"name="Submit2"value="重填"></td> </tr> <tr> <td height="76" align="right"><span class="style1">超级用户:tsoft<br> 密  ;码:111 </span></td> <td><span class="style1">普通用户:zts<br>密  ;码:000</span></td> </tr> </table> </td> </tr> </table> </form>
(2)在“提交”按钮的单击事件下,调用自定义函数check()来验证表单元素是否为空。自定义函数check()的代码如下:
<script language="javascript"> function check(form){ if(form.user.value==""){ alert("请输入用户名"); form.user.focus(); return false; } if(form.pwd.value==""){ alert("请输入密码"); form.pwd.focus(); return false; } form.submit(); } </script>
(3)提交表单元素到数据处理页default.php,首先使用session_start()函数初始化Session变量,然后通过POST方法接收表单元素的值,将获取的用户名和密码分别赋给Session变量,代码如下:
<?php session start(); $ SESSlON['user']=$ POST['user']; $ SESSlON['pwd']=$ POST['pwd']; ?>
(4)为了防止其他用户非法登录本系统,使用if条件语句对Session变量值进行判断,代码如下:
<?php if($ SESSlON['user']==""){ //如果用户名为空,则弹出提示,并跳转到登录页 echo "<script language='Javascript'>alert(’请通过正确的途径登录本系统!'); history.back(); </script>"; } ?>
(5)在数据处理页default.php的导航栏处添加如下代码:
<TABLE align="center" cellPadding=0 cellSpacing=0 > <TR align="center" valign="middle"> <TD style="WIDTH: 140px; COLOR: red; ">当前用户: <! -- ----------------------------------输出当前登录的用户级别----------------------------------- --> <?php if($ SESSlON['user']=="tsoft"&&$ SESSlON['pwd']=="111"){echo"管理员"; }else{echo"普 通用户"; } ?> </TD> <TD width="70"><a href="default.php">博客首页</a></TD> <TD width="70">| <a href="default.php" >我的文章</a></TD> <TD width="70">| <a href="default.php" >我的相册</a></TD> <TD width="70">| <a href="default.php">音乐在线</a></TD> <TD width="70">| <a href="default.php">修改密码</a></TD> <?php if($ SESSlON['user']=="tsoft"&&$ SESSlON['pwd']=="111"){ //如果当前用户是管理员 ?> <! -- -------------------------如果当前用户是管理员,则输出“用户管理”链接------------------------ --> <TD width="70">| <a href="default.php">用户管理</a></TD> <?php } ?> </TR> </TABLE>
(6)在default.php页面添加“注销用户”超链接页safe.php,该页代码如下:
<?php session start(); //初始化Session unset($_SESSION['user']); //删除用户名会话变量 unset($_SESSION['pwd']); //删除密码会话变量 session destroy(); //删除当前所有的会话变量 header("location:index.php"); //跳转到博客用户登录页 ?>
(7)运行本例,在博客用户登录页面输入用户名和密码,以超级用户的身份登录网站,运行结果如图11.8所示。以普通用户身份登录网站的运行结果如图11.9所示。
图11.8 超级用户登录网站的运行结果
图11.9 普通用户登录网站的运行结果
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。