PHP学习笔记-Session

转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/52262182
本文出自:【顾林海的博客】

前言

上一篇讲述了Cookie管理,我们知道Cookie是服务器留在用户计算机中的小文件。每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie。并且数
据信息是以明文文本的形式保存在客户端计算机中,因此最好不要保存一些含有敏感的、未加密的数据,否则会影响网络的安全性。
对比Cookie,Session会话文件中保存的数据在PHP脚本中是以变量的形式创建的,创建的会话变量在生命周期中可以被跨页的请求所引用。另外,Session会话是存储在服务器端的,相对安全,并且不像Cookie那样有存储长度的限制。

Session使用前的准备

在进行Session使用前,我们需要知道什么是Session、原理以及它的功能。

什么是Session

Session译为“会话”,其本义是指有始有终的一系列动作/消息,如打电话时从拿起电话拨号到挂断电话这一系列过程可以称为一个Session。
在计算机专业术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统所经过的时间。因此,Session实际上是一个特定的时间概念。

工作原理

当启动一个Session会话时,会生成一个随机且唯一的session_id,也就是Session的文件名,此时session_id存储在服务器的内存中,当关闭页面时此id会自动注销,重新登录此页面,会再次生成一个随机且唯一的id。

Session的功能

Session在Web技术中非常重要。由于网页是一种无状态的连接程序,因此无法得知用户的浏览状态。通过Session则可记录用户相关信息,以供用户再次以此身份对Web服务器提交要求时作确认。例如,在电子商务网站中,通过Session记录用户登录的信息,以及用户所购买的商品,如果没有Session,那么用户每进入一个页面都需要登录一次用户名和密码。
另外,Session会话适用于存储信息量比较少的情况。如果用户需要存储的信息量相对较少,并且对存储内容不需要长期存储,那么使用Session把信息存储到服务器端比较合适。

Session的使用

创建一个Session需要以下几个步骤:

  1. 启动会话
  2. 注册会话
  3. 使用会话
  4. 删除会话

1、启动会话的方式有两种,一种是使用session_start()函数,另一种方式是使用session_register()函数为会话创建一个变量来隐含地启动会话。

session_start()函数在页面开始位置调用,然后会话变量被登录到数据$_SESSION。

通过session_register()函数用来为会话创建一个变量来隐含地启动会话,但要求设置php.ini文件的选项,即将register_globals指令设置为on,然后重新启动Apache服务器即可;使用session_register()函数时不需要调用session_start()函数,PHP会在创建变量之后隐含地调用session_start()函数。

2、会话变量被创建后,全部保存在数组 SESSION _SESSION创建一个会话变量很容易,只要直接给该数组添加一个元素即可。

<?php
/**
 * Created by IntelliJ IDEA.
 * User: 蛋蛋球
 * Date: 2016/8/20
 * Time: 14:41
 */

session_start();
$_SESSION["admin"]=null;

?>

上述程序中第一行代码是用于启动Session,第二行代码是声明一个名为admin的变量,并赋空值。

3、使用会话时,我们需要判断会话变量是否有一个会话ID存在,如果不存在,就需要创建一个,并且使其能够通过全局数组$_SESSION进行访问;如果已经存在,则将这个已经创建的会话变量载入以供用户使用。

<?php
if(!empty($_SESSION['session_name'])){
    $myvalue=$_SESSION['session_name'];
}
?>

就像上述程序,先判断用于存储用户名的Session会话变量是否为空,不为空时,将会话变量赋给一个变量$myvalue。

4、删除会话的方法主要有删除单个会话、删除多个会话和结束当前会话3种,下面分别介绍这三种。

(1)删除单个会话即删除单个会话变量,同数组的操作一样,直接注销$_SESSION数组的某个元素即可。

<?php
unset($_SESSION['user']);
?>

使用unset()函数时,要注意$_SESSION数组中元素不能省略,即不可以一次注销整个数组,这样会禁止整个会话的功能,如unset($_SESSION)函数会将全局变量$_SESSION销毁,而且没有办法将其恢复,用户也不能再注册$_SESSION变量。如果要删除多个或全部会话,可采用下面的两种方法。

(2)删除多个会话即一次注销所有的会话变量,可以通过将一个空的数组赋值给$_SESSION来实现。

<?php
$_SESSION=array();
?>

(3)如果整个会话已经结束,首先应该注销所有的会话变量,然后使用session_destroy()函数清除结束当前的会话,并清空会话中的所有资源,彻底销毁Session。

<?php
session_destroy();
?>

给Session设置时间

Session失效时间设置主要有两种方式:

