PHP基础知识点【九】会话控制(Cookie与Session)

当我们在浏览网站时候访问的web页面HTTP协议使用的无状态协议,即每个 HTTP 请求之间是相互独立的,所以不能维护两个事务之间的状态,那么服务器怎么知道这是同一个用户在请求页面还是不同用户。利用会话控制的特点面向连接可靠通信方式,其主要思想就是允许服务器追踪同一个用户发出的连续请求。PHP常用的方式有Cookie和Session。

        在网站中,我们经常需要跟踪一个变量,通过对变量的跟踪,使多个请求事物之间建立联系,再根据授权和用户身份显示不同的内容、不同页面,这就是会话控制技术。简单地说,Cookie 是通过在客户端中记录信息而确定用户身份;Session 是通过在服务器端记录信息而确定用户身份。EMMM,没有画图,下面字有点多不太好理解。

目录

一、Cookie

(1)工作原理

(2)PHP如何设置Cookie

(3)设置Cookie并获取Cookie

(4)设置过期时间

(5)设置保存路径

(6)可以看一下请求头的一些信息

(7)数组形态的Cookie

(8)获取Cookie二维数组的值

(9)setrawcookie()函数

(10)删除Cookie

二、Session

(1)工作原理

(2)PHP设置Session与读取Session

(3)销毁变量与销毁Session

(4)Session的注销过程

(5)Session的垃圾自动回收机制

(6)传递SessionID

三、Cookie与Session的区别


一、Cookie

(1)工作原理

        Cookie 是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制,是一种由服务器向客户端发送的片段信息。

        Cookie的中文含义是“小甜饼”,是很小很小的文件,它存储在客户端浏览器的内存或者硬盘上。包含在HTTP请求报文中,并在服务器中与浏览器之间传递。但是这个也不是服务器随意给浏览器的,需要浏览器使用Cookie为服务器记录一些信息。

 

         举个例子:把这个web服务器比作一家商场,商场里面的每个店面是一个web页面,而Cookie就相当于你第一次进入这家商场的时候商场给你办理的会员卡,但是会存储你的姓名手机号类似的 ,就会允许你在每一个店里享受优惠条件,只要在会员卡有效时间内,你任何时间都可以来这家商场拿着你的会员卡,你就会被看作商场的会员。

 

看一下Cookie具体的流程:

  1. 用户第一次登陆输入登陆的信息(例如账号密码)然后请求服务器进行登陆,第一次登陆验证成功后。服务器通过在 HTTP 响应报文中设置一个 Set-Cookie 字段,并把 Cookie 数据放在 Set-Cookie 字段中以HTTP 报文传给浏览器;

  2. 浏览器在接收到 HTTP 响应报文后,检查到 Set-Cookie 字段有值,会在本地创建一个 Cookie 文件以键值对的形式来保存数据;

  3. 当浏览器再次向同一个服务器发送请求其他脚本时,浏览器会先搜索本地保存的 Cookie 文件,如果在 Cookie 文件中有任何与正在连接的 URL 相关的 Cookie,就在 HTTP 请求报文中设置一个 Cookie 字段,并把 Cookie 文件中的数据添加到该字段中,最后把携带 Cookie 字段的 HTTP 请求报文发送给服务器

  4. 服务器的每个脚本都可以接受Cookie的数据,并重新对登陆者的身份进行验证,而不是每次用户都需要重新去输入登陆信息。

(2)PHP如何设置Cookie

       PHP 透明地支持 HTTP Cookie。Cookie是一种在远程浏览器端储存数据并以此来跟踪和识别用户的机制。可以用 setcookie()setrawCookie() 函数来设置 Cookie。Cookie是 HTTP 标头的一部分,因此 setCookie() 函数必须在其它信息被输出到浏览器前调用,这和对 header() 函数的限制类似。可以使用输出缓冲函数来延迟脚本的输出,直到按需要设置好了所有的 cookie 或者其它HTTP头。

  • setcookie()函数
