PHP强化之14 - cookie与session

版权声明:著作权归作者所有,转载请注明出处 https://blog.csdn.net/weixin_42565457/article/details/84997105

一、会话

在讲理Cookie与Session之前,写这里先引入一个叫做会话的概念。

在计算机术语中,会话是指一个终端用户与交互系统进行通讯的过程,比如从输入账户密码进入操作系统到退出操作系统就是一个会话过程。会话较多用于网络上,TCP的三次握手就创建了一个会话,TCP关闭连接就是关闭会话。

会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。而使用会话跟踪技术,则可以弥补HTTP协议无状态的不足。

二、COOKIE

1、简介

Cookie技术是客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。

让我们说得更具体一些:当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header);当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置,对于Windows操作系统而言,我们可以从: [系统盘]:\Documents and Settings\[用户名]\Cookies目录中找到存储的Cookie;自此,客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。

2、cookie的原理

当服务器返回给客户端一个http响应信息时,其中如果包含Set-Cookie这个头部时,意思就是指示客户端建立一个cookie,并且在后续的http请求中自动发送这个cookie到服务器端,直到这个cookie过期。如果cookie的生存时间是整个会话期间的话,那么浏览器会将cookie保存在内存中,浏览器关闭时就会自动清除这个cookie。另外一种情况就是保存在客户端的硬盘中,浏览器关闭的话,该cookie也不会被清除,下次打开浏览器访问对应网站时,这个cookie就会自动再次发送到服务器端。一个cookie的设置以及发送过程分为以下四步:

  • 客户端发送一个http请求到服务器端
  • 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
  • 客户端发送一个http请求到服务器端,其中包含Cookie头部
  • 服务器端发送一个http响应到客户端

3、cookie的基本操作

1)创建cookie
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
setcookie() 定义了 Cookie,会和剩下的 HTTP 头一起发送给客户端。 和其他 HTTP 头一样,必须在脚本产生任意输出之前发送 Cookie(由于协议的限制)。 请在产生任何输出之前(包括 和 或者空格)调用本函数。

一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。

如果在调用本函数以前就产生了输出,setcookie() 会调用失败并返回 FALSE。 如果 setcookie() 成功运行,返回 TRUE。当然,它的意思并非用户是否已接受 Cookie。

2)获取cookie
$_COOKIE['name']

问题:客户端的cookie信息是怎么传递给服务器的?
通过http协议的Cookie:name=test;这个机制是http协议规定的。

3)更新cookie
更新某个cookie的key<==>val,实际是就是重新设置;依然是使用setcookie();

4)删除cookie
指定删除某个cookie,只需要把这个key的time设置成time()-秒数即可。
如:setcookie('name','',time()-1);
如果需要删除所有的cookie则可以用遍历的方法:

foreach($_COOKIE as $key=>$val){
  setcookie($key,'',time()-1);
}

如果你把这个网站的所有cookie都删除掉,则浏览器会自动把这个cookie文件也删除掉的。

4、注意

1)Cookie功能需要浏览器的支持。
如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。

2)Cookie具有不可跨域名性。
Cookie在客户端是由浏览器来管理的,Cookie是不可跨域名的。如域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。

三、SESSION

1、简介

Session 是存放在服务器端的,类似于Session结构来存放用户数据,当浏览器 第一次发送请求时,服务器自动生成了一个Session和一个Session ID用来唯一标识这个Session,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的Session。

2、seesion的工作原理


3、seesion的基本用法

1)保存sesion

session_start();  //初始化session
$_SESSION['name'] = 'nosee123';

查看服务器的session文件,存储结果如:name|s:8:"nosee123";
上面的s表示保存类型为字符串,8为表示所保存数据的字节大小,最后nosee123是session的值。
seesion文件中可以存储的类型有如:string、float、integer、bool、array、object。

2)获取sesion数据

session_start();  //初始化session
$name = $_SESSION['name'];

注意:如果我们需要取出对象,则需要实现申明一下类的定义信息。(如:可以使用require_once来解决)

3)删除seesion数据
删除某个key:

unset($_SESSION['key']);

删除所有session:

session_destroy();   //相当于删除整个对应的session文件

4、配置说明

在配置文件php.ini中我们可以作一些session的配置。

1)session.auto_start
指定会话模块是否在请求开始时自动启动一个会话。默认为 0(不启动,也不推荐启用)。
此时使用$_SESSION前要先调用session_start()初始化session。

