Linfinity

Never say never.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

会话技术COOKIE&SEESION---解决http协议无状态

Posted on 2019-01-08 16:55  Linfinity  阅读(221)  评论(0)    收藏  举报

一、cookie技术

1.1 Cookie介绍

Cookie是客户端技术,当客户端 请求服务器的时候,随身携带数据过去

例如:我们去超市购物,买很多东西,超市会给我们办会员卡,会员卡就会保存我们购买的商品信息,以后我们只需要拿着会员卡就可以le。

 

1.2 Cookie原理介绍

当客户端请求服务器时,服务器会告诉浏览器在自己身上做一个标记(cookie)这样,以后浏览器在访问时会带着自己的cookie

 

1.3 Cookie基本使用(增删改查)

1->创建cookie(增加)

setcookie();setcookie7个参数:

参数1:保存的cookie变量名称

参数2:变量对应的值

参数3cookie文件的有效期

 

参数4:有效路径

默认情况只允许访问当前目录、当前目录子目录下面的cookie,不能访问上一级目录里面定义的cookie,子目录中可以读取到父级目录里面的cookie。

我们可以通过第4个参数设置为  / ,设置cookie起作用的路径:

/ 表示服务器的根目录,也就是在整个服务器的根目录下都起作用

 

参数5:有效域名(cookie不支持跨域使用,可以通过参数5指定cookie在哪个域名下起作用)

例如:www.jd.com 在这台主机下面定义一个cookie变量,默认无法在news.jd.com这个域名主机下面读取到,但是可以通过参数5设置

下面表示该cookie可以在jd.com这个域名以及其子域名中都可以使用,如果不设置参数5,只能在当前域名下访问

 

参数6:是否只允许在https协议下使用

如果设置为true,就表示该cookie只能在https协议下进行传输

 

参数7:为了防止cookie被劫持定义的参数,只允许在http协议下传输(在web服务器下进行传输)

如果设置为false,允许该cookie在任何协议下都能传输

例如:

我们可以在浏览器端通过javascript脚本语言读取到cookie的数据

 

 

2->读取cookie(查询)

与访问普通数组元素一样。  $_COOKIE[]

 

3->修改cookie

如果给同一个cookie变量重新赋值,就是修改的意思,而且cookie的有效期会从修改的时间重新计算

 

4->两步删除cookie

①先将cookie的有效期设置为过期

②再将$_COOKIE超全局数组中的cookie变量删除

 

1.4  Cookie细节

Cookie默认每个域名下最多创建20cookie,每个cookie文件最多存储4K左右的数据,当然chrome浏览器创建的cookie更大18KB

 

setcookie前面不能有任何输出,echo var_dump()

因为setcookie是服务器告诉浏览器的,告诉浏览器在自己身上创建cookie文件,服务器向浏览器回应信息是通过header头信息回应的。

正常的http请求时,先向浏览器发出header头信息,再输出内容,如果先echo,再发出header头信息的时候,就违反了http协议!

 

 

二、Session技术

 

2.1session的基本介绍

 说明

Session是服务器端技术,session保存的数据存储到服务器端

由于cookie每次都随身携带数据到服务器,这样的话,1. 效率比较低;2. 安全性比较低,就好比你给领导去送礼,送100万过去,一是不安全,其次效率比较低

那么session就好比是你先把钱(数据)存储到银行(服务器),银行给你一张银行卡(session_id, 把银行卡给领导,领导通过银行卡找到钱

 

示意图:

通过代码给大家演示一下

首先确定session文件保存的地址

session文件的存储路径取决于PHP的配置文件:php.ini

 

 

然后就会在服务器端创建一个session文件

 

 

2.2session的增删改查操作

(1). session 创建的基本使用

查看是否将上面的数据写入到session文件

 

(2).session的读取的基本使用

与查询普通数组相同。   $_SESSION[]

 

(3).session的修改操作

修改session也是通过$_SESSION数组进行操作,如果数组的下标已经存在,则表示修改的意思,并且会把原来的值覆盖掉

 

(4).session的删除

说明: session的删除分这么几种情况

① 删除单个session

②将所有的sessoin全部删除.

作为了解即可,实际开发时,不需要谁就删除哪个session即可

思路找到session数组中的每一个元素分别unset

不要直接删除$_SESSION这个超全局数组,因为里面除了我们创建的session数据之外,还可能有其他的数据

session文件删除和数据

session_destroy()

把创建的session文件删除

 

2.3session使用的注意事项(细节)

如何开启session 机制

1开启使用session_start()

2除了上面的方式还可以这样开启session,在php.ini这个配置文件中自动开但是我们不建议自动开启而是哪里需要就在哪里开启

 

 

关于session的几个安全配置的地方

 

 

通过ini_set 函数动态的修改php.ini 的配置项

当我们没有权限接触服务器的配置服务器的操作等情况时

我们通常就会在PHP文件中,使用ini_set()设置PHP的配置项但是通过该方法设置的配置只能在当前php脚本文件生效

 

session中可以存放什么数据类型

说明session可以存放 string ,int,float,bool,array,object 都可以,除了资源类型

sessionkey的值,只能是字符串,不能是整数

 

2.4 sesssion的存储机制

session的存储分为3个阶段:

1->session_start()开启阶段

  1. 确定浏览器身上是否携带了session_idsession文件名称),如果携带了,就使用浏览器身上的sess_id,如果没有携带session_id,则创建session文件并把session文件名称(作为session_id)回应给浏览器
  2. 初始化$_SESSION这个变量,先读取session文件里面的内容,再将内容反序列化之后,赋值给$_SESSION这个变量