PHP官网setcookie()函数解释:
	https://www.php.net/manual/zh/function.setcookie.php
函数用法:
    setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] ) : bool
作用:
	一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。
参数:
	$name	Cookie的识别名称				  随后可以利用$_COOKIE['name']获取对应value
	$value	Cookie的值,以数值或者字符串形态	这个值储存于用户的电脑里,请勿储存敏感信息。
	$expire Cookie过期时间,以时间戳的形式 如果设置成零或者不写 Cookie 会在会话结束时过期(也就是关掉浏览器时)
	$path	Cookie有效的服务器路径, 默认值是设置 Cookie 时的当前目录。
	$domain	Cookie所属服务器的域名
	$secure	指明Cookie是否在安全的https下传递
	$httponly Cookie 仅可通过 HTTP 协议访问
返回值:
	如果在调用本函数以前就产生了输出,setcookie() 会调用失败并返回 FALSE。 如果 setcookie() 成功运行,返回 TRUE。

(3)设置Cookie并获取Cookie

$name = 'Tacks';
#isset检测变量是否已设置并且非 NULL 
if(!isset($_COOKIE['name'])){//第一次访问,浏览器还不知道cookie有name 
    setcookie('name',$name);//设置cookie name='Tacks'
}else{//第二次访问页面,浏览器知道cookie有name
    echo $_COOKIE['name'];//通过$_COOKIE全局数组进行获取对应的cookie值
}

        注意:当前设置的Cookie不是立即生效的,而是要等到下一个页面时才能看到.这是由于在设置的这个页面里Cookie由服务器传递给客户浏览器,在下一个页面浏览器才能把Cookie从客户的机器里取出传回服务器的原因。看一下火狐浏览器F12的输出,这里时间默认是UTC的标准时间,比北京时间晚8个小时。

(4)设置过期时间

setcookie('name',$name,time()+60*60*24);//设置cookie name='Tacks'  过期时间一天

(5)设置保存路径

默认的保存路径是在于当前文件同级的目录下,但是也可以自己进行更改,如果不是对应目录则获取不到。

setcookie('name',$name,time()+60*60*24,'/php/');#设置其他目录进行保存

(6)可以看一下请求头的一些信息

        客户端浏览器第一次请求后,服务器设置对应Cookie返回携带到http请求头中,再次返回给客户端,客户端将其存储在本地,下一次客户端请求页面的时候,就会携带Cookie的请求头 。

(7)数组形态的Cookie

         通过带 数组[]标记的 Cookie 名称,也可以把 Cookie 设置成数组。 如果有数组元素,可以把它放进 Cookie 里; 脚本接收到时,Cookie 名称里的值会是一个数组。

$admin['name']  = 'Tacks';
$admin['pass']  = '12a@#$yh%^&*009238,.y+00-8~86GADB"28\3/ad42';#这里特殊符号比较多
$admin['power'] = 0;
#Cookie也可以利用多维数组的形式进行设置
setcookie('admin[name]',$admin['name']);
setcookie('admin[pass]',$admin['pass']);
setcookie('admin[power]',$admin['power']);

注意:在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码,如果不想URL编码可以使用下面的setrawcookie()函数。

(8)获取Cookie二维数组的值

#上面存储admin二维数组获取
foreach($_COOKIE['admin'] as $key=>$value){
    echo $key,":",$value,'<br/>';
}
/*
name:Tacks
pass:12a@#$yh%^&*009238,.y+00-8~86GADB"28\3/ad42
power:0
*/

(9)setrawcookie()函数

setrawcookie() 和 setcookie() 非常相似,唯一不同之处是发送到浏览器的 cookie 值没有自动经过 URL(urlencode)编码。

$name = 'ABC+-*/!235#$21asd=-+';
echo $name;
setrawcookie('name',$name);

(10)删除Cookie

           要删除一个 Cookie,应该设置过期时间为过去,以触发浏览器的删除机制。

setCookie('name','Tacks',time()-1);

 

二、Session

