session和cookies会话机制详解

会话控制

$_SESSION全局变量

当运行一个应用程序时,会打开它,做些更改,然后关闭它。这很像一次会话。计算机清楚你是谁。它知道你何时启动应用程序,并在何时终止。但是在因特网上,存在一个问题:服务器不知道你是谁以及你做什么,这是由于
HTTP 地址不能维持状态。

通过在服务器上存储用户信息以便随后使用,PHP session
解决了这个问题(比如用户名称、购买商品等),所以说SESSION是存在服务器端的。不过,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久储存信息,可以把数据存储在数据库中。

Session 的工作机制是:为每个访问者创建一个唯一的 id (UID),并基于这个
UID 来存储变量。UID 存储在 cookie 中,亦或通过 URL 进行传导。


//session的赋值

$_SESSION[‘user’] =’张三’;

//SESSION的取值就像一个普通的变量一样

echo $_SESSION[‘user’];

//$_SESSION — Session 变量,可以跨页面调用

session_start(); 

//注销(删除某一个SESSION的值)

//unset() 函数用于释放指定的 session 变量:

unset($_SESSION[‘user’]);

//也可以通过 session_destroy() 函数彻底终结 session:

session_destroy();


SESSION的值存储在服务器端

$_COOKIE全局变量

$_COOKIE — 可以跨页面调用,当前页面需要刷新后取值

威尼斯网址开户网站 1

//赋值

setcookie(name, value, time, path, domain);

setcookie(‘user’,’张三’, time() +10,’/’,’.test.me’);

//取值

echo $_COOKIE[‘user’];

//当删除 cookie 时,应当使日期变更为过去的时间点。

setcookie(“user”,””, time()-3600);


COOKIE赋值必须用函数setcookie,取值必须在赋完值之后重新刷新页面才能取得到。

COOKIE存储在浏览器端

SESSION和COOKIE的区别和联系

web请求与响应基于http,而http是无状态协议。所以我们为了跨越多个请求保留用户的状态,需要利用某种工具帮助我们记录与识别每一次请求及请求的其他信息。举个栗子,我们在淘宝购物的时候,首先添加了一本《C++
primer》进入购物车,然后我们又继续去搜索《thinking in
java》,继续添加购物车,这时购物车应该有两本书。但如果我们不采取session
management会话管理的话,基于http无状态协议,我们在第二次向购物车发出添加请求时,他是无法知道我们第一次添加请求的信息的。所以,我们就需要session
management会话管理!

  最近在优化之前给学校写的一个项目,发现了同一个浏览器(IE,Firefox)开多个选项卡的时候不能登录多个用户,后一个登录用户会把前一个用户给覆盖了,我的登录逻辑是把user对象存放到session中的,究竟为什么呢?经过各种debug,查看浏览器的网络请求信息,终于发现了其中的问题。

1Cookie 是什么

cookie 常用于识别用户。cookie
是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送
cookie。

概念:

在同一个网站上,多个页面切换时,保持用户登录状态,访问的都登录用户是自己的信息;

在网站中跟踪一个用户,处理在同一个网站中同一个用户在多个页面为其共享数据!

允许服务器跟踪同一个客户端做出的连续请求!

SESION的特点:

(1)保存位置:服务端指定或默认的系统缓存文件夹内的一个文本文件里,SESSION文件的保存位置可以手动修改,也可以修改成保存在MYSQL里或者MEMCACHE

(2)生存周期:默认是24分钟,可以修改

(3)赋值:直接像数组一样赋值,通过指定下标即可

(4)取值:直接调用某一个下标,就像普通变量取值一样

(5)在使用SESSION之前,必须要先开启SESSION服务,开启的方法有两种:第一种:在PHP.INI里面,把sesseion.auto_start的值设为1,设为0表示关闭。第二种方式,在PHP文件里面写一行语句:session_start();

(6)SESSION调用,默认情况下不能跨子域名,可以通过session_id()给一个session的文件名后缀来让SESSION实现跨子域名的功能。

(7)删除已赋过值的SESSION,通过unset()函数来实现

会话管理的基本主要有隐藏域,cookies,与URL重写这几种实现方式。用得较多的是后两种。

  首先,先说明下服务器中session的机制,因为http协议不同tcp,客户端不是与服务端建立一个长连接的,所以客户端与服务端要建立一一对应的关系只能使用另一种机制,session+cookie实现会话跟踪,禁用cookie的情况暂时不讨论。在客户端没有禁用cookie的情况下,每次向后台服务器发出请求,都会发送cookie中的jsesessionid,而服务端是根据这个jsessionid的值来进行服务端检索到该session的。

