java多线程    Java入门    vsftp    ftp    linux配置    centos    FRP教程    HBase    Html5缓存    webp    zabbix    分布式    neo4j图数据库    

深入了解Session,定时控制

当程序启动session_start()之后,就会生成一个sessionID,保存在$_COOKIE变量中(此时,该sessionID并没有保存到客户端,他仅仅存在于会话之中)。同时服务器端默认会在/tmp目录下建立一个session文件,文件名是用前缀“sess_”再加上当前的sessionID组合而成的,我暂且把他叫做sess文件吧。

cookie机制:
当使用cookie机制的时候,在sess文件中没有保存任何数据。而cookie中的数据,实际上是通过setcookie()的方法保存在客户端的。
并且,该方法只将指定的数据保存到了客户端,而sessionID并没有被保存到客户端。这个时候sessionID依然存在于会话之中。
当重新打开浏览器之后,我们发现当前的sessionID实际上已经不是之前的sessionID了,
但是cookie中的数据并不受影响,我们仍然可以通过$_COOKIE变量来获取cookie的值。

php中的session有效期默认是1440秒(24分钟),也就是说,客户端超过24分钟没有刷新,当前session就会失效。当然如果用户关闭了浏览器,会话也就结束了,Session自然也不存在了!

最近的后台开发,遇到这个情况,浏览器不定期的退出Session,让人头疼,服务器改成24小时以后过期根本无效。

我们见到的一些代码片段,经过严格测试根本达不到1小时

1.	ini_set("session.cookie_lifetime","3600"); // 秒  


		if(isset($_SESSION['expiretime'])) {  
		  
		    if($_SESSION['expiretime'] < time()) {  
		  
		        unset($_SESSION['expiretime']);  
		  
		        header('Location: logout.php?TIMEOUT'); // 登出  
		  
		        exit(0);  
		  
		    } else {  
		  
		        $_SESSION['expiretime'] = time() + 3600; // 刷新时间戳  
		  
		    }  
		  
		}  

1、session.use_cookies:默认的值是“1”,代表SessionID使用Cookie来传递,反之就是使用Query_String来传递;
2、session.name:这个就是SessionID储存的变量名称,可能是Cookie,也可能是Query_String来传递,默认值是“PHPSESSID”;
3、session.cookie_lifetime:这个代表SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废……就是因为这个所以Session不能永久使用!
4、session.gc_maxlifetime:这个是Session数据在服务器端储存的时间,如果超过这个时间,那么Session数据就自动删除!

在PHP的文档中明确指出,设定session有效期的参数是session.gc_maxlifetime。可以在php.ini文件中,或者通过ini_set()函数来修改这一参数。问题在于,经过多次测试,修改这个
参数基本不起作用,session有效期仍然保持24分钟的默认值。

分析下原因
默认配置,session.gc_probability = 1,session.gc_divisor =100,也就是说有1%的概率启动GC。
GC的工作,就是扫描所有的session信息,用当前时间减去session的最后修改时间(modified date),同session.gc_maxlifetime参数进行比较,如果生存时间已经超过gc_maxlifetime,就把该session删除。

工作一切正常。那为什么会发生gc_maxlifetime无效的情况呢?

在默认情况下,session信息会以文本文件的形式,被保存在系统的临时文件目录中。在Linux下,这一路径通常为\tmp,在 Windows下通常为C:\Windows\Temp。当服务器上有多个PHP应
用时,它们会把自己的session文件都保存在同一个目录中。

GC在工作时,并不会区分不同站点的session。

举例,站点A的gc_maxlifetime设置为2小时,站点B的 gc_maxlifetime设置为默认的24分钟。当站点B的GC启动时,它会扫
描公用的临时文件目录,把所有超过24分钟的session文件全部删除掉,而不管它们来自于站点A或B。这样,站点A的gc_maxlifetime设置就形同虚设了。
找到问题所在,解决起来就很简单了。修改session.save_path参数,或者使用session_save_path()函数,把保存session的目录指向一个专用的目录,gc_maxlifetime参数工作正常了。

一个永久不过期的Session方案,不过介入了cookie,还按全么

上面为什么说是一般的session机制呢,因为我们可以用一个php的函数:session_set_cookie_params()来实现cookie的机制。详情如下:
CODE:

// 取出当前的sessionID的设置
$cookieParams = session_get_cookie_params();

var_dump($cookieParams);

没有任何登陆的时候
array(5) { ["lifetime"]=> int(0) ["path"]=> string(1) "/" ["domain"]=> string(0) "" ["secure"]=> bool(false) ["httponly"]=> bool(false) }


// 修改当前的sessionID的设置
session_set_cookie_params(
    3600,// 设置sessionID在cookie中保存的时长
    $cookieParams['path'],
    $cookieParams['domain'],
    $cookieParams['secure']
    );
// 重新生成一个新的sessionID
session_regenerate_id(true);
// 执行session_start()
// 注意,此时的session_start跟平时不一样的地方是,这个时候启动session的同时,他会把当前的sessionID保存到客户端的cookie中
session_start();

当然tmp下的sess文件还必须在,所以服务器应该为某个独立站点,进行单独的Session sess文件划分出一个目录,避免被其他程序的GC回收删除了自己的文件。

session永不过期的方法(这个吹牛的办法,如果被其他站点的Session GC回收删除了sess文件也是无效的)

打开php.ini设置文件,修改三行如下:

1、session.use_cookies

把这个的值设置为1,利用cookie来传递sessionid

2、session.cookie_lifetime

这个代表SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废……就是因为这个所以PHP的session不能永久使用! 那么我们把它设置为一个我们认为很大的数字吧,999999999怎么样,可以的!就这样。

3、session.gc_maxlifetime

这个是Session数据在服务器端储存的时间,如果超过这个时间,那么Session数据就自动删除!那么我们也把它设置为99999999。

就这样一切ok了,当然你不相信的话就测试一下看看——设置一个session值过个10天半个月的回来看看,如果你的电脑没有断电或者宕机,你仍然可以看见这个sessionid。

无法修改底层配置,可以采用cookie的办法来解决。

 

以上就是php设置session的具体做法,内容涉及session设置值或直接设置过期、失效和有效期,希望对大家的学习有所帮助。

2018-4-25 11:25 将服务器php.ini配置修改后 重启
session.cookie_lifetime = 360000
session.gc_maxlifetime = 360000

结果后台三天也不用重新登陆了。


This entry was posted in JAVA, PHP and tagged . Bookmark the permalink.
月小升QQ 2651044202, 技术交流QQ群 178491360
首发地址:月小升博客https://java-er.com/blog/session-control-time/
无特殊说明,文章均为月小升原创,欢迎转载,转载请注明本文地址,谢谢
您的评论是我写作的动力.

Leave a Reply