(1)工作原理

       Session技术与Cookie相似,都是用来存储用户的相关资料。但是最大的不同之处,在于Cookie是将数据存储在客户端中,而Session则是将数据存储在服务器系统下面。

      Session的中文含义是“会话”,在web系统中,通常指用户与web系统进行交互的过程,也就是从用户打开浏览器登陆到web系统中,到关闭浏览器退出web系统的这个过程。

 

      在Web发展历史上,Cookie技术的出现确实是一个重大的改革,但是Cookie在存储在客户端中可以进行修改。不太安全,另外用户如果篡改了,那么服务器也就不能正常追踪某个用户了。而Session技术是将用户相关的资料放在服务器下面,所以是相对安全的,用户无法停用Session的使用。

       举个例子:还是最上面那个商场的例子,用户去过商场后,Cookie好比用户自己存放一张会员卡在自己这里,但是如果会员卡丢失,那么就不能以会员方式进行购物了;而Session则是在用户办理卡的时候,由商场去记录用户的会员信息,这样下次用户去商场不需要带卡了,只需要报一下你的手机号(唯一标识符)或者会员卡号,商场就可以查到你的信息,进而判断你是否是会员。

      就这样客户端只需要存储由服务器为用户创建的一个Session标识符(相当于会员卡号),称之为SessionID,而在服务器端存储Session变量的值。SessionID是一个既不会重复又不容易找到规律的,由32位16进制数组成的字符串。SessionID是会保存在客户端的Cookie中。如果用户阻止Cookie的使用,可以将SessionID保存在用户浏览器地址URL中,当用户请求web服务器中,就会把SessionID发送给服务器,服务器再通过SessionID就可以提取保存在服务器中的Session变量,服务器可以利用全局变量$_SESSION进行共享变量。 

 

       Session 的工作机制是:为每个访客创建一个唯一的 id ( Session ID),并基于这个 Session ID 来存储变量。SessionID存储在 Cookie中或者通过 URL 进行传导。有两种情况去传送SessionID, Cookie 方式相对好一些,但是用户可能在浏览器中关闭 Cookie;第二种方案就是把SessionID直接并入到 URL 中,以保证SessionID 的传送。无需开发人员干预,PHP 就可以自动处理 URL 传送SessionID 的场景。 如果启用了 session.use_trans_sid 选项, PHP 将会自动在相对 URL中包含会话 ID。

 

看一下Session具体的流程:

  1. 当浏览器第一次访问 PHP 脚本时,seesion_start() 函数会创建一个唯一的 Session ID(每个客户端都有一个唯一的标识),并自动通过 HTTP 的响应头,将这个 Session ID 保存到客户端 Cookie 中。同时,也在服务器端创建一个以 Session ID 命名的文件,用于保存这个用户的会话信息;

  2. 当同一个用户再次访问这个网站时,会自动通过 HTTP 的请求头将 Cookie 中保存的 Seesion ID 再携带过来;

  3. 服务器 PHP 脚本接受到客户端请求,这时 session_start() 函数就不会再去分配一个新的 Session ID,而是在服务器的硬盘中去寻找和这个 Session ID 同名的 Session 文件,将这之前为这个用户保存的会话信息读出。

(2)PHP设置Session与读取Session

        Session的设置不同于Cookie,必须先进行启动。调用session_start()函数,以便让PHP的核心程序和Session相关的内建环境变量预先载入内存。session_start()函数作用启动新会话或者重用现有会话。

        基于Cookie的Session,在开启前不能有任何输出内容,因为此函数有设置头信息的内容。如果不想每次都进行session_start()开启,可以在php.ini里面设置“session.auto_start=1”。但是对象不能放入Session中,因为类定义要在session_start()开启前进行加载。

       另外可以通过$_SESSION超全局数组,进行赋值设置。执行下面代码后,默认情况下,PHP.ini 中设置的 SESSION 保存方式是 files(session.save_handler = files),即使用读写文件的方式保存 SESSION 数据,Session变量就会存储在服务器下的某个文件中,该文件的位置是通过php.ini中session.save_path属性指定的路径。