1、客户端没有禁止Cookie

(1)使用session_set_cookie_params()设置Session的失效时间,此函数时Session结合Cookie设置失效时间。以下示例让Session在1分钟后失效:

<?php
$time=1*60;
session_set_cookie_params($time);
session_start();
$_SESSION[username]='mr';
?>

session_set_cookie_params()必须在session_start之前调用。
不推荐使用此函数,此函数在一些浏览器上会出现问题,所有一般手动设置失效时间。

(2)使用setcookie()函数对Session设置失效时间,如让Session在1分钟后失效:

<?php
session_start();
$time=1*60;
setcookie(session_name(),session_id(),time()+$time,"/");
$_SESSION['user']="mr";
?>

在上面程序的setcookie()函数中,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设置失效时间,但是登陆情况没有变化。

我们基于第3种方法使用GET方法传输,先看实际效果图:

这里写图片描述

<?php 
header("Content-Type:text/html;charset=utf-8");
session_start(); 
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登录页面</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
</head>

<body>
<table width="328" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td height="100"></td>
  </tr>
  <tr>
    <td height="214" valign="top" background="images/index_01.jpg">
    <form id="form1" name="form1" method="post" action="common.php?<?=session_name(); ?>=<?=session_id(); ?>">
    <table width="100%" height="171" border="0" cellpadding="0" cellspacing="0">
      <tr>
        <td width="200" height="60"></td>
        <td>&nbsp;</td>
      </tr>
      <tr>
        <td align="right" class="white12">用户名:</td>
        <td>
            <input name="username" type="text" size="15" />        
        </td>
      </tr>
      <tr>
        <td align="right" class="white12">密&nbsp; 码:</td>
        <td><input name="password" type="password" size="15" /></td>
      </tr>
      <tr>
        <td>&nbsp;</td>
        <td valign="bottom"><input type="submit" name="Submit" value="登 录" />
          <input type="reset" name="Submit2" value="取 消" /></td>
      </tr>
    </table>
    </form>
    </td>
  </tr>
</table>
</body>
</html>

上面是我们的登陆主界面的代码。在最上面执行了session_start();
这时会话变量被登录到数据$_SESSION。

看到点击登陆是地址栏会显示session的ID,并在当前目录下的tmp文件夹下生产一个以sess_开头加上sessionID的文件,查看文件内容可以发现存储着以下值:

admin|s:6:”mrsoft”;

这时点击登陆执行以下代码:

<form id="form1" name="form1" method="post" action="common.php?<?=session_name(); ?>=<?=session_id(); ?>">

点击登陆按钮后执行common.php脚本,继续查看common.php:

<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
$path = './tmp/';
$sess_name = session_name();
$sess_id = $_GET[$sess_name];
session_id($sess_id);
session_save_path($path);
session_start();
if ((trim($_POST['username'])) != 'tm' or (trim($_POST['password']) != '111'))
{
    echo "<script>alert('用户名与密码错误!');location.href='index.php'</script>";
}
$_SESSION['admin'] = 'mrsoft';
?>
<link href="css/style.css" rel="stylesheet" type="text/css" />

<table width="328" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td height="100"></td>
  </tr>
  <tr>
    <td height="214" valign="top" background="images/index_01.jpg"><table width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td width="100"></td>
        <td height="70"></td>
      </tr>
      <tr>
        <td align="center" valign="middle">&nbsp;</td>
        <td height="80" align="center" valign="middle"><p class="white12"> &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 恭喜您登录成功<a href="connect.php?<?=session_name(); ?>=<?=session_id() ?>">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 请点击转入内容页面</a></p>
          </td>
      </tr>
    </table></td>
  </tr>
</table>

代码比较简单,先是获取session的名称,然后根据session名称获取session的ID,然后通过session_id()函数存取目前 session的ID,并保存在当前路径下的tmp文件夹下。最后通过$_SESSION[‘admin’] = ‘mrsoft’;将mrsoft值保存在服务器中以便你其他模块操作的使用 。

假设我们将tmp文件夹下的生成的文件删除,点击登陆按钮执行以下代码:

<form id="form1" name="form1" method="post" action="connect.php?<?=session_name(); ?>=<?=session_id(); ?>">

这里写图片描述

