说到会话控制,大部人会想,那还不简单吗?不就是COOKIE和SESSION吗?

的确就是cookie和session,但是你真的会用吗?

几年前面试的时候我碰到了一个这样的问题:

如何保证session在1小时后失效?

当时我想这个还不简单,将gc_maxlifetime设置为3600不就行了。当时面试的人说,回答的不对,这样不能保证1小时后肯定失效。当然他也没和我说原因。后来我回去后,仔细查找了一番,才搞清楚。

回答这个问题前,先普及下cookie和session的知识。

COOKIE与SESSION的区别与联系

存储位置的不同:

  • cookie存储在客户端

  • session存放在服务端

他们之间的联系:

当服务端开启session后,即

session_start();

后,会生成一个唯一ID(session_id),并通过响应头告诉客户端。客户端拿到后,会将它保存在cookie中。当客户端再次发起请求时,会带上这个信息。服务端收到这个信息后,就会去存放session文件的目录去查找对应文件,找到后会去提取session信息。就是通过这样的机制,服务端识别了客户端的身份。

所以说,如果没有cookie,session就没有任何意义。

介绍完cookie与session的关系后,我们再来说说session的有效期。

SESSION的垃圾回收

一般php默认的session有效期为24分钟。客户端在超过这个时间后一直没有发出请求,就会有可能触发垃圾回收机制,删除过期的session文件。为什么说有可能?这就要说说垃圾机制的原理了。

php的session垃圾回收是有概率的,是由session.gc_probability和session.gc_diviso确定概率的。概率为

session.gc_probability/session.gc_diviso

php默认gc_probability是1,而gc_diviso默认为100,也就是说每次请求触发垃圾回收的概率为1/100。一般的,当我们网站访问量大的时候,可以将这个概率提高,比如1/1000,以减少io操作。

另外还有一点要说明:比如客户端A,此时新建了一个session(session的有效期为10分钟),过了8分钟后,A又发送了请求。这个时候他的session是2分钟后到期,还是10分钟后到期?

答案是10分钟后。因为第二次请求后,服务端的session文件的修改时间也改变了。垃圾回收是看session文件最后的修改时间。但是大家再想想,对应的cookie有效期是不是也会更新?很可惜,cookie有效期不会更新。

如何保证1小时一定过期

现在,我们来看最初的问题,如何保证session文件一个小时后一定过期。session的垃圾回收是概率事件,所有不能指望他了。

那通过设置cookie的有效期了,通过设置cookie_lifetime可以做到么?

答案还是不行。cookie是在客户端的,他没有了,只是在下次请求的时候不能带上这个cookie了,但对应的session文件还是存在的。

其实这个问题最简单的做法,是将session保存在redis中,通过redis的键的过期时间来保证1个小时候,一定过期。该方法也是推荐的方法

但只能用php的话,要怎样来完成呢?

可以为每一个session都设置一个时间戳,每次访问前都判断时间戳。贴上代码:

<?phpsession_start([    'cookie_lifetime' => 3600,    'gc_maxlifetime' => 3600]);if (isset($_SESSION['lifetime']) && $_SESSION['lifetime'] > time()) {    // 未过期,更新session的lifetime及cookie的有效期    $_SESSION['lifetime'] += 3600;    $tmpVal = $_COOKIE[session_name()];    setcookie(session_name(), $tmpVal, time() + 3600, '/');} else {    // 过期删除    $_SESSION = [];    if (isset($_COOKIE[session_name()])) {        setcookie(session_name(), '', time() - 100, '/');    }    session_destroy();}

通过阅读了该内容,相信大家对php的会话应该有了更深的理解。

更多相关文章

  1. 使用PHP来获取客户端和服务端IP
  2. php实时推送系统消息给客户端的原理及详解
  3. 干掉Navicat!MySQL官方客户端到底行不行?
  4. Github标星 8K+,免费又好用的Redis客户端工具!
  5. 技术干货 | mPaaS 客户端问题排查:漫长的 3s 等待之谜
  6. centos7搭建NFS客户端以及NFS详细步骤
  7. Zabbix5.0服务端和客户端安装
  8. 客户端请求服务器时的状态码讲解
  9. 推荐一款神仙颜值的 ZooKeeper 客户端工具

随机推荐

  1. Android UI Operation in Thread
  2. Android快速开发框架介绍
  3. 百度Android开发面试题
  4. Android 五子棋开发经验
  5. 数据解析
  6. Android - menu 相关
  7. Android的系统的Binder机制(一)
  8. 构建Android开发环境
  9. 在Android库中不能使用switch-case语句访
  10. Android SVG矢量资源的使用方法