session_start();#开启Session
if (!isset($_SESSION['name'])) {//设置Session
  $_SESSION['name'] = 'Tacks';
} else {
    echo $_SESSION['name'];
}

         执行后它会在服务端对应的存储目录下,生成一个以sess_后面跟着sessionID的文件。内容大致是"变量名|类型:长度:值;"的形式。另外在客户端可以看到下面会存储Cookie,其默认是PHPSESSID,值的内容就是存储的SessionID。

name|s:5:"Tacks";//这就是session文件中存储的。

(3)销毁变量与销毁Session

        如果您希望删除某些 session 数据,可以使用 unset() session_destroy() 函数。例如用户向退出web系统,就需要提供一个注销功能。切记不要用unset($SESSION)注销整个Session数组,这样就不能通过($SESSION)超全局注册变量。

unset($_SESSION['name']);//第一种:删除Session中单个变量
$_SESSION = [];//第二种:将某个用户在Session中注册的变量全部清空
session_destroy();//第三种:销毁当前会话中的全部数据

(4)Session的注销过程

      PHP默认的Session是基于Cookie的,SessionID被服务器存储在客户端的Cookie中,所以在注销Session时也需要清除Cookie中保存的SessionID,而这就需要借助setCookie()函数完成。删除保存在客户端Cookie中的SessionID。从而销毁关于本次会话的所有相关资源。

      另外在PHP脚本中,可以通过调用session_name()函数获取Session名称, 如果指定name参数, session_name() 函数会更新会话名称, 并返回原来的会话名称。

//第一步:开启session_start并且初始化
session_start();
//第二步:删除所有Session变量,
$_SESSION = [];
//第三步:默认基于Cookie的session,使用setCookie删除包含SessionID的Cookie
if(isset($_COOKIE[session_name()])){
    setCookie(session_name(),'',time()-42000);
}
//第四步:彻底销毁session会话本身
session_destroy();//将用户再服务器端对应的Session文件删除

(5)Session的垃圾自动回收机制

       上面的四步走之后可以销毁本地会话,但是用户如果不直接点击退出,而是关闭浏览器。那么在服务器端的Session是不会被删除的,如果下次进行登陆,又会重新分配一个SessionID进行登陆,这个是因为在php.ini文件中默认设置session.cookie_lifetime=0,来进行设定SessionID在客户端Cookie 有效期,0指的是直到浏览器关闭。如果你设定的有效期(以秒为单位),那么不管你是否关闭浏览器,只要在有效期后,SessionID就会消失,从而客户端的SessionID也没有了,但是这个时候服务器的Session并没有删除,如果这样的垃圾文件越来越多,会影响服务器系统造成负荷,因此系统必须必须要有一种机制进行删除。

 

       设置Session后,服务器生成的Session文件就是一个小小的文本文件,是文件就会有一个修改时间的属性。那么垃圾回收机制就是根据这个时间来进行判断的。通过php.ini中设置session.gc_maxlifetime选项来设置一个时间(以秒为单位)。例如该选项的值是3600,那么系统垃圾回收程序,就会在所有的Session文件中进行排查,如果有文件的修改时间距离当前系统时间大于3600秒,就会将其删除,所以失去了客户端SessionID引用的文件,那么就访问不到该变量;同样如果没有失去客户端SeesionID的文件,只要用户在使用,那么Session文件修改时间就会更新,从而不会被删除。

 

      垃圾回收机制也是在开启session_start()时候启动的,但是有一个问题,一个网站的用户登陆多了,可能会多次调用session_start()开启会话,这样垃圾回收机制可能总是被调用,那么样就不是很合理,一天请求太频繁了。可以通过在php.ini里面设置session.gc_probaility和session.gc_divisor两个选项,进行设置启动回收程序的概率,计算公式大概是"session.gc_probaility/session.gc_divisor"。所以一般设置session.gc_probaility=1,选项session.gc_divisor=100,也就是调用session_start()函数开启会话100次才可能启动一次垃圾回收程序。会话请求越频繁,概率值应当越小。

