php 会话控制(关于session的维护与生命周期)
Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器创建生成一个唯一的sessionID,用该sessionID为标识符来存取服务器端的Session存储空间,在会话期间,分配给客户端的唯一sessionID,用来标识当前用户,与其他用户进行区分。
sessionID也可以作为会话信息保存到数据库中,进行session持久化。这样可以跟踪用户的登陆次数、在线与否、在线时间等从而维护HTTP无状态事物之间的关系。session的内容存储是键值对的列表,键是字符串类型,session的存储更方便,值可以是对象。
在session会话期间,session会分别保存在客户端和服务器端两个文件,客户端可以是cookie方式保存的sessionID(默认的保存方式)或通过url字符串形式传递。服务器端一般以文本的形式保存在指定的session目录中。在服务器端session.use_cookies来控制客户端使用哪一种保存方式。
如果定义为cookie保存方式,我们可以通过session.cookie_lifetime(默认值0,闭浏览器就清除)来控制被保存在client上的cookie的有效期。
而如果客户端用cookie方式保存的sessionID,则使用“临时”的cookie保存(cookie的名称为PHPSESSID,通过Firebug你可以了解到详细的信息,该名称你可以通过php.ini session.name进行更改),用户提交页面时,会将这一SessionID提交到服务器端,来存取session数据。这一过程,是不用开发人员干预的。
Session的创建:
session_start()
功能:
初始化Session,也标识着session生命周期的开始。要使用session,必须初始化一个session环境,有点类似于OOP概念中调用构造函数构创建对象实例一样。session初始化操作,声明一个全局数组$_SESSION,映射寄存在内存的session数据。如果session文件已经存在,并且保存有session数据,session_start()则会读取session数据,填入$_SESSION中,开始一个新的session生命周期。
说明:
如果在php.ini中session.auto_start=1开启,则在每个页面执行session_start(),不需要手工设置,该选项默认为关闭状态,开启后不能将对象放入session中。
Session ID:
用户session唯一标识符,随机生成的一串字符串,具有唯一性,随机性。主要用于区分其它用户的session数据。用户第一次访问web页面的时候,php的session初始化函数调用会分配给当前来访用户一个唯一的ID,也称之为session_id。
获得session_id():
echo $_COOKIE['PHPSESSID'].'<br/>';
echo $_COOKIE[session_name()].'<br/>';
echo session_id().'<br/>';
备注:
php默认的session是基于cookie的,如果要删除cookie的话,必须借助setcookie()函数
session_unset()和unset()函数区别:
在session生命周期,session_unset()从当前session中注销全部session数据,让$_SESSION成为一个空数组。它与unset($_SESSION)的区别在于:unset直接删除$_SESSION变量,释放内存资源;另一个区别在于,session_unset()仅在session生命周期能够操作$_SESSION数组,而unset()则在整个页面(page)生命周期都能操作$_SESSION数组。session_unset()同样不进行任何IO操作,只影响$_SESSION数组。
Session生命周期(session lifetime):Session失效时间与过期回收机制
我们把初始化session开始,直到注销session这段期间,称为session生命周期。默认的,php会将session保存在php.ini配置中session.save_path设定的目录下
设置SESSION的生命周期:
php session是基于cookie的,所以要设置session的生命周期,首先要设置cookie的失效时间。因为在客户端(如浏览器)登录网站时,SESSION 是否有用,首先找客户端是否有 COOKIE,通过COOKIE 中的 SESSION ID 去找服务器上的文件。
其实PHP5 Session还提供了一个函数 session_set_cookie_params(); 来设置PHP5 Session的生存期的,该函数必须在 session_start() 函数调用之前调用
在服务器端,php如何判断session文件是否过期?
session.gc_maxlifetime = 1440 (初始值)#设置session存活时间,单位是秒。每次GC启动后, 会通过stat得到session文件最后访问的unix时间,通过现在时间减去文件最后访问时间之间大于session.gc_maxlifetime,则会删除该文件。
如果"最后的修改时间"到"现在"超过了session.gc_maxlifetime(默认是1440)秒,也就是说在这里设置的时间内,该文件没有被修改过,这个session文件就被认为是过期了,由于php5的session采用被动的回收机制,过期的session文件不会自己消失,而是通过触发“回收”来处理过期的session,那么在下一次session回收的时候,如果这个文件仍然没有被更改过,这个session文件就会被删除(session就过期了)。
session回收何时发生?
默认情况下,每一次php请求,就会有1%的概率发生回收,所以可能简单的理解为“每100次php请求就可能有一次回收概率发生”。这个概率是通过以下参数控制的:
session.gc_probability = 1 (初始值)
session.gc_divisor = 100 (初始值)
#由这二个函数决定了启用GC的概率,默认是1/1000。也就是说,每一千次用户请求中有一次会启动GC回收session。启动GC进程不宜过于频繁。过于频繁访问的网站,并发量大的网站,可减小PHP GC的启动频率。PHP GC回收session会降低php的执行效率。
这两个合起来就是启动Gabadge Collection(gc)进程管理概率的,在session初使化时(session_start())。Gabadge Collection启动后跟踪session信息文件。其启动概率为session.gc_probability/session.gc_divisor。也就是说不是每个session信息文件都有100%的被系统当作垃圾来处理的。如果直接关闭浏览器的话,session信息文件很多情况下都是留在了服务器上,如果把概率改成了100%,虽然Gabadge Collection百分之百被启动了,但是这会对服务器添加负荷,也就失去了GC本身的意义了。
补充说明:
假设这种情况session.gc_maxlifetime=1440,如果某个session文件最后修改时间是1440秒之前,那么在下一次回收(1/100的概率)发生前,这个session仍然是有效的;
如果你的session使用session.save_path中使用别的地方保存session,session回收机制有可能不会自动处理过期session文件。这时需要定时手动(或者crontab)的删除过期的session:cd /path/to/sessions; find -cmin +24 | xargs rm;
注意,当服务器端session文件数量没有得到有效的回收,逐渐增长到GB或更大级别时可能你的站点在存取session时就会越来越缓慢,多见于站点登入登出会受到影响;
写日志、周报、月报等时候我们最后提交的关头,有时会出现”无效的操作,请登陆后重试”等消息,其原因也不言而喻,可能就是session失效,gc清除那些已经“超时”的session文件。
一些特殊情况:
因为回收机制会检查文件的“最后修改时间”,所以如果某个会话是活跃的,但是session的内容没有改变过,那么对应的session文件也就没有改变过,回收机制会认为这是一个长时间没有活跃的session而将其删除。这是我们不愿看到的,可以通过增加如下的简单代码解决这个问题:
<?php
if(!isset($_SESSION['last_access'])||(time()-$_SESSION['last_access'])>120)
$_SESSION['last_access'] = time();
?>
php 会话控制(关于session的维护与生命周期)的更多相关文章
- hibernate学习系列-----(3)Session 缓存和持久化生命周期以及Session 基本操作
Session缓存原理 为了能够在控制台更好的看到我们的hibernate干了些什么,可以在hibernate.cfg.xml文件中写入如下配置: <!-- print all generate ...
- 会话控制:session与cookie
我们在浏览网站时,访问的每一个web页面都需要使用"http协议"实现.而HTTP协议是无状态协议,就是说HTTP协议没有一个内建机制来维护两个事务之间的状态.当一个用户请求一个页 ...
- php 会话控制(Session会话控制)
php的session会话是通过唯一的会话ID来驱动的,会话ID是一个加密的随机数字,由php生成,在会话的生命周期中都会保存在客户端.客户端保存数据的地方只有cookie,所以php的会话ID一般保 ...
- Servlet学习笔记(1)--第一个servlet&&三种状态对象(cookie,session,application)&&Servlet的生命周期
servlet的404错误困扰了两天,各种方法都试过了,翻书逛论坛终于把问题解决了,写此博客来纪念自己的第一个servlet经历. 下面我会将自己的编写第一个servlet的详细过程提供给初学者,大神 ...
- java之hibernate之session中对象的生命周期
1. session是用来执行对象的crud操作,并且session是对象事务工厂.session是线程级别的,所以生命周期比较短. 2.session中对象的生命周期图: 3.session中对象的 ...
- php会话控制cookie/session
设置cookie PHP设置Cookie最常用的方法就是使用setcookie函数,setcookie具有7个可选参数,我们常用到的为前5个: name( Cookie名)可以通过$_COOKIE[' ...
- php 会话控制(关于cookie的维护与生命周期)
cookie是在服务器端被创建并写回到客户端浏览器,浏览器接到响应头中关于写cookie的指令则在本地临时文件中. cookie内容的存储是键值对的方式,键和值都只能是字符串. 函数原型:setcoo ...
- 16/7/8_PHP-设置cookie会话控制(session与cookie)
设置cookie PHP设置Cookie最常用的方法就是使用setcookie函数,setcookie具有7个可选参数,我们常用到的为前5个: name( Cookie名)可以通过$_COOKIE[' ...
- 11月7日上午PHP会话控制(session和cookie)、跨页面传值
1.session 登录上一个页面以后,长时间没有操作,刷新页面以后需要重新登录. 特点:(1)session是存储在服务器: (2)session每个人(登陆者)存一份: (3)session ...
随机推荐
- Java对象的访问方式
之前写过一篇随笔 https://www.cnblogs.com/qianjinyan/p/10352749.html 现在看看,貌似不是很准确,方法区和栈应当区分开来,两者有很大的区别 看下面的一个 ...
- Python语法注意点
1. 在Python中定义函数,可以用必选参数.默认参数.可变参数.关键字参数和命名关键字参数,这5种参数都可以组合使用.但是请注意,参数定义的顺序必须是:必选参数.默认参数.可变参数.命名关键字参数 ...
- Systemd程序及相关命令
Systemd程序及相关命令 Systemd是一款用于Linux操作系统系统管理和服务管理的工具.它向后兼容SysV init脚本,并且支持许多类似于startup系统服务的功能,比如系统快照(sna ...
- vue 打开新页面
<router-link tag="a" target="_blank" :to="{path:'/system/detail?id=' + s ...
- vue轮播图实现
1.先安装组件 cnpm install vue-awesome-swiper; 2.在main.js下引入文件: import VueAwsomeSwiper from 'vue-awesome-s ...
- python中字符串格式化
username='小黑'age=18high=1.88s2='欢迎%s,年龄是%d,身高是%.2f'%(username,age,high)#%s是通用的,%d就必须传整数,%f就必须是小数,想保留 ...
- java 线程操作
停止线程 创建“停止标记”,thread.interrupt() 准确的说interrupt()方法只是“告知线程该停止了”,而线程检查到该“告知”后,再通过其他的办法停止线程. 线程调用了inter ...
- VirtualBox fedora29 安装
目录 准备工作 VirtualBox安装 fedora安装 快捷键定义 准备工作 平台配置 win10 64位 内存 8G 硬盘 1T 下载地址 VirtualBox 5.2.22:https://w ...
- cocos2d-x js 中创建node的方法
1.精灵Sprite 一共4种创建方式 (1) 根据图片资源路径创建 1 2 3 4 //参数1:图片资源路径 var sprite1 = cc.Sprite.create("res/zif ...
- 8.6 C++文本文件的读写操作
参考:http://www.weixueyuan.net/view/6412.html 总结: 文件类型: 计算机上的文件其实是数据的集合,对文件的读写归根结底还是对数据的读写操作.文件可以大致分为两 ...