php session gc_maxlifetime,PHPsession 有效期 session.gc_maxlifetime

PHPsession 有效期 session.gc_maxlifetime

一个已知管用的方法是, 使用 session_set_save_handler, 接管所有的 session 管理工作, 一般是把 session 信息存储到数据库, 这样可以通过 SQL 语句来删除所有过期的 session, 精确地控制 session 的有效期这也是基于 PHP 的大型网站常用的方法但是, 一般的小型网站, 似乎没有必要这么劳师动众

但是一般的 Session 的生命期有限, 如果用户关闭了浏览器, 就不能保存 Session 的变量了! 那么怎么样可以实现 Session 的永久生命期呢?

大家知道, Session 储存在服务器端, 根据客户端提供的 SessionID 来得到这个用户的文件, 然后读取文件, 取得变量的值, SessionID 可以使用客户端的 Cookie 或者 Http1.1 协议的 Query_String(就是访问的 URL 的? 后面的部分)来传送给服务器, 然后服务器读取 Session 的目录

要实现 Session 的永久生命期, 首先需要了解一下 php.ini 关于 Session 的相关设置 (打开 php.ini 文件, 在[Session] 部分):

1session.use_cookies: 默认的值是 1, 代表 SessionID 使用 Cookie 来传递, 反之就是使用 Query_String 来传递;

2session.name: 这个就是 SessionID 储存的变量名称, 可能是 Cookie, 也可能是 Query_String 来传递, 默认值是 PHPSESSID;

3session.cookie_lifetime: 这个代表 SessionID 在客户端 Cookie 储存的时间, 默认是 0, 代表浏览器一关闭 SessionID 就作废就是因为这个所以 Session 不能永久使用!

4session.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_pisor(同样可以通过 php.ini 或者 ini_set()函数来修改)的值, 来决定是否启动一个 GC(Garbage Collector)

默认情况下, session.gc_probability = 1,session.gc_pisor =100, 也就是说有 1% 的可能性会启动 GCGC 的工作, 就是扫描所有的 session 信息, 用当前时间减去 session 的最后修改时间(modified date), 同 session.gc_maxlifetime 参数进行比较, 如果生存时间已经超过 gc_maxlifetime, 就把该 session 删除

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

在默认情况下, session 信息会以文本文件的形式, 被保存在系统的临时文件目录中在 Linux 下, 这一路径通常为mp, 在 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 生存的最短时间, 并不能够保存在超过这一时间之后 session 信息立即会得到删除因为 GC 是按机率启动的, 可能在某一个长时间内都没有被启动, 那么大量的 session 在超过 gc_maxlifetime 以后仍然会有效

解决这个问题的一个方法是, 把 session.gc_probability/session.gc_pisor 的机率提高, 如果提到 100%, 就会彻底解决这个问题, 但显然会对性能造成严重的影响另一个方法是自己在代码中判断当前 session 的生存时间, 如果超出了 gc_maxlifetime, 就清空当前 session

但是如果你没有服务器的操作权限, 那就比较麻烦了, 你需要通过 PHP 程序改写 SessionID 来实现永久的 Session 数据保存查查 php.net 的函数手册, 可以见到有 session_id 这个函数: 如果没有设置参数, 那么将返回当前的 SessionID, 如果设置了参数, 就会将当前的 SessionID 设置为给出的值

只要利用永久性的 Cookie 加上 session_id 函数, 就可以实现永久 Session 数据保存了!

但是为了方便, 我们需要知道服务器设置的 session.name, 但是一般用户都没有权限查看服务器的 php.ini 设置, 不过 PHP 提供了一个非常好的函数 phpinfo, 利用这个可以查看几乎所有的 PHP 信息!------------------------------------------------------------------------------------

------------------------------------------------------------------------------------

打开编辑器, 输入上面的代码, 然后在浏览器中运行这个程序, 会见到 PHP 的相关信息 (如图 1 所示) 其中有一项 session.name 的参数, 这个就是我们需要的服务器 session.name, 一般是 PHPSESSID

记下了 SessionID 的名称后, 我们就可以实现永久的 Session 数据储存了!

代码如下:

代码如下:session_start();

ini_set('session.save_path','/tmp/');

//6 个钟头

ini_set('session.gc_maxlifetime',21600);

// 保存一天

$lifeTime=24*3600;

setcookie(session_name(),session_id(),time()+$lifeTime,"/");

后记:

其实真正的永久储存是不可能的, 因为 Cookie 的保存时间有限, 而服务器的空间也有限但是对于一些需要保存时间比较长的站点, 以上方法就已经足够了!

把 session 放入 mysql 的 Example:

数据库里建表: session ( sesskey varchar32 , expiry int11 , value longtext)

code:

代码执行前已经连接数据库了

代码如下:

代码如下:define('STORE_SESSIONS','mysql');

if(STORE_SESSIONS=='mysql'){

if(!$SESS_LIFE=get_cfg_var('session.gc_maxlifetime')){

$SESS_LIFE=1440;

}

function_sess_open($save_path,$session_name){

// 如果没有连接数据库, 可以在此执行 mysql_pconnect,mysql_select_db

returntrue;

}

function_sess_close(){

returntrue;

}

function_sess_read($key){

$value_query=mysql_query("select value from sessions where sesskey ='".addslashes($key)."'and expiry>'".time()."'");

$value=mysql_fetch_array($value_query);

if(isset($value['value'])){

return$value['value'];

}

returnfalse;

}

function_sess_write($key,$val){

global$SESS_LIFE;

$expiry=time()+$SESS_LIFE;

$value=$val;

$check_query=mysql_query("select count(*) as total from sessions where sesskey ='".addslashes($key)."'");

$check=mysql_fetch_array($check_query);

if($check['total']>0){

returnmysql_query("update sessions set expiry ='".addslashes($expiry)."', value ='".addslashes($value)."'where sesskey ='".addslashes($key)."'");

}else{

returnmysql_query("insert into sessions values ('".addslashes($key)."','".addslashes($expiry)."','".addslashes($value)."')");

}

}

function_sess_destroy($key){

returnmysql_query("delete from sessions where sesskey ='".addslashes($key)."'");

}

function_sess_gc($maxlifetime){

mysql_query("delete from sessions where expiry

returntrue;

}

session_set_save_handler('_sess_open','_sess_close','_sess_read','_sess_write','_sess_destroy','_sess_gc');

}

danoo_session_name('dtvSid');

danoo_session_save_path(SESSION_WRITE_DIRECTORY);

还是有点不明白, open,write 那些参数哪里来的

修改 php.ini 配置的两个常用函数:

get_cfg_var('session.gc_maxlifetime') : 取得 session.gc_maxlifetime 的值

ini_set('session.cookie_lifetime','0') : 设置 session.cookie_lifetime 的值为 0

来源: https://www.php1.cn/detail/php-643d49734f.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值