background image

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 数据就自动删除!

还有很多的设置,不过和本文相关的就是这些了,下面说下如何使用永久

Session 的原

理和步骤。

前面说过,服务器通过

SessionID 来读取 Session 的数据,但是一般浏览器传送的

SessionID 在浏览器关闭后就没有了,那么我们只需要人为的设置 SessionID 并且保存下来,
不就可以了。如果你拥有服务器的操作权限,那么设置这个非常非常的简单,只是需要进行
如下的步骤:

1、把“session.use_cookies”设置为 1,打开 Cookie 储存 SessionID,不过默认就是 1,一

般不用修改;

2、把“session.cookie_lifetime”改为正无穷(当然没有正无穷的参数,不过 999999999 和

正无穷也没有什么区别)

;

3、把“session.gc_maxlifetime”设置为和“session.cookie_lifetime”一样的时间;

PHP 的文档中明确指出,设定 session 有效期的参数是 session.gc_maxlifetime。可以

php.ini 文件中,或者通过 ini_set()函数来修改这一参数。问题在于,经过多次测试,修改

这个参数基本不起作用,

session 有效期仍然保持 24 分钟的默认值。

由于

PHP 的工作机制,它并没有一个 daemon 线程,来定时地扫描 session 信息并判断

其 是 否 失 效 。 当 一 个 有 效 请 求 发 生 时 ,

PHP 会 根 据 全 局 变 量

session.gc_probability/session.gc_divisor(同样可以通过 php.ini 或者 ini_set()函数来修改)的
值,来决定是否启动一个

GC(Garbage Collector)。

默认情况下,

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 文件都保存在同一个目录中。同样地,这些 PHP

应用也会按一定机率启动

GC,扫描所有的 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 参数
工作正常了。

严格地来说,这算是

PHP 的一个 bug?

还有一个问题就是,

gc_maxlifetime 只能保证 session 生存的最短时间,并不能够保存