2如何创建 Cookie

setcookie() 函数用于设置 cookie。

注释:setcookie() 函数必须位于  标签之前。

PHP通过setcookie()函数进行Cookie的设置,任何从浏览器发回的Cookie,PHP都会自动的将他存储在$_COOKIE的全局变量之中,因此我们可以通过$_COOKIE[‘key’]的形式来读取某个Cookie值。

函数参数:7个中重点的5个

name( Cookie名)可以通过$_COOKIE[‘name’] 进行访问

value(Cookie的值)

威尼斯网址开户网站,expire(过期时间)Unix时间戳格式,默认为0,表示浏览器关闭即失效

path(有效路径)如果路径设置为’/’,则整个网站都有效

domain(有效域)默认整个域名都有效,如果设置了’www.imooc.com’,则只在www子域中有效

缘由:

访问web页面要使用’ HTTP 协议’ 实现, 而HTTP
协议是无状态协议,即,其没有一个内建机制来维护两个事物之间的状态!

但一个用户在请求一个页面后再请求另一个页面是,要让服务器知道是同一个用户,为了应对这种情况的发生,提供了三种页面之间传递数据的方法

使用a 超链接或header() 函数等重定向方式,在URL的GET请求中附加参数的形式。

也可以通过网页中的隐藏表单来储存user的信息,在post提交表单时传递

{俩个脚本之间的简单数据传送,例如:表单修改或删除数据时,传递对应行ID}

使用Cookie
将用户的状态信息,存放在客户端计算机中,其他程序通过存取cookie来存放user的信息

使用 Session 将用户信息存放在服务器中

{传递的数据较多,次数频繁,需要传递数组,例如:在项目中跟踪一个用户,要为不同权限用户提供不同的动态页面,让每个页面知道who
is user now?即,ervery 页面都能获得user的 information,

使用URL需要在跳转的时候都加上同样的信息,带来很大的困难。针对这种情况,选用Cookie
和 Session 技术}

COOKIE的特点:

(1)保存位置:浏览器的缓存文件夹内


(2)生存周期:可以自定义时间,单位是秒


(3)赋值:setcookie(COOKIE的名称,值,生存周期,生效路径,生效域名),一般指定5个参数比较好

(4)取值:直接$_COOKIE[],默认刷新一下才能取到值

(5)开启:不需要开启就能直接运行

(6)子域名调用:可以自由指定让某个子域名调用

(7)删除:还是使用setcookie(),生存周期比现在小,设置成以前的时间就可以了。

(8)cookie的生存周期的值为0,表示直到当前浏览器关闭的时候,cookie就消失。

隐藏域实现会话管理

以一个网络注册信息填写为例。我们在填注册信息的时候,经常遇到填完一个页面的内容之后,还要继续填写下一个页面的内容。但由于http的无状态,那么容易造成的后果,当进入第二页填写的时候,服务器已经不记得我们上一页填写了什么。怎么利用隐藏域解决这个问题呢?顾名思义,其实就是既然服务器不会记得两次请求间的关系,那就由浏览器在每次请求时主动告诉服务器多次请求间的必要信息,但是上一页的信息并不显示在第二页中,而是采用隐藏域的方式。然而显然这种方式是存在各种问题的。比如关掉网页之后,就会遗失信息,而且查看网页源代码时,容易暴露信息,安全性不高。隐藏域并不是servlet/jsp实际会话管理的机制。

  威尼斯网址开户网站 2

3如何取回 Cookie 的值

PHP 的 $_COOKIE 变量用于取回 cookie 的值。

setcookie(“user”, “love chin”, time()+3600);

echo $_COOKIE[“user”];

Cookie的应用:

Cookie是服务器发给客户端的片段信息!.存储在客户端浏览器的内存或硬盘上,在客户请求该服务时发回它!打个比方就像是商场提供用户会员卡或积分卡,有期限!

通过验证,成功登陆网站后,以键值对的形式设置到cookie中(通过HTTP
响应头信息发送给客户端)

再次访问同一个服务器其他php脚本,自动携带Cookie中的information一起访问(通过HTTP
响应头信息返回给服务器)

Windows系统中,cookie文件存放在”C:\Document and Setting\用户名\Cookies
” 文件夹

cookie实现会话管理