在这个阶段还会判断哪些session文件已经过期了,然后再触发垃圾回收机制

 

2->脚本运行周期内:session_start()之后

php只是对$_SESSION这个变量进行增删改查的操作,需要注意:这个阶段并没有影响到session文件里面的内容,除非你在这个阶段session_destroy()了,除此之外,该阶段不会对session文件有任何影响

 

 3->脚本执行结束阶段

在这个阶段才会对session文件进行操作也就是这个阶段才会把$_SESSION数组中的数据序列化然后存储到session文件

 

一些session相关问题 

·如何清除内存中的session数据?

内存中运行的session数据就是$_SESSION这个超全局数组

 

 

·如何删除和当前session相关的所有数据

1内存中运行的session数据

2)删除session文件中保存的数据

3cookie中存储的session文件名称

 

2.5sesssionGC垃圾回收机制

说明

Session的垃圾回收机制,是当session_start()的时候会先判断哪些session文件已经过期session超过有效期之后就会触发垃圾回收机制并不是直接把过期的session文件都删除而是有概率的删除那么这个概率是怎么计算的

删除的概率 = propability/ divisor

例如

gc_propability 设置为1000,将gc_divisor设置为1000,将gc_maxlifetime设置为60,表示在60秒内如果没有做任何操作,说明该session文件过期了,删除的概率是1也就是100%删除

 

 2.6 session的存储机制重写

为什么有可能对session机制进行改写?

如果将来用户访问量特别大的时候,如果我们安装了负载均衡服务器,就会根据负载情况,将用户引导、分配到压力小的服务器上,但是我们的数据可能在原来的服务器上,这样就无法实现数据的共享了,所以我们要将session文件存储到其他地方(内存缓存中memcahe、数据库)

 

两步session入库

步骤1:

创建session数据表

create table session(sess_id varchar(32),sess_content text,last_time int)engine myisam default charset utf8;

步骤2:

开始重写session的存储机制,将session. save_handler配置项的值设置为user表示自己定义 

<?php
//修改配置文件,将session存储机制修改为user(自定义)
ini_set('session.save_handler', 'user');
//开始自己定义session的存储
//参数1:就表示session_start的时候,怎么处理
//参数2:脚本结束的时候怎么处理
//参数3:读取session数据表中数据的函数
//参数4:向session数据表写入数据的函数
//参数5:销毁session数据表中的数据的函数
//参数6:session过期之后的处理函数
session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');

session_start();

//初始化session、session_start时执行的函数
function open()
{
    //初始化数据库的链接
    $link = @mysql_connect('127.0.0.1','root','root');
    mysql_select_db("php_7");
    mysql_query("set names utf8");
}
//脚本结束的函数
function close()
{
    echo '脚本结束了...';
    return true;
}

//从session表读取数据的方法
//说明:客户端携带过来session_id,会自动传递到read里面
function read($sess_id)
{
    $sql = "SELECT sess_content FROM session WHERE sess_id='$sess_id'";
    $result = mysql_query($sql);
    $res = mysql_fetch_assoc($result);
    return $res['sess_content'];
}

//向session数据表写入数据的函数
//说明:当用户$_SESSION['name'] = 'lisi';这样操作的时候,就会把数据写入到session表
function write($sess_id,$sess_content)
{
    $sql = "INSERT INTO session VALUES('$sess_id','$sess_content',".time().")";
    return mysql_query($sql);   
}

//destroy,当执行session_destroy()删除文件,现在要删除数据表中的记录
//说明:自动传递浏览器携带的session_id
function destroy($sess_id)
{
    $sql = "DELETE FROM session WHERE sess_id = '$sess_id'";
    return mysql_query($sql);
}

//当session_start()的时候判断哪些session文件过期了,在这里会判断哪些数据过期了
//说明:会自动把session数据的有效期传递进来
function gc($max_lifetime)
{
    $time = time() - $max_lifetime;       
    $sql = "DELETE FROM session WHERE last_time < $time";   //35 36 37 38 39 40
    return mysql_query($sql);
}

// $_SESSION['name'] = 'zhangsan';
// echo '写入成功';
session_destroy();
echo '删除成功';

 

 

cookiesessoin比较

1存储位置

  cookie存储在客户端(浏览器),每次请求是随身携带,在setcookie时创建的

  session存储在服务器端,session_start的时候创建的

 

2安全性

cookie每次随身携带安全性不如session

 

3)生命周期:

Cookie的生命周期在setcookie时设置的

Session的生命周期在配置文件中的gc_maxlifetime设置但是通过cookie里面携带的PHPSESSID找到的这个cookie的有效期默认是0秒,也就是说一旦关闭了浏览器,cookie就失效了,下次访问会重新分配新的cookie

 

cookie的生命周期是累计的,session的生命周期是间隔的,以20分钟为例

cookie1  2   3  4   .....  20分钟

session1   2   3   4   ..... 19,如果从创建到第19分钟,重新访问了,会重新计算,也就是重新分配20分钟