一、php中session的生成机制php
咱们先来分析一下PHP中是怎么生成一个session的。设计出session的目的是保持每个用户的各类状态来弥补HTTP协议的不足(无状态)。咱们如今有一个疑问,咱们都知道session是保存在服务器的,既然它用于保持每个用户的状态那它利用什么来区别用户的呢?这个时候就得借助cookie了。当咱们在代码中调用session_start();时,PHP会同时往SESSION的存放目录(默认为/tmp/)和客户端的cookie目录各生成一个文件。session文件名称像这样:浏览器
格式为sess_{SESSIONID} ,这时session文件中没有任何内容,当咱们在session_start();添加了这两行代码:安全
复制代码代码以下:服务器
$_SESSION['name'] = 'wanchun0222';cookie
$_SESSION['blog'] = 'coderbolg.net';session
这时文件就有内容了:spa
复制代码代码以下:.net
name|s:11:"wanchun0222";blog|s:13:"coderbolg.net";设计
这时再看看cookie:code
能够看到服务器为咱们自动生成了一个cookie,cookie名称为"PHPSESSID",cookie内容是一串字符,其实这串字符就是{SESSIONID}。也许你已经明白了,当咱们使用session时,PHP就先生成一个惟一的SESSIONID号(如2bd170b3f86523f1b1b60b55ffde0f66),再在咱们服务器的默认目录下生成一个文件,文件名为sess_{SESSIONID},同时在当前用户的客户端生成一个cookie,内容已经说过了。这样PHP会为每个用户生成一个SESSIONID,也就是说一个用户一个session文件。PHP第一次为某个用户使用session时就向客户端写入了cookie,当这个用户之后访问时,浏览器会带上这个cookie,PHP在拿到cookie后就读出里面的SESSIONID,拿着这个SESSIONID去session目录下找session文件。找到后在调用$_SESSION['blog']的时候显示出来。
二、php中session的过时回收机制
咱们明白了session的生成及工做原理,发如今session目录下会有许多session文件。固然这些文件必定不是永远存在的,PHP必定提供了一种过时回收机制。在php.ini中session.gc_maxlifetime为session设置了生存时间(默认为1440s)。若是session文件的最后更新时间到如今超过了生存时间,这个session文件就被认为是过时的了。在下一次session回收的时候就会被删除。那下一次session回收是在何时呢?这和php请求次数有关的。在PHP内部机制中,当php被请求了N次后就会有一次触发回收机制。究竟是请求多少次触发一次是经过如下两个参数控制的:
复制代码代码以下:
session.gc_probability = 1
session.gc_divisor = 100
这是php.ini的默认设置,意思是每100次PHP请求就有一次回收发生。几率是 gc_probability/gc_divisor 。那么这个几率这么小,若是php请求少的话,岂不是不会回收了?答案:是的。因此有时候你设置了session过时时间,但会发现会话仍是没有过时,就是这个缘由,那么为何重启浏览器就能销毁session了?答案是NO,浏览器重启,并无销毁session,只是session_id换了,你天然就找不到上次的会话了。
咱们了解了服务器端的session过时机制,再来看看客户端的cookie的过时机制。
若是cookie失效了浏览器天然发送不了cookie到服务器,这时即便服务器的session文件存在也没用,由于PHP不知道要读取哪一个session文件。咱们知道PHP的cookie过时时间是在建立时设置的,那么PHP在建立session的同时为客户端建立的cookie的生命周期是多久呢?这个在php.ini中有设置:session.cookie_lifetime 。这个值默认是0,表明浏览器一关闭SESSIONID就失效。那就是说咱们把session.gc_maxlifetime和session.cookie_lifetime设置成同一个值就能够控制session的失效时间了。
三、php中session的客户端存储机制
由上面的介绍咱们能够知道,若是用户关闭了cookie,那咱们的session就彻底无法工做了。是的,确实是这样。php中session的客户端存储机制只有cookie吗?不是的。既然咱们的SESSIONID 不能经过cookie传递到各个页面,那咱们还有另外一个法宝,就是经过页面GET传值的方式。
PHP能够在cookie被禁用时自动经过GET方式跨页传递SESSIONID,前提是设置php.ini的session.use_trans_sid为1。这时当咱们在客户端禁用了cookie时使用了session,并在当前页面经过点击连接到另外一页面时,PHP会自动在连接上添加SESSIONID参数,像这样:nextpage.php?SESSIONID=2bd170b3f86523f1b1b60b55ffde0f66。我想你应该看到了这种方式的缺点:好像不够安全啊。