cookie是什么?举个简单的例子,现在当我们浏览网站的时候,经常会自动保存账号与密码,这样下次访问的时候,就可以直接登录了。这种技术的实现就是利用了cookie技术。**
cookie是存储key-value对的一个文件,务必记住,它是由服务器将cookie添加到response里一并返回给客户端,然后客户端会自动把response里的cookie接收下来,并且保存到本地,下次发出请求的时候,就会把cookie附加在request里,服务器在根据request里的cookie遍历搜索是否有与之符合的信息
**具体cookie的实现我们会在后面详细讲到

 

4如何删除 Cookie

当删除 cookie 时,您应当使过期日期变更为过去的时间点。

setcookie(“user”, “”, time()-3600);

设置Cookie:

Cookie的建立十分简单,只要浏览器支持,就可以使用内建的setCookie()函数来建立

Cookie是HTTP标头的一部分,因此setCookie()函数必须在其他信息被输出到浏览器之前使用。

① 不能有空行空格 ,

② 引入的文件在<?php ?>后面有空行空格

③ 保存为dom+utf8形式

setcookie( $name[, $value, $expire] )

$name Cookie识别名称

$value Cookie值

$expire 生存期限 unix时间戳

存储数组形态的cookie

setcookie() 第一个参数标识名称带数组下标的形式设置

setcookie(“user[name]”,”lili”);

URL重写实现会话管理

URL重写就是将需要记录的信息附加在请求的链接背后,以链接参数的形式发送给服务器识别。具体实现的过程会在后文结合cookie详解。

**
利用httpsession对象进行会话管理。httpsession对象可以保存跨同一个客户多个请求的会话状态。**

换句话说,与一个特定客户的整个会话期间看,httpsession会持久储存。

**对于会话期间客户做的所有请求,从中得到的所有信息都可以用httpsession对象保存。
**

  • 以之前的问卷调查为例,当一个新客户小明填写问卷时,服务器会生成一个httpsession对象,用于保存会话期间小明所选择的信息,服务器会以setAttribute的方式将其保存到httpsession对象中。每个客户会有一个独立的httpsession对象,保存这个客户所有请求所需要保存的信息。
  • 服务器如何识别所有的请求是否来自同一个客户?客户需要一个会话ID来标识自己。就跟我们每个人的身份证号一样。对于客户的第一个请求,容器会生成一个唯一的会话ID,并通过相应把它返回给用户,客户在以后发回一个请求中发回这个会话ID,容器看到ID之后,就会找到匹配的会话,并把这个会话与请求关联。
  • 实现存储会话ID的就是通过cookie!

威尼斯网址开户网站 3Paste_Image.png

cookie存储在客户端,是被服务器放在response里发回客户端的,以后每次request时,都会把cookie加入到request里。而session是存在服务器的,以属性的形式将会话中的信息存到httpsession对象中。调用时,只要通过httpsession对象调用相应attribute即可。

  • 很多地方总是把session与cookie分开单独讲。但我们通过前面的介绍,不难知道,session实现其会话管理机制时,在如何确定所有请求是否来自同一个客户时,是利用了cookie技术的。所以不应该将cookie与session完全分开讲。

  • 这里产生这个误解的原因。是因为我们对session的会话管理机制不够了解。因为容器在创建session对象时,会帮我们实现所有cookie相关的工作,而我们只需要实现这一句:HttpSession session = request.getSession();记住:
    **
    这个方法不只是创建一个会话,而是会完成所有与cookie相关的工作,只是容器都自动帮我们实现了。我们来看看容器在背后默默为我们做了什么:

    • 建立新的httpsession对象
    • 生成唯一的会话ID
    • 建立新的会话对象
    • 把会话ID与cookie关联
    • 在响应中设置cookiecookie所有的工作都在后台进行。看到这里,是不是很爽?容器几乎帮我们实现了所有cookie工作。
  • 从请求中得到会话ID只需一行代码:HttpSession session = request.getSession();与上一部分为响应生成会话ID是一致的其中也在后台实现了一些步骤:if(请求包含一个会话ID)找到与该ID匹配的会话else
    if(没有会话ID或者没有匹配的ID)创建一个新的会话。还是那句话: **
    cookie所有工作都在后台自动进行 **

cookie原先设计的初衷就是为了帮助支持会话状态。但是因为cookie的简便性,容器为我们封装了大量操作。现在cookie已经被越来越运用到各个方面。首先,**
我们明确cookie是存在客户端的,实际上就是在客户端与服务端交换的一小段数据(一个name/string对)。**由于session在用户关闭浏览器后,会话结束,就会消失,cookie随之应该也会消失。但servlet的API中提供了一些方法,可以让客户端的cookie存活的时间更久一点。这就是cookie相对于session的一大优势所在。我们目前常用的记住用户名和密码,下次登录就是利用cookie在session消失后,还能存活实现的。所以,我们可以定制cookie为我们实现各种功能。

  上面可以看到,请求头中包括了一个cookie,那么这个cookie的jsessionid究竟对应的是不是服务器中session的id?下面我们来看看服务器中的session对应的id究竟是多少。下图是服务端中session的id。

