本文章介绍了关于php session用法及session在使用过种中的一些细节和生命周期,有需要的同学可以参考一下。
最近在网上的交流中发现大家对SESSION的使用上有很多误区,本质上就是不了解SESSION的工作原理。
SESSION会话开启时,会首先发送一个对浏览器的唯一标识session_id的cookie(名字为PHPSESSID可以通过session_name()获取),同session.save_handler = files的情况下,在服务器的指定目录(如temp)下生成一个没有后缀的文件,名字是
?'sess_" + 'session_id';
这样就完成了基本的设置。那么在下一次发起http请求时,首先浏览器会发送这个当前域名下的所有cookie名字和值过去,这样服务器就能根据cookie中的session_id来去读取session文件,而不会混淆这个session属于谁。
这一步具体如下:
SESSION发送一个对浏览器的唯一cookie变量session_id,这个session_id变量有名字、有值。变量名(name)默认为PHPSESSID,变量值(value)为apach随机生成的字符串,类似rvag9m368vim7k8g4v7k2ank70 。通常说的session_id其实是指这个唯一的字符串rvag9m368vim7k8g4v7k2ank70。
具体的在FF的HTTP响应头下如此:
?session_start();
在程序中上面一句就完成了上面的功能,假如浏览器没有发送PHPSESSID的cookie过来就发送一个过去,有就读取这个cookie,这样就能维持同一个会话。
好了既然知道了session的工作原理,那么我们可以推测到假如服务器端sess_rvag9m368vim7k8g4v7k2ank70 这个文件我们手动删除了,那么session失效,假如浏览器cookie失效,那么session照样失效。
在手动的情况下:
在服务器端,可以用
?session_ destroy() 或者session_ unset()
来使其失效。
在浏览器端:
可以直接
?setcookie('PHPSESSID','',123);
让cookie过期,或者另外一种方式,但不能立即失效
?session_set_cookie_params($time);//当前时间戳上的秒,例如60,即让其60秒后过期,不要用时间戳+自己设定的时间。
上面所讲的都是让session提前过期,但是想直接让session延迟行不行呢?除了修改配置(session.gc_maxlifetime)是不行的,在php.ini里面session.gc_maxlifetime 设置过期时间,到了这个时间,就有session.gc_probability /session.gc_divisor的概率被回收。假如到了这个时间,并且启动了GC进程,GC会去读取session文件的修改时间(mtime),发现大于和当前时间相减后大于session.gc_maxlifetime ,立刻删除。到此,我们也就明白了如何保持这个会话呢,只能在session.gc_maxlifetime 内,必须有用户在访问,每次访问都去修改下session,这样就这个session又多出session.gc_maxlifetime的存活时间。
另外说一下session.cookie_lifetime ,设置PHPSESSID在浏览器的存活时间,默认为0,IE下我发现是正常的,浏览器重启即cookie失效;FF下还继续存在。设置session.cookie_lifetime可以用session_set_cookie_params,
?session_set_cookie_params(60);//60 s session_start();
session.gc_maxlifetime和session.cookie_lifetime 共同决定了session的生存时间。
举例来说明:
第一页:
代码如下 | 复制代码 |
page_open(array("sess" => "Test _Session")); $sess->register( "welcome"); //注册变量$welcome,注意不需要加$ $welcome="Hello,PHP world!"; …… page_close(); ?> |
第二页:
代码如下 | 复制代码 |
page_open();//开始session echo $welcome;//显示第一页中定义的$welcome page_close();//保存状态信息 ?> |
注册完一个变量,当页面最后调用page_close()函数后,各个session变量会被写回到数据库中。如果忘记调用page_close()函数的话,变量就不会被写回数据库,这样将出现不可预知的后果。当变量被使用完毕,不再需要用到时,可以调用以下函数将变量删除:
代码如下 | 复制代码 |
page_open(array("sess" => "Test _Session")); …… $sess->unregister( "variable_name"); …… page_close(); ?> |