<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
$sess_name = session_name();
$sess_id = $_GET[$sess_name];
session_id($sess_id);
session_save_path('./tmp/');
session_start();
if ($_SESSION['admin'] == "")
{
    echo "<script>alert('对不起,你没有权限');location.href='index.php'</script>";
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>后台管理页面</title>
<link href="css/style.css" rel="stylesheet" type="text/css" />
</head>

<body>
<table width="779" height="712" border="0" align="center" cellpadding="0" cellspacing="0" background="images/index_02.jpg">
  <tr>
    <td></td>
  </tr>
</table>
</body>
</html>

从上面程序可以看出来登陆时会去检查session的ID生成的文件中是否有admin,为空时,说明没有权限,当然之前tmp文件下的文件如果不删除的话,可以直接登陆进入,无需用户名和密码。

Session高级应用

session的临时文件

在服务器中,如果将所有用户的Session都保存到临时目录中,会降低服务器的安全性和效率,打开服务器存储的站点会非常慢。使用PHP函数session_save_path()存储Session临时文件,可缓解因临时文件的存储导致服务器效率降低和站点打开缓慢的问题。

<?php
$path = './tmp/';                          // 设置session存储路径
session_save_path($path);                  
session_start();                            // 初始化session
$_SESSION[username] = true;
echo "Session文件名称为:sess_" , session_id();
?>

session缓存

Session的缓存是将网页中的内容临时存储到IE客户端的Temporary Internet Files文件夹下,并且可以设置缓存的时间。当第一次浏览网页后,页面的部分内容在规定的时间内就被临时存储在客户端的临时文件夹中,这样在下次访问这个页面时,就可以直接读取缓存中的内容,从而提高网站的浏览效率。

Session缓存的完成使用的是session_cache_limiter()函数,其语法如下:

string session_cache_limiter ( [string cache_limiter])

参数cache_limiter为public或private。同时Session缓存并不是指在服务器端而是客户端缓存,在服务器中没有显示。

缓存时间的设置,使用的是session_cache_expire()函数,其语法如下:

int session_cache_expire ( [int new_cache_expire])

参数cache_expire是Session缓存的时间数字,单位是分钟。

下面是Session缓存页面过程:

<?php
session_cache_limiter('private');
$cache_limit = session_cache_limiter();

session_cache_expire(30);
$cache_expire = session_cache_expire();

session_start();
?>
<html>
<head>
<title>Session客户端缓存</title>
</head>
<style type="text/css">
<!--
.black12 {
    font-family: "宋体";
    font-size: 12px;
    line-height: 30px;
    color: #000000;
    text-decoration: none;
}
.red12 {
    font-family: "宋体";
    font-size: 12px;
    line-height: 30px;
    color: red;
    text-decoration: none;
}
-->
</style>

<body>
<table width="502" height="300" border="0" align="center" cellpadding="0" cellspacing="0" background="images/index_01.jpg">
  <tr>
    <td valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td height="120">&nbsp;</td>
      </tr>
      <tr>
        <td align="center" class="black12">缓存限制为 <span class="red12"><?=$cache_limit ?></span></td>
      </tr>
      <tr>
        <td align="center" class="black12">缓存Session页面失效时间在 <span class="red12"><?=$cache_expire ?></span> 分钟之后</td>
      </tr>
    </table></td>
  </tr>
</table>
</body>
</html>

Session数据库存储

通过改变Session存储文件夹使Session不至于将临时文件夹填满而造成站点瘫痪,但一个网站一天登陆几千人,一个月就上万人,这时站点中就存在这么多Session文件,要在这些文件中查询某个session_id也不是一件轻松的事情。这时就可以用Session数据库存储,也就是PHP中的session_set_save_handler()函数。

语法格式如下:

bool session_set_save_handler ( string open, string close, string read, string write, string destroy, string gc)
参数说明
open(save_path,session_name)找到Session存储地址,取出变量名称
close()不需要参数,关闭数据库
read(key)读取Session键值,key对应session_id
write(key,data)其中data对应设置的Session变量
destroy(key)注销Session对应Session键值
gc(expiry_time)清除过期Session记录

一般应用参数直接使用变量,但是此函数中参数为6个函数,而且在调用时只是调用函数名称的字符串,下面将分别讲解这6个参数(函数),最后将把这些封装进类中。

(1)封装session_open()函数,连接数据库,代码如下:

function _session_open($save_path,$session_name)
{
     global $handle;
     $handle = mysql_connect('localhost','root','root') or die('数据库连接失败');     //连接MySQL数据库
     mysql_select_db('db_database11',$handle) or die('数据库中没有此库名');     //找到数据库
     return(true);
}

2)封装session_close()函数,关闭数据库连接,代码如下:

function _session_close()
{
    global $handle;
    mysql_close($handle);
    return(true);
} 

在这个参数中不需要任何参数,所以不论是Session存储到数据库还是文件中,只需返回true即可。但是如果是MySQL数据库,最好是将数据库关闭,以保证以后不会出现麻烦。

