Session详解

Posted mnhome

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Session详解相关的知识,希望对你有一定的参考价值。

1、Session简介

一个php session可以让应用存储当前"会话"的信息,它可以定义为一个哟过户登录你的应用。

一个会话是通过一个唯一的session ID来标识的。

PHP为每一个会话创建一个session ID,它是一个通过MD5对远程IP地址、当前时间和一些附加数据进行散列处理的一个显示为十六进制的字符串。这个session ID可以传递到一个cookie中或者添加到所有的URL来跨越你的应用。

为了安全考虑,让用户使用cookie会比通过URL(通常手动增加?PHP_SESSID=<session_id>或者打开php.ini中的session.use_trans_sid选项)传递session ID更好,因为通过URL传输会在Web服务器的log中以HTTP_REFERER显示出来或者让一些不怀好意的人通过监控你的浏览获取到ID。不怀好意的人还可以看到session cookie数据,当然,你可能会使用SSL的服务器来确保真正的安全。

2、Session的工作原理

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

 技术分享图片

 

3、Session的功能

由于网页是一种无状态的连接程序,因此无法得知用户的浏览状态。通过Session则可记录用户的有关信息,以供用户再次以此身份对web服务器提交时作确认。

例如,在电子上午网站中,通过session记录用户登录的信息,以及用户所购买的商品,如果没有Session,那么用户每进入一个页面都需要登录一次用户名和密码。

 

4、创建会话步骤:启动会话 —>注册会话—>使用会话—>删除会话。

启动会话:①使用session_start()函数  ② 使用session_register()函数    //为会话登录一个变量来隐含地启动会话

注意:在使用session_start()函数之前浏览器不能有任何输出,否则会产生类似错误"cannot send session cookie-headers already send by ..."。

但有时我们发现在之前有其他输出时,并没有报上面的错误,原因是php.ini配置文件里开启了缓存机制,如果想要有上面的提示,需要把配置项output_buffering设置为off,所以我们在写session_start()函数或header()函数的时候,因为不能保证配置项到底有没有开启缓存机制,所以为了避免错误,习惯性在session_start()或header()之前,不要有任何其他输出。

而使用session_register()函数时,不需要调用session_start()函数,PHP会在注册变量之后隐含地调用session_start()函数,但是需要设置php.ini文件的选项,将register_globals指令设置为"on",然后重启Apache服务器。

注册会话:会话变量被启动过后,全部保存在数组$_SESSION中。通过数组$_SESSION创建一个会话变量很容易,只要直接给该数组添加一个元素即可。

使用会话:通过全局数组$_SESSION进行访问或创建。

<?php 
/**
*判断存储用户名的Session会话变量是否存在,如果不存在则将字符串赋值给Session
*/
session_start();        //启动Session
$string="apache";
if(!isset($_SESSION[‘name‘])){    //判断用于存储用户名的Session会话变量是否存在
    $_SESSION[‘name‘]=$string;
    echo $_SESSION[‘name‘];
}else{
    echo $_SESSION[‘name‘];
}
?>

删除会话:方法主要有删除单个会话、删除多个会话和结束会话3种。

删除单个会话:同数组的操作一样,可以使用unset()直接注销$_SESSION数组的某个元素即可。

注意:使用unset()函数时,要注意$_SESSION数组种某元素不能省略,即不可以一次注销整个数组,否则会禁止整个会话。如unset($_SESSION)会将全局变量$_SESSION销毁,而且没有办法恢复,用户也再不能注册$_SESSION变量。

删除多个会话:如果想要一次注销所有的会话变量,可以将一个空的数组赋值给$_SESSION,如$_SESSION=array()。

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

 

5、Session应用

①Session临时文件

在服务器中,如果将所有的Session都保存到临时目录中,会降低服务器的安全性和效率,打开服务器存储的站点会非常慢。

可以通过session_save_path()函数存储Session临时文件,可缓解因临时文件的存储导致服务器效率降低和站点打开缓慢的问题。

技术分享图片

注意:session_save_path()函数应在session_start()函数之前调用。

②Session缓存

Session的缓存是将网页中的内容临时存储到IE客户端的Temporary Internet Files文件夹下,并且可以设置缓存的时间。

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

session_cache_limiter(‘private’);  //开启客户端缓存

session_cache_expire(分钟);  //设置客户端缓存时间,单位是分钟

