Bootstrap

PHP 的 Session 与 Cookie

为什么需要会话控制技术?

​ 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 的使用

  1. 开启 Session: session_start()
  2. 使用 Session: $_SESSION 直接操作 SESSION 数组就可以
  3. 清空 Session: $_SESSION=[] 或 $_SESSION = null
  4. 删除 Session (包括文件和 Cookie): session_destroy()

Session 的配置  php.ini  文件

  • session.auto_start  是否自动开启 Session

  • session.cookie_domain  设置 Session 的有效域名

  • session.cookie_lifetime  设置的 cookie 有效时间,是从创建了这个 cookie 时开始计算,不会因为操作而刷新

  • session.cookit_path  设置 session 有效服务器路径

  • session.name  存储在客户端的 Cookit 的名称,

  • session.save_path  设置 session 在服务器存储路径

  • session.use_cookies  是否使用 Cookie 传递 session

  • session.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 的垃圾回收机制,大概流程是这样的:

  1. 当用户长时间没有再次访问 Session,比如刷新、修改、添加等操作(时间根据:session.gc_maxlifetime 设置的秒数,默认 1440,PHP5 默认 1500),超过这个时间 则 Session 将会被设为过期的 “垃圾文件”
  2. 当 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  设置用户自定义会话存储函数。

;