phpsession
首先,咱们大约知道session是浏览器与服务器之间的一次交互会话。
那么会话又是什么呢?顾名思义便是浏览器与服务器之间的对话,浏览器一封闭,会话就完毕了。
说session不得不说的便是HTTP协议和cookie了
咱们都知道http协议是一个无状态的协议,便是说本次恳求和前次恳求没有任何关系。这就会带了一个问题,假如恳求的页面有关联,比方登录后拜访主页,那么在主页怎么判别是登录状态呢?
所以此时cookie就呈现了,cookie是把少量的信息存储在用户自己的浏览器上,当用户用浏览器拜访服务器时,PHP就可以读取cookie中的信息,在任何页面中都可以运用。
可是cookie存在缺陷,cookie存储在客户端,存储大小有限制,一个域名下存储个数也有限制,最关键的是用户是可见的,不安全,用户可以修改甚至禁用cookie
这个时候session就呈现了,session存储在服务器端,不必每次恳求客户端都随身携带cookie
所以:session的作用便是:处理HTTP协议恳求的无状态问题,让屡次的HTTP恳求发生联络
Session的运行机制
咱们要运用session,第一步便是敞开session,这也是session的第一阶段:
session_start()阶段
这个函数的作用便是敞开session,敞开之后读取cookie信息判别是否存在session_id,假如存在便是用这个session_id,假如没有就会随机生成一个唯一的32位的session_id。经过这个session_id就可以绑定一个唯一的用户。
这个进程还会初始化$SESSION这个变量,读取session文件中的内容,把内容反序列化之后赋值到$SESSION这个变量中,这个阶段还有一个特别关键的作用,还会判别那些session文件已经过期,调用gc进程,删去掉过期的session文件。gc如何判别文件是否过期,如何操作后面再说
session_start();echo”SID:”.SID.””;echo”session_id():”.session_id().””;echo”COOKIE:”.$_COOKIE[“PHPSESSID”];
输出:
SID:PHPSESSID=bjjwfoo45hajsjv89trsgtiertbuiwom
session_id():bjjwfoo45hajsjv89trsgtiertbuiwom
cookie:提示Notice:undefinedindex:PHPSESSID
这个由于浏览器第一次恳求还没有在cookie中存储session_id,这个cookie的一个特性,只有当第一次恳求之后,服务器接收到恳求才在服务器端设置cookie,存储session_id。
留意:cookie中存储的session_id默许是会话时刻
SID:是系统常量,SID包含着会话名以及会话ID的常量,格局为“name=ID”,假如cookie中已经存在session_id,SID就为一个空字符串,否则便是”name=ID”
第二阶段便是脚本运行期间:
php仅仅对$_SESSION这个变量进行增修改查的操作,需求留意:这个阶段并没有影响到session文件里面的内容,除非你在这个阶段session_destroy()了,除此之外,该阶段不会对session文件有任何影响
第三阶段:脚本履行完毕
在这个阶段才会对session文件进行操作,也便是这个阶段才会把$_SESSION数组中的数据序列化然后存储到session文件
session的存储方法
默许会存储在服务器的暂时目录,以文件的方法存储,文件名为(sess_+session_id),这些都可以在php.ini文件中装备,文件内容为序列化的数据,如下:
$_SESSION[‘name’]=‘张三’
$_SESSION[‘age’]=18
session文件为:
name|i:张三;age|i:18
下面是常用的php.ini文件中sessionde相关装备:
session.save_handler=files#规则session的存储方法,默许是文件,还可所以redis或者是memcache,提升功率
session.save_path=”d:/wamp/tmp”#规则session文件的存储目录
session.use_cookies=1#是否运用cookie存储session_id
session.name=PHPSESSID#客户端存储session_id的会话名
session.auto_start=0#是否主动敞开session
session.cookie_lifetime=0#设置客户端中存储的session_id的过期时刻,留意session的过期时刻是间隔的,比方20分钟过期,从头拜访了,session的过期时刻会从头核算,cookie的过期时刻是累记的
session.serialize_handler=php
session.gc_divisor=1000
session.gc_probability=1
session.gc_maxlifetime=1440#设置session文件的过期时刻
session的废物收回机制
一个用户拜访服务器会发生一个session文件,封闭浏览器,然后在拜访服务器又会发生一个新的session文件,这样session的废物文件就会很多,长时刻不整理就会占用大量的磁盘空间,拜访session文件的速度也会降低,gc进程废物收回就很有必要了
先提一下PHP的一些整理session的函数
unset($_SESSION[‘name’])整理某个变量
session_unset()不传参数,清除一切的session变量,可是session文件还在
session_destroy()清除session文件
setcookie(session_name(),”,time()-1000,’/’)设置cookie文件过期
留意:一般做了session_destroy()操作之后,setcookie(session_name(),”,time()-1000,’/’)也是有必要的,否则用户从头改写页面,又会设置一样的session_id,发生session文件
然后便是gc主动删去废物文件:
session.gc_divisor=1000
session.gc_probability=1
session.gc_maxlifetime=1440#设置session文件的过期时刻
删去session废物文件的概率是,session.gc_probability/session.gc_divisor=1/1000,也便是说每次session_start()都会有1/1000的概率触发gc进程,可是1000次中必会有一次,假如session.gc_probalility=1000,便是100%的概率,也就说每次session_start()都会触发gc进程.
php中的session安全
相同点:两者都是保存用户的临时信息,以便利用户和网站之间的交互
不同点:Session保存在服务器端,只有服务器端才可检查和修正。服务器端经过客户端在cookie中携带的session_id来取得保存在服务器端的用户数据。Cookie保存在客户端,服务端和客户端都能够对其进行修正。
Session的作业原理
首先测验如下一段代码
session_start();//开启session
echo‘Sessionid:’.session_id().‘
’;//显现此次交互的session_id
?>
页面显现成果为
Sessionid:ihrk96384qjvvsqmce0dlkla04
即便不断改写页面,仍然不变,阐明服务器端是能够识别出客户端,那么它是如何做到的呢?
咱们能够检查一下他们的第一次HTTP交互(先清空一次cookie和缓存再测验)
RequestHeader:
GET/phptest/test2.phpHTTP/1.1
Host:localhost
Cookie:
ResponseHeader:
Set-Cookie:PHPSESSID=sastrf9cikeij6meoe3055brq3;path=/
为了阐明问题,我只取要用到的信息,从恳求头能够看到,这个时分客户端没有给服务端传Cookie内容。而回来的头信息中,服务端指明了set-cookie要设置一个PHPSESSID的内容,保存在”/”目录下。
来看第二次交互:
RequestHeader:
GET/phptest/test2.phpHTTP/1.1
Host:localhost
Cookie:PHPSESSID=sastrf9cikeij6meoe3055brq3
ResponseHeader:
Set-Cookie:
这一次成果显现服务器端没有再要求写Cookie,而客户端主动上传了上次取得的PHPSESSID值,也便是这种机制,使服务端”知道”了客户端。只需服务端没有要求再次写session,则今后的交互将一直以此session_id作为客户端的身份标志。
服务器端修正Session_id
当然session_id不是永久不变的,当咱们清空过一次Cookie今后就发现以前登录了的网站都得从头登陆。再次登陆的时分,咱们又会以新的session_id来进行从头承认身份。(注:还有别的方法能够传递session_id值,例如querystring等)。
其实从上一个例子中咱们就能够看到,服务器端修正session_id其实是经过重写一次cookie来完结的,这次重写发生在一次恳求完结今后,即传回的HTTP头中阐明的。
为了防止Session劫持,咱们或许需要经过每次恳求都更改session_id来保证用户是自己登录的。在php中,能够运用以下方法:
session_start();//开启session
echo‘OldSessionid:’.session_id().‘
’;
session_regenerate_id(true);//重置session_id,并使原session无效
echo‘NewSessionid:’.session_id().‘
’;
?>页面显现成果为:
OldSessionid:mqk5sfudpu9ikgp49vc825ggo6
NewSessionid:mrck9n85v190reupsni4ob6lo5
可见session_id在运用了session_regenerate_id()今后发生了变化,变化写入方法同第二点介绍的,服务器端在回来的HTTP头中加入Set-Cookie。
session_regenerate_id()的一个问题
在实际操作中,session_id的保存方位能够经过
session_set_cookie_params()
来修正,如下:
session_set_cookie_params(0,‘/’,‘testdomain’);
session_start();//开启session
echo‘OldSessionid:’.session_id().‘
’;
session_regenerate_id(true);//重置session_id,并使原session无效
echo‘NewSessionid:’.session_id().‘
’;
?>
在这种方法下,session_id的默许domain被修正,可是session_regenerate_id()是不识别的。这不知道是不是php的一个bug,为了处理这个问题,咱们有必要运用手动方法重置session保存,修正代码如下:
session_set_cookie_params(0,‘/’,‘testdomain’);
session_start();//开启session
echo‘OldSessionid:’.session_id().‘
’;
session_regenerate_id(true);//重置session_id,并使原session无效
echo‘NewSessionid:’.session_id().‘
’;
setcookie(session_name(),session_id(),0,‘/’,‘testdomain’);//手动更新session_id
?>
这样一来就能够每次交互更新session_id了……虽然有些杂乱,可是经测验可行
评论前必须登录!
注册