#php.ini关于垃圾回收的选项
session.cookie_lifetime=0;#关闭浏览器相应的cookie文件即被删除
session.gc_maxlifetime=0;#设置过期session时间,默认1440秒(24分钟)
session.gc_probaility/session.gc_divisor;#启动垃圾回收程序的概率

(6)传递SessionID

     通过上面的了解,我们知道客户端与服务器通过SessionID进行追踪一个用户,那么这个SessionID的传递方式有两种,默认是基于Cookie进行传递,另一种通过URL进行传递SessionID。

     如果客户端没有禁用Cookie,那么在PHP脚本中通过session_start()函数进行初始化,服务器会通过发送HTTP中会携带SessionID,客户端会响应到然后将其保存在浏览器Cookie中。

      如果禁用Cookie,那么浏览器中也就不会保存其SessionID,因而下次去请求服务器的时候,请求头中不会包含SessionID的信息,而服务器调用session_start()又会重新创建一个会话,这样就无法追踪用户状态。

     PHP中另一种传递会话ID机制,就是通过重写客户端请求的URL,把SessionID添加到URL中,这样服务端也可以接受到。无需开发人员干预,PHP 就可以自动处理 URL 传送会话 ID 的场景。 如果启用了 session.use_trans_sid 选项, PHP 将会自动在相对 URI 中包含会话 ID。详情可以看一下PHP官网对传递会话ID的方式。

 

三、Cookie与Session的区别

  1. 存放位置:

    • Cookie放在客户端浏览器中;

    • Session放在服务器端某个文件夹下;

  2. 存放的类型:

    • Cookie只能存放字符串。

    • Session还可以存放对象等其他类型。

  3. 存放大小:

    • Cookie存储的数据根据浏览器的不同而有不同的限制,Chrome大概是50左右,最大4097字节。

    • Session默认没有限制,但是如果过多的话,会影响服务器性能。

  4. 存放路径:

    • Cookie是可以用setcookie()函数设置路径参数的,如果同一个网站下不同路径的Cookie互相也是访问不到。

    • Session不能区分路径,同一个用户在会话期间,Session在任何一个地方都可以访问到。

  5. 生命周期:

    • Cookie是可以用setcookie()函数过期时间的,如果浏览器关闭,Cookie还没过期那么会存储到本地,下次打开浏览器的时候还有。如果没有设置过期时间一般是到浏览器关闭的时候就销毁了。

    • Session默认基于Cookie,然后默认设置session.cookie_lifetime=0也就是浏览器关闭的时候,会删除客户端Cookie,那么你就访问不到你之前的会话,而是新创建一个会话,但是远程服务器上的会话文件不会被删除(它会被垃圾回收机制进行处理);另外Session也可以用session.cookie_lifetime进行设定SessionID在客户端Cookie 有效期。

  6. 浏览器访问:

    • Cookie可以在不同浏览器下共享数据,都能访问到Cookie的信息。

    • Session只能在一个浏览器独享,常见的场景就是你如果登陆一个web系统后,复制链接到另一个浏览器上是需要重新进行登陆创建新的会话。

  7. 创建方式:

    • Cookie直接就可以用setcookie()进行设置。

    • Session必须先开启session_start(),然后用超全局变量$_SESSION['name'] = 'Tacks';进行设置。

  8. 手动销毁

    • Cookie利用 setCookie('name','Tacks',time()-1);设置过期就好了。

    • Session需要四步走,开启session_start(),然后删除对应的session变量$_SESSION = [];,然后让对应客户端的cookie也过期,然后彻底消除会话session_destroy();

  9. 用处

    • Cookie一般用于不重要的数据存储在浏览器上,如果想要更安全一些,可以利用一些加密算法处理后存放。

    • Session一般于登陆时候,存储会话状态。

 

 

能一口气看完可真不容易o(* ̄▽ ̄*)o,好多字啊,虽然有些地方重复啰嗦了,但是理解一些会话的原理也是蛮重要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值