(3)封装session_read()函数,在函数中设定当前时间的UNIX时间戳,根据$key值查找Session名称及内容,代码如下:

function _session_read($key)
{
    global $handle;	//全局变量$handle连接数据库
    $time = time();         //设定当前时间   
    $sql = "select session_data from tb_session where session_key = '$key' and session_time > $time";
    $result = mysql_query($sql,$handle);
    $row = mysql_fetch_array($result);
    if ($row){
        return($row['session_data']);          //返回Session名称及内容
    }else{
        return(false);
    }
}

存储进数据库中的session_expiry是UNIX时间戳。

(4)封装session_write()函数,函数中设定Session失效时间,查找到Session名称及内容,如果查询结果为空,则将页面中Session根据session_id、session_name、失效时间插入数据库中;如果查询结果不为空,则根据$key修改数据库中Session存储信息,返回执行结果,代码如下:

function _session_write($key,$data)
{
    global $handle;
    $time = 60*60;   //设置失效时间
    $lapse_time = time() + $time; //得到UNIX时间戳         $sql = "select session_data from tb_session where session_key = '$key' and session_time > $lapse_time";
    $result = mysql_query($sql,$handle);
    if (mysql_num_rows($result) == 0 ) {   //没有结果
    $sql = "insert into tb_session values('$key','$data',$lapse_time)";//插入数据库sql语句
        $result = mysql_query($sql,$handle);
    }else{
        $sql = "update tb_session set session_key = '$key',session_data = '$data',session_time = $lapse_time where session_key = '$key'";	 //修改数据库sql语句		$result = mysql_query($sql,$handle);
    }
    return($result);
} 

(5)封装session_destroy()函数,根据$key值将数据库中Session删除,代码如下:

function _session_destroy($key)
{
    global $handle;
    $sql = "delete from tb_session where session_key = '$key'";            //删除数据库sql语句
    $result = mysql_query($sql,$handle);
    return($result);
} 

(6)封装session_gc()函数,根据给出的失效时间删除过期Session,代码如下:

function _session_gc($expiry_time)
{
    global $handle;
    $lapse_time = time();						//将参数$expiry_time赋值为当前时间戳
    $sql = "delete from tb_session where expiry_time < $lapse_time";  //删除数据库sql语句
    $result = mysql_query($sql,$handle);
    return($result);
}

以上为session_set_save_handler()函数的6个参数(函数)。

至此关于PHP的Session讲解完毕。

已标记关键词 清除标记
相关推荐
目录 HTML 1 小知识点 1 表格 3 Frameset 5 Form/input 8 Map 11 HTML5 12 canvas 12 HTML5废除的标签 13 XML 15 基本语法 15 DTD校验 16 在xml文件中引入dtd文件的两种方式 17 DTD元素和修饰符 17 元素属性列表说明 17 实体定义分两种 18 使用php对xml文件进行操作 19 CSS 23 margin 26 element 28 box 29 position 31 apache 34 PHP 36 数据类型 36 一.双引号与单引号 36 二.运算符 36 三.字符串拼接 36 四.类型运算符 36 五.switch语句 36 六.全局变量 37 七.预定义变量 37 函数 39 数组 40 一.用字符串做下标 40 二.使用小数作为key将,自动截断小数部分 40 四.删除数组元素 40 六.二维数组。 40 类 41 一.重载 41 二.覆盖 41 三.抽象类 41 四.final 42 五.const 42 时间 42 一.输出日期 42 错误处理 43 一.自定义错误处理函数 43 二.触发器 43 三.异常处理 43 四.设置顶级异常处理器 45 防盗链 45 HTTP 46 经过一定时间跳转到指定页面 46 不让浏览器缓存 46 cookie 47 session 47 php.ini中关于session和cookie的配置说明 50 文件操作 51 文件读取 51 文件下载 52 文件上传 53 写入文件 54 拷贝文件 54 文件和文件夹的创建和删除 55 画图 56 画饼状图 56 案例一:投票柱状统计图 57 案例二:验证码 59 GD库 60 PHP和数据库 64 mysql扩展库 64 一.创建一张用户表 64 二.查询数据库中的表 64 三.增删改查类 65 四.数据库操作函数 66 mysqli扩展库 69 一.查询数据库中的表 69 二.释放资源的方式 69 三.增删该查类 69 四.预编译 70 mail 71 ZendFramework 73 快速体验 73 修改数据 74 增加数据 74 查询数据 74 memcached 76 telnet操作 76 php中使用memcached 78 把session数据放入memcache中 79 小知识点 80
©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页