2)session.name
session.name = PHPSESSID 默认值为PHPSESSID;用于设置session的名字,该值可以通过session_name()获取。

3)session.save_path
session的保存路径,默认为:session.save_path = "/var/lib/php/sessions"

4)垃圾回收
session.gc_maxlifetime = 1440这个时间是指在1440秒(24分钟)内,没有使用session文件,该session就会被当做垃圾回收。
session.gc_probability = 1session.gc_divisor = 1000,ession.gc_divisor 与 session.gc_probability 合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率。此概率用 gc_probability/gc_divisor 计算得来。例如 1/1000 意味着在每个请求中有 0.1% 的概率启动 gc 进程。如果网站的规模越大,我们建议把这个概率设置越小。

5)session.use_cookie
session.use_cookies = 1设置是否使用cookie,默认使用。

6)session.cookie_lifetime
session.cookie_lifetime = 0cookie保存时间,默认0,关闭浏览器就失效

7)session.use_trans_sid
session.use_trans_sid 指定是否启用透明 SID 支持。默认为 0(禁用)。

8)session.save_handler
session.save_handler 定义了来存储和获取与会话关联的数据的处理器的名字。默认为 files。
session数据还可以存放的位置如:数据库(mysql),内存(redis、memcache),网络文件(nfs)

5、禁用cookie的情况
当用户禁用cookie后,服务器每次session_start()都会创建一个全新的session文件。

解决办法:
方法一,在每个超链接上添加一个PHPSESSIONID=$sessionId

//在每个超链接上添加一个PHPSESSIONID=$sessionId;同时每个页面加入:
if(isset($_GET['PHPSESSIONID'])){
  session_id($_GET['PHPSESSIONID']);    //设置session_id();
}
session_start();    //若有设置session_id()则sesssion_start()不会创建一个新的session文件。
//$sessionId = session_id();

方法二,使用常量SID
SID是一个包含着会话名以及会话 ID 的常量,格式为 “name=ID”,它的值相当于字符串"session_name().'='.session_id()";或者如果会话 ID 已经在适当的会话 cookie 中设定时则为空字符串。

可以在超链接(herf)、action、header(Location:xxx)里直接拼接SID常量,如

<a href="index.php?<?php echo SID; ?>">下个页面</a>

方法三,使用session.use_trans_sid指定是否启用透明SID支持
直接配置php.ini文件的session.use_trans_sid = 0,把0改为1即可。(配置成功后则在herf、action、header中会自动加SID,但是javascript的跳转中不会自动添加)
但是该方法对安全有影响,不推荐开启。

6、注意

1)在使用$_SESSION前要保证session被初始化,具体方法如下:
方法一:先调用session_start();
方法二:配置php.ini的session.auto_start=1(不推荐,会影响效率)

2)一个会话对应一个session:
当关闭浏览器再打开操作session后,会创建一个新的session文件。

3)误解:“只要关闭浏览器,session就消失了”
产生这种错觉的原因:当关闭浏览器后这个 session id就消失了,再次连接服务器时也就无法找到原来的session。
恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,所以session的gc机制都会有存在的意义。

四、COOKIE与SESSION

1)存放位置
cookie数据存放在客户的浏览器上,session数据放在服务器上。

2)安全性
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。

3)网络传输量
cookie通过网络在客户端与服务器传输,而session保存在服务器不需要传输。
cookie每次请求都会被自动添加到Request Header中,无形中增加了流量。cookie信息越大,对服务器请求的时间越长。

4)生命周期(以20分钟为例)
cookie的生命周期是累计的,从创建开始计时,20分钟后cookie生命周期结束,cookie失效。
session生命周期是间隔的,从创建计时,如在20分钟内没有访问过session,那么session信息无效;如果在第19分钟访问过session,那么它的生命周期将重新开始计算。

5)服务器性能:
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用COOKIE。

6)储存大小:
单个cookie在客户端的限制一般是4K,就是说一个站点在客户端存放的COOKIE不能超过4K。

7)保存内容
cookie保存的是字符串,session中可以保存多种数据类型。

参考

官方手册:
cookie: http://php.net/manual/zh/features.cookies.php
seesion: http://php.net/manual/zh/book.session.php

博客:
https://my.oschina.net/xianggao/blog/395675?fromerr=GC9KVenE

猜你喜欢

转载自blog.csdn.net/weixin_42565457/article/details/84997105