5如果浏览器不支持 Cookie 该怎么办

如果您的应用程序需要与不支持 cookie
的浏览器打交道,那么您不得不使用其他的办法在您的应用程序中的页面之间传递信息。一种方式是通过表单传递数据

在PHP脚本中读取Cookie:

$_COOKIE, 单个信息通过$name ,批量处理 遍历数组

在设置Cookie的脚本中,第一次读取cookie
information不会生效,必须刷新或到另一个页面才可以看到;因为要先设置到客户端,再次访问时,才能被发送回来!

威尼斯网址开户网站 4

6PHP Session 变量

您在计算机上操作某个应用程序时,您打开它,做些更改,然后关闭它。这很像一次对(Session)。计算机知道您是谁。它清楚您在何时打开和关闭应用程序。然而,在因特网上问题出现了:由于
HTTP 地址无法保持状态,Web 服务器并不知道您是谁以及您做了什么。

PHP session
解决了这个问题,它通过在服务器上存储用户信息以便随后使用(比如用户名称、购买商品等)。然而,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久存储信息,可以把数据存储在数据库中。

Session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个
UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。

删除cookie:

setCookie(‘user’);
仅导入第一个参数cookie的识别名{生存时间为空,生存期限与浏览器一样}

setCookie(‘age’,’’,time;
把目标cookie设定为’已过期’状态{系统会自动删除超时的客户端cookie程序}

  经过比对,可以确定请求中的jsessionid对应的就是服务器该session对应的id,接下来,继续开另外一个选项卡进行服务器的访问,查看两个选项卡登录不同的用户时候的情况。

7在您把用户信息存储到 PHP session 中

首先必须启动会话。

session_start();

$_SESSION[‘name’] = ‘jobs’;

echo $_SESSION[‘name’];

session的应用:

session将资料存放在服务器,user无法停止使用。打个比方session是商场给你办理并保存会员卡,用户只需提供卡号就能查到相关信息!

在客户端仅需保存有服务器为user创建的一个session标识符,称为Session
ID;而在服务器端(文件/数据库/MemCache)保存session变量的值。

Session ID是一个不重复,不容易找到规律的,32位十六进制数组成的字符串

Session ID保存在 客户端Cookie里,如果user
组织Cookie的使用,则可以将Session ID保存在用户浏览器地址的URL中。

威尼斯网址开户网站 5

8销毁 Session

如果您希望删除某些 session 数据,可以使用 unset() 或 session_destroy()
函数。

如果要删除所有的session,可以使用session_destroy函数销毁当前session,session_destroy会删除所有数据,但是session_id仍然存在。

值得注意的是,session_destroy并不会立即的销毁全局变量$_SESSION中的值,只有当下次再访问的时候,$_SESSION才为空,因此如果需要立即销毁$_SESSION,可以使用unset函数。

session_start();

$_SESSION[‘name’] = ‘chin’;

echo $_SESSION[‘name’];

$_SESSION[‘time’] = time();

echo $_SESSION[‘time’];

unset($_SESSION);

session_destroy();

var_dump($_SESSION); //此时已为空

Session的配置

php.ini文件中和Session有关的,一些有意义的选项

  • session.auto_start user访问任何页面时,都自动开启并初始化Session,
    默认禁用

{类定义必须在会话启动之前被载入,打开此项,不能在会话中存放对象,

Session.auto_start = 1
则无需在每个脚本中使用Session-start()函数来开启session

}

  • session.cookie_domain 传递会话ID的Cookie的作用域。 默认none
  • session.cookie_lifetime 默认 0
  • session.cookie_path 默认 /
  • session.name 会话名称,。 默认 PHPSESSID
  • session.save_path 对于files处理器, 创建会话数据文件的路径 默认
    /tmp
  • session.use_cookies 是否使用Cookie 在客户端保存会话ID,1允许 默认 1
  • session.user_trans_sid 是否使用明码在URL中显示SID 默认禁止

{基于URL的会话管理宗洪超比基于Cookie的会话管理有更多的风险,应当禁用}

  • session.gc_probability /session.gc_divisor

定义在每次初始化会话时,启动垃圾回收程序的概率。对会话页面访问越频繁,概率越小。建议值(1/1000~5000)
默认值 1/100 开发值默认1/1000

  • session.gc_maxlifetime
    超过次参数设置的秒数后,保存的数据将被是为’垃圾’,并有垃圾回收程序清理
    默认 1440
  • session.save_handler 存储和检索与会话关联的数据的处理器名字,

可以使用(files/user/sqlite/memcache)中的一个值, 默认 files

如果想要使用自定义的处理器(数据库/MemCache),可用”user”

  我发现,另外一个选项卡的请求头中的cookie和第一个的是一样的,经过后台查看,他们对应的sessionid也是一致的,那么用户覆盖的问题就应该出现在这里了,同一个浏览器访问同一个网站,他们是根据客户机的cookie来追踪在服务器中的会话的,如果多个用户使用session.setAttribute(“user”,
user);方法来存储当前的登录的用户信息,那么后面的登录用户肯定会将前面的用户覆盖。这个问题我查看了一下京东究竟是怎么实现同一个浏览器登录多个用户的,发现他们一个浏览器只能登录一个用户,想登录另外一个用户必须把当前用户退出才能进行另一个用户的登录。

9session与cookie的异同

cookie将数据存储在客户端,建立起用户与服务器之间的联系,通常可以解决很多问题,但是cookie仍然具有一些局限:

cookie相对不是太安全,容易被盗用导致cookie欺骗

单个cookie的值最大只能存储4k

每次请求都要进行网络传输,占用带宽

session是将用户的会话数据存储在服务端,没有大小限制,通过一个session_id进行用户识别


来自:w3c教程和幕课网

Session 的声明与使用 :

Session的设置不同于Cookie,必须先启动,在PHP中的调用session_start()函数,以便让PHP核心程序,将和Session相关的内建环境变量预先载入至内存中。

bool session_start() 1/没有参数 2/返回值均为TRUE

3/两个主要作用:①开启一个会话②返回已经存在的会话

第一次访问网站, Session_start()函数会创建一个唯一的 Session ID,

并自动通过HTTP响应头,保存到客户端cookie中,

同时在服务器创建一个以这个Session ID命名的文件,用于保存user的会话信息

再次访问这个网站,会自动通过HTTP请求头将客户端Cookie中保存的Session
ID在携带过来,Session_start()不会再去新分配一个新的Session
ID,而是在服务器硬盘中去寻找和此 Session
ID同名的Session文件,将之前保存的user信息读出,在当前脚本应用

使用基于Cookie的session,在开启session之前,不能有任何输出,session_start()要设置cookie值,类似setCookie()的原因

   经过短暂的思考我也实现了类似的功能,首先登录的时候我先查找session中的user是否存在,如果存在,则直接跳转到登录成功的页面,否则再进行数据库中的用户的查找,这样子,只要在session没有失效的情况下,同一时刻就只能登录一个用户,要登录另一个用户就只能退出当前用户或者开不同的浏览器进程来登录,因为同一类型的浏览器读取的cookie还是一样的。

注册一个会话变量和读取session:

一、
注册和读取Sesson变量,都要通过访问$_SESSION数组完成,必须在开启session_start()之后
{Session_start(); $_SESSION[‘username’] = ‘sky’;}

二、 保存Session变量的文件 变量名|类型:长度:值

三、 读取值的时候,先从session文件中获取全部数据信息进入$_SESSION数组中

注销变量和销毁session

1) Session_destroy()函数 结束当前会话,
并清空会话中的所有资源,关闭session运作,删除session文件。成功返回true,失败返回false
{但不会释放和当前session相关的变量,也不会删除保存在客户端Cookie中的Session
ID}

2) unset()函数来释放session中的单个变量 unset($_SESSION[‘user’]);

{一定注意,不要使用unset($_SESSION)删除整个$_SESSION数组,这将不能通过$_SESSION来注册变量,}

需要删除session中注册的所有变量,给$_SESSION赋值空数组 $_SESSION=
array();

3) session_name()获取session的名称,删除session ID
setcookie(session_name(),’’,time-1,’/’)

4) 注销Session的完整过程,4步走:

<?php

//第一步: 开启session并初始化

session_start();

//第二步: 删除所有Session的变量,

$_SESSION = array();

//第三步: 使用基于cookie 的session ,使用setCookie()删除包Session
Id的Cookie

If(isset($_COOKIE[session_name{

setCookie(‘seesion_name()’,’’,time()-1,’/’)
}

//第四步: 最后彻底销毁Session

session_destroy();

注意:

$_SESSION = array();
清空$_SESSION数组的同时,也将服务器对应的Session文件内容清空。

session_destroy();将服务器对应的Session文件删除

相关文章