<?php 
session_cache_limiter(‘private‘);    //读取或设置缓存限制器,public标识允许客户端或代理服务器缓存内容,private标表示允许客户端缓存,但是不允许代理服务器缓存内容
$cache_limit=session_cache_limiter();    //开启客户端缓存
session_cache_expire(30);
$cache_expire=session_cache_expire();    //设置客户端缓存时间,默认180分钟
session_start();
echo $cache_limit;    //private
echo ‘<br />‘;
echo $cache_expire;//30
?>

③Session数据库存储

虽然通过改变Session存储文件夹使Session不至于将临时文件夹填满而造成站点瘫痪,但是可以计算一下如果一个大型网站一天登录1000人,一个月登录了30000人,这时站点中存在30000个Session文件,要在30000个文件中查询一个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个函数,而且在调用时只是调用函数名称的字符串。

session数据表

技术分享图片

 

下面开始讲解这6个参数(函数),最后把这些封装进类中。

 

<?php 
//封装_session_open()
//这里并没有用到$save_path和$session_name,可以将它们去掉,但还是建议输入,因为一般使用时都是存在这两个变量的,应该养成一个好的习惯
 function _session_open($save_path,$session_name){
    global $handle;
    $handle=mysql_connect(‘localhost‘,‘root‘,‘123‘)or die(‘数据库连接失败‘);    //连接MySQL数据库
    mysql_select_db(‘mydb8‘,$handle)or die(‘数据库中没有此库名‘);    //找到数据库
    return (true);
}


//封装_session_close()函数,关闭数据库连接
//在这个函数中不需要任何参数,所以不论是Session存储到数据库还是文件中,只需返回true即可
//但是如果是MySQL数据库,最好是将数据库关闭,以保证以后不会出现麻烦。
function _session_close(){
    global $handle;
    mysql_close($handle);
    return(true);
}

//封装_session_read()函数,在函数中设定当前时间的UNIX时间戳,根据$key值查找Session名称及内容
function _session_read($key){
    global $handle;    //全局变量$handle连接数据库
    $time=time();    //设定当前时间
    $sql="select session_data from t_session where session_key=‘$key‘ and lapse_time>$time";
    $result=mysql_query($sql,$handle);
    $row=mysql_fetch_array($result);
    if($row){
        return ($row[‘session_data‘]);        //返回Session名称及内容
    }else{
        return (false);
    }
}

//封装_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;    //设置生效时间
    $handle=mysql_connect(‘localhost‘,‘root‘,‘123‘) or die(‘数据库连接失败‘);    //连接MySQL数据库
    mysql_select_db(‘mydb8‘,$handle);    //选择数据库
    $sql="select session_data from t_session where session_key=‘$key‘ and lapse_time>$lapse_time";
    $result =mysql_query($sql,$handle);
    if(mysql_num_rows($result)==0){
        $sql="insert into t_seession values(‘$key‘,‘$data‘,$lapse_time)";    //插入数据库sql语句
        $result=mysql_query($sql,$handle);
    }else{
        $sql="update t_session set session_key =‘$key‘,session_data=‘$data‘,session_time=$lapse_time where session_key=‘$key‘";    
    }
    return ($result);
}

//封装_session_destroy()函数,根据$key值将数据库中的session删除
function  _session_destroy($key){
    global $handle;
    $sql="delete from t_session where session_key =‘$key‘";    //删除数据库sql语句
    $result=mysql_query($sql,$handle);
    return ($result);
}

//封装_session_gc()函数,根据给出的失效时间删除过期Session
function _session_gc(){
    global $handle;
    $lapse_time=time();    //将参数$lapse_time赋值为当前时间戳
    $sql="delete from t_session where session_time <$lapse_time";    //删除数据库sql语句
    $result=mysql_query($sql,$handle);
    return ($result);
}

//ini_set(‘session.save_handler‘,‘user‘);

session_set_save_handler(‘_session_open‘,‘_session_close‘,‘_session_read‘,‘_session_write‘,‘_session_destroy‘,‘_session_gc‘);
session_start();
//下面通过函数session_set_save_handler()实现Session存储数据库
//定义Session
$_SESSION[‘user‘]=‘mr‘;
$_SESSION[‘pwd‘]=‘mrsoft‘;

 

以上是关于Session详解的主要内容,如果未能解决你的问题,请参考以下文章

(转) Java中的负数及基本类型的转型详解

详解Android WebView加载html片段

Spring Security---验证码详解

python接口自动化(十四)--session关联接口(详解)

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段

Python中verbaim标签使用详解