您的位置:首页 > 编程语言 > PHP开发

PHP session机制小析

2015-06-28 15:09 543 查看
经常遇到一些用PHP写的需要登录的网站,如果你想退出,一个很方便的做法就是如下图所示:




在浏览器那里,按下F12,找的Cookies那一项,然后把名为PHPSESSID的Cookie删掉,然后刷新一下页面,你就会发现,自己已经退出了。这是什么原因呢?因为我们知道,PHP网站判断是否登录一般是用session来判断的,那为什么删除了Cookie之后就退出了呢?那么,我们就要知道,删除了这个Cookie对session到底有什么影响。

首先,我们需要知道,PHP是如何实现session机制的呢。当我们进入一个PHP网站,这个网站第一次执行session_start();时,PHP内部其实是执行了如下过程:

setcookie(ini_get('session.name'),
    session_id(),
    ini_get('session.cookie_lifetime'),//默认0
    ini_get('session.cookie_path'),//默认'/'当前程序根目录下都有效
    ini_get('session.cookie_domain')//默认为空
 );


这段代码其实就是设置了一个Cookie,这个Cookie的key是ini_get(‘session.name’)(一般我们的PHP配置文件里面,session.name的值默认是PHPSESSID),这个Cookie的value是session_id()(session_id()会生成一串字符串,在上面那个图中,这个字符串就是:’uqafv5lgqdm68nuvbp6kdprd66’)。

接着,网站可能会设置session的值。如下:

$_SESSION['name'] = 'tihouzai';
$_SESSION['telnum'] = 12345678910;


那么这之后程序会做什么呢?PHP内部会在程序结束之前,将session这个变量序列化后存放到一个文件中(假设PHP配置文件中session.save_handler = files),这个文件所在的目录就是session.save_path定义的目录,文件名就是”sess_”.session_id();(比如上图那个用户,session_id() = ‘uqafv5lgqdm68nuvbp6kdprd66’;在PHP配置文件中,定义了session.save_path = “c:/wamp/tmp”,所以就可以看到有这么一个文件存在。)



设置好session之后,当用户第二次再访问该站点的时候,后端程序根据用户传上来的Cookie中PHPSESSID的值,获取到该用户session文件,然后将文件中的内容反序列化后,赋给$_SESSION变量。到这里,就可以理解,为什么删除了Cookie里面的PHPSESSID,用户就会退出了吧。

到这里,再讲一下session的失效和垃圾回收机制。在session_start()函数中,会先将session文件里面的内容序列化给$_SESSION变量,然后再按一定的概率执行session的垃圾回收函数。这个顺序很重要,等下再讲为什么。这里执行session垃圾回收的概率等于:session.gc_probability / session.gc_divisor。session的垃圾回收函数可以大致理解如下过程:

$session_path = rtrim(ini_get('session.save_path'),'/');
$maxLiftTime = ini_get('session.gc_maxlifetime'); //session的有效时间
$time = time();
foreach(glob($session_path.'/sess_*') as $file){
     if(filemtime($file) + $maxLiftTime  < $time){
          @unlink($file);
     }
}


垃圾回收过程简单的说就是:获取目录下所有以”sess_”开头的文件,如果上次修改时间离当前时间超过session的有效时间,就将该文件删除。删除session文件之后,用户再来访问,由于session里面的内容没有了,用户就自然变成退出状态了。

最后说一点,如果我们设置session.gc_maxlifetime = 600;那么,当一个用户600秒后才再次刷新页面,是不是一定会被退出呢?答案是:不一定。这要看在这个用户刷新页面时,之前的用户请求有没有触发session垃圾回收函数,如果触发了,用户会被退出,如果没有,就不会被退出。但如果,就在用户刷新页面的那次请求里,触发了session的垃圾回收函数,那用户会被退出吗?答案是:不会的。因为刚才说过,session的垃圾回收函数是在PHP获取了session内容后执行的。所以,虽然用户的session文件已经失效,但是由于在用户获取session数据的时候,session文件并没有被删除,所以用户不会被退出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: