# SESSION技术
>[success]SESSION与COOKIE的作用相似,也是用来存储客户的相关数据。两者最大的不同在于Cookie存在客户端,而SESSION存储在服务端。PHP默认把SESSION以文件的形式存储在服务器的某个文件下,每个客户拥有不同的session文件,**此外还可以灵活修改默认存储方式,可以使用数据库或者redis或Memcache进行存储。**
## SESSION实现机制
当某个用户访问站点时,服务器就检查这个客户端的请求头里是否携带了sessionID的头信息,如果包含说明已经为其创建了SESSION。否则,为其创建一个SESSION【文件】并生成一个唯一的与之关联的SessionID,在响应中加入到响应头。在会话期间,每个请求都会携带这个SessionID给服务端。
## SessionID的特点
一般由32位16进制数组成的字符串组成,是一个既不重复又不容易被找到的字符串。
## 如果客户端禁用了Cookie?
可以把SessionID保存在浏览器地址栏的URL中,就像一个普通的查询参数。服务端即可获得对应的Session信息。
```
ini_set('session.use_trans_id', 1);
if (isset($_GET[session_name()])) {
//关键代码
session_id($_GET[session_name()]);
}
session_start();
$_SESSION['user'] = 'zhangsan';
var_dump($_SESSION);
echo SID;//PHPSESSID=ghqvdqmimba5p25iirdm46aj71
//如果启用了Cookie,SID是空的字符串
```
## Session配置
| 配置项 |意义 |默认值 |
| --- | --- |--- |
| session.auto_start | 访问任何页面时都自动开启并初始化Sesion |0(禁止),需要手动执行session_start() |
| session.cookie_domain | 传递会话ID的Cookie作用域 |none(自动生成)|
| session.cookie_lifetime | 会话ID的Cookie有效期 |0(浏览器关闭就消失)|
| session.cookie_path | 会话ID的Cookie作用路径 |/|
| session.name | 会话ID的Cookie标识符名称 |PHPSESSID|
| session.save_path| 基于文件存储,文件路径 |/tmp|
| session.use_cookies| 是否使用客户端Cookie保存会话ID |1|
| session.use_trans_id| 是否使用URL携带SessionID |false(不安全,禁止)|
| session.gc_probability| 定义垃圾回收启动的概率 |1|
| session.gc_divisor| 定义垃圾自动回收的概率 |1000|
| session.gc_maxlifetime|超过设定秒杀后会话数据将被当做垃圾回收 |1440|
| session.save_handler| 设置会话数据的处理器|files|
## 创建Session
```
session_start();
$_SESSION['user'] = 'zhangsan';
```
![](https://img.kancloud.cn/19/f3/19f3923e9d70505f0ac095721787958f_570x201.png)
![](https://img.kancloud.cn/01/df/01df6d8186ae30f76e6d441210718b27_878x333.png)
![](https://img.kancloud.cn/65/c2/65c21f944fd9510723085ee8e7ae17f4_608x253.png)
![](https://img.kancloud.cn/a2/86/a2865b66c5747c80fb24cab56754db8b_337x74.png)
## 获取SESSION
```
session_start();
var_dump($_SESSION);
```
## 销毁Session和注销标量
```
session_start();
$_SESSION['user'] = 'zhangsan';
session_destroy();
var_dump($_SESSION['user']);//zhangsan
```
>[info]session_destroy()会删除session_start()创建的文件,但不会释放和当前SESSION相关的变量,也不会删除保存在客服端Cookie中的SessionID。如需全部清除执行如下代码
```
session_start();
unset($_SESSION['user']);
//或者全部清除
$_SESSION = [];
//确保是基于Cookie机制的SessionID才需要
if(isset($_COOKIE[session_name()])){
setcookie($_COOKIE[session_name()],'',time()-1);
}
session_destroy();
```
## Session自动回收机制
>[info]每次进行请求都会修改session文件的有效期,即使只是刷新。只要用户有在操作。
>[info]用户没有动作,到达Session有效期后,不管浏览器是否开启,Session都会自动消失。
>[info]Session到达有效期后并不是绝对能立即被垃圾回收机制处理。
>[info]垃圾自动回收的启动机制决定于gc_probability/gc_divisor的计算公式,即执行了多少次session_start()后启动垃圾回收机制。此时,超过有效期的session垃圾将全部被回收。
>[danger]每个页面Session相关操作都必须先session_start();,如果是统一入口文件,只需设置1次。
## 思考
***SESSION使用文件处理机制的缺陷。***
* 登录用户数量比较多时,文件操作的IO开销很大,会严重影响系统的执行效率
* Session只能存储在一台服务器,无法跨机。对于采用多台WEB服务器处理访问量比较大的并发处理的系统,不能达到跟踪用户的目的。