为什么需要会话控制技术?
HTTP是无状态协议,没有一个内建机制维护两个事物之间的状态。同一个用户请求两次HTTP请求时,HTTP协议不会认为这两次请求都来自同一个用户,会当成两个独立的请求来处理。也就没有办法保持用户的登陆状态,所以会话控制技术的核心思想是 允许客户端跟踪服务端做出的连续请求 ,从而完成登陆状态的保持。
Cookie: 服务器发送给客户端的片段信息, 存储在客户端浏览器的内存或硬盘中的一种技术。
写Cookie: setcookie(name,value,expire,path,domain,secure)
- name:Cookie名称,可以使用 'a[b]'
- value:Cookie值
- expire:Unix时间戳,以秒为单位,如果不设置,则在浏览器关闭时过期
- path:有效服务器路径,设置为 '/' 时,对整个域名domain有效,如果设置为 '/foo/' ,则仅对domain中/foo/目录及其子目录有效(例如:/foo/ban/)
- domain:Cookie的有效域名/子域名,设置成子域名(例如:'www.example.com' ),会使Cookie对这子域名和他的三级域名有效(例如:w2.www.example.com)。要让Cookie对整个域名有效,设置顶级域名就行了(例如:example.com)
- 读取Cookie: $_COOKIE
- 删除Cookie: setcookie(name,'',time()-1) ,把Cookie设为过期即可
Cookie优缺点:
优点: 存储在客户端不会浪费服务器资源
缺点: 由于数据存储在客户端,不建议将一些敏感重要的数据使用Cookie存储。客户端有权限禁用掉Cookie的使用。
Session: 将用户的数据 存储在服务器 当中,用户无法禁止掉Session使用,但 Session不是完全脱离Cookie的 。Session是通过服务器客户端Cookie带过来的SESSIONID来确定用户数据的,如果Cookie被禁用,需要通过URL传递SESSIONID的形式保存SESSION的状态。
Session的使用
- 开启Session:
session_start()
- 使用Session:
$_SESSION
直接操作SESSION数组就可以 - 清空Session:
$_SESSION=[]
或$_SESSION = null
- 删除Session(包括文件和Cookie):
session_destroy()
Session的配置 php.ini
文件
session.auto_start
是否自动开启Sessionsession.cookie_domain
设置Session的有效域名session.cookie_lifetime
设置的cookie有效时间,是从创建了这个cookie时开始计算,不会因为操作而刷新session.cookit_path
设置session有效服务器路径session.name
存储在客户端的Cookit的名称,session.save_path
设置session在服务器存储路径session.use_cookies
是否使用Cookie传递sessionsession.use_trans_sid
是否允许SESSIONID通过URL明文传输session.gc_probability
清理多少次垃圾session.gc_divisor
每访问多少次session.gc_maxlifetime
设置的session的最大生命周期session.save_handler
设置存储方式,可以存储到Redis中或MySQL中,默认是'files'类型,即文件存储
Session垃圾回收机制
Session是存储在服务器上的,如果用户没有走退出程序而是直接关闭掉了浏览器,则Session文件会永久的保存在服务器上,时间长了会撑满内存,这个适合就需要使用Session的垃圾回收机制,大概流程是这样的:
- 当用户长时间没有再次访问Session,比如刷新、修改、添加等操作(时间根据:
session.gc_maxlifetime
设置的秒数,默认1440,PHP5默认1500),超过这个时间 则Session将会被设为过期的“垃圾文件” - 当Session被设置为垃圾文件时,PHP每被请求设定次数 (次数根据:
session.gc_divisor
设置的次数,默认1000),清除设定个数文件(session.gc_probability
默认是1次,也就是说每访问1000次清空一个过期文件),不建议把清除次数设置的特别小,会消耗服务器资源
优点: 数据存储在服务器,相比Cookie比较更安全。
缺点: 占用服务器资源,如果垃圾回收机制设置不合理,会撑满服务器硬盘。
Cookie被禁用时如何传递SESSIONID
<!-- 使用session_name()和session_id()传递 -->
<a href="<?php echo session_name().'='.session_id()?>">下一个页面</a>
<!-- 使用SID常量传递,SID比较智能,比较推荐使用这个-->
<!-- 在Cookie开启的时候,值为空,Cookie禁用的时候才会输出 -->
<a href="<?php echo SID?>">下一个页面</a>
Session存储共享(Redis/MySQL/Memcache)
如果需要使用多台服务器的话,直接将Session存储到其中一台服务器的时候,可能下次访问的时候就是另一台服务器了,这种情况下Session因为不能共享的原因会导致用户的Session信息无法共享在其他的服务器上。这时需要使用 session_set_save_handler
设置用户自定义会话存储函数。