会话跟踪技术之SESSION

一般来说,登录信息既可以存储在session中,也可以存储在cookie中,他们之间的差别在于session可以方便的存取多种数据类型,而cookie只支持字符串类型,同时对于一些安全性比较高的数据,cookie需要进行格式化与加密存储,而session存储在服务端则安全性较高

一、SESSION操作

1、 使用SESSION

在使用PHP session时,一定要在页头加上​​session_start()​​,告诉服务器开始使用session了,而且在它之前应该没有任何输出,否则会报错。

# 开始一个会话或者返回已经存在的会话
session_start();


2、设置session

$_SESSION['jack']['name'] = 'jack';
$_SESSION['jack']['height'] = 175;
$_SESSION['jack']['weight'] = 160.00;
$_SESSION['jack']['like'] = ['eat','run','sing','jump'];
$_SESSION['jack']['class'] = new test();
$_SESSION['jack']['null'] = null;
$txt = file_get_contents('hello.txt');
$_SESSION['jack']['res'] = $txt;

class test{
public function abc(){
echo 'test';
}
}

echo '<pre>';
var_dump($_SESSION);


session保存在配置文件(session.save_path)指定的服务器路径中。保存的格式:变量名|类型:长度:值

3、判断和删除

isset($_SESSION['name']);   // 判断
unset($_SESSION['name']); //删除


4、销毁session

如果要清空当前用户所有的Session信息可以使用以下代码:

session_destroy();       //销毁session 结束当前会话


二、SESSION的工作原理

  1. 用户访问WEB网站的时候,比如请求​​goods.php​​;
  2. 再运行​​session_start()​​时,PHP会给每个访问的用户创建一个session ID
  3. 该ID是唯一ID,同时使用该ID命名生成文本文件,在服务器端保存会话数据,
  4. 同时在客户机上cookie里存储该ID,
  5. 下次用户请求,就会携带该ID,来获取服务器上存储的会话数据

三、SESSION的几个注意点

1、session_start()前的输出

1、使用基于cookie的session时,函数session_start()必须在程序最开始执行,在其前面不能有任何输出内容,否则:

Warning: Cannot send session cache limiter - headers already sent (output started at ...


可以在php.ini里启动session.auto_start=1,这样就无需每次使用session之前都要调用session_start()。但启用该选项也有一些限制,如果确实启用了 session.auto_start,则不能将对象放入会话中,因为类定义必须在启动会话之前加载以在会话中重建对象。

2、session的存储方式

PHP的session默认是通过文件的形式实现的,即存储在服务器端的session文件,每个session一个文件。

文件名形式:sess_jkj7hkfje9klhgop8s0ferascdwedjksjkxj,
内容结构:`变量名 | 类型 |:长度 : 值;


3、客户端禁用Cookie功能

基于cookie的session更优化,但不总是可用。一旦用户关闭cookie,那么session就不起作用啦!所以接下来我们将要把session的id号放在链接地址上,这样就不怕用户关闭cookie啦!

PHP5在linux平台可以自动检测Cookie状态,如果客户禁用它,则系统自动把sessionId附加到URL上传送。但windows没有此功能

a. login.php

<?php
session_start();
?>
<html>
<head>
<title>login</title>
</head>
<body>
<form action="act.php?<?php echo SID;?>" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="pass"><br/>
<input type="submit" name="send" value="login">
</form>
</body>
</html>


act.php

if( isset($_GET[session_name()]) ){
$sid = $_GET[session_name()];
session_id($sid);
}
session_start();

$_SESSION['name'] = $_POST['username'];
$_SESSION['pass'] = $_POST['pass'];

var_dump($_SESSION);

echo '<a href="logout.php?'.SID.'">退出</a>';


logout.php

if( isset($_GET[session_name()]) ){
$sid = $_GET[session_name()];
session_id($sid);
}
session_start();

$_SESSION = [];
setcookie(session_name(),'',time()-1,'/');
session_destroy();

四、SESSION中的几个常用函数

1、session_start() 启动新会话或者重用现有会话

​session_start()​​ 会创建新会话或者重用现有会话。 如果通过 GET 或者 POST 方式,或者使用 cookie 提交了会话 ID, 则会重用现有会话。 开启session,并生成session_id,创建服务器端会话数据

要使用基于 cookie 的会话, 必须在输出开始之前调用 session_start() 函数。

2、session_name()

session.name设置会话的名称,即在客户端用作cookie的标示符名称。默认值为PHPSESSID

/* 设置会话名称为 WebsiteID */
$previous_name = session_name("WebsiteID");


3、session_id() 获取/设置当前会话 ID

  1. session_id() 返回当前会话ID。 如果当前没有会话,则返回空字符串("")
  2. 如果指定了 id 参数的值, 则使用指定值作为会话 ID。 必须在调用 session_start() 函数之前调用 session_id() 函数
  3. 为了能够将会话 ID 很方便的附加到 URL 之后, 你可以使用常量 SID 获取以字符串格式表达的会话名称和 ID

4、session_destroy 销毁一个会话中的全部数据

​session_destroy()​​ 销毁当前会话中的全部数据, 但是不会重置当前会话所关联的全局变量, 也不会重置会话 cookie。 如果需要再次使用会话变量, 必须重新调用 ​​session_start()​​ 函数


五、php.ini中关于session的配置

1、session.auto_start

是否自动启动session,0表示禁止,1表示开启,默认不启动。 我们知道在使用session功能时,我们基本上在每个php脚本头部都会通过session_start()函数来启动session,如果你启动这个选项,则在每个脚本头部都会自动启动session,不需要每个脚本头部都以session_start()函数启动session,推荐关闭这个选项,采用默认值

2、session.save_path

session.save_path用于设置会话在服务存储路径。默认值为/tmp

3、session.use_cookies

session.use_cookies用于设置是否允许在客户端使用cookie会话,默认值为1,表示允许

4、session.use_only_cookies

是否仅仅使用cookie在客户端保存会话sessionid,这个选项可以使管理员禁止用户通过URL来传递id,默认为0,如果禁用的话,客户端如果禁用Cookie将使session无法工作

5、session.gc_divisor

定义在每次初始化会话时,启动垃圾回收程序的概率。计算公式如下:​​session.gc_probability/session.gc_divisor​​,比如1/100,表示有1%的概率启动启动垃圾回收程序,对会话页面访问越频繁,概率就应当越小。建议值为1/1000~5000

六、session过期时间

在php.ini文件中有这样一个配置,这个配置表示session文件过期时间,默认的话是1440秒,也就是24分钟,这个24分钟是session的发呆时间,如果在24分钟内没有对session进行操作,那么session文件就会过期,如果在23分钟的时候操作了session,那么就会又有24分钟的过期时间,如果过期了,该session被服务器认为是垃圾。

session.gc_maxlifetime = 1440

垃圾回收机制控制

还有这样的两个配置,服务器每次session_start的时候,都有可能启动垃圾回收机制去删除垃圾文件,这个概率为session.gc_probability / session.gc_divisor。

session.gc_probability = 1
session.gc_divisor = 1000


我们可以这样进行配置,来体会一下session垃圾回收机制。

session.gc_maxlifetime = 60
session.gc_probability = 1000
session.gc_divisor = 1000


这样session的过期时间为60秒,还有就是每次session_start的时候都会去开启gc,然后删除垃圾。

然后写一个脚本:gc.php

<?php

session_start();

测试

1、然后第一次启动浏览器去请求gc.php,然后关闭浏览器,这个时候会产生第一个session文件,如果没有配置的话,默认是在C:\Window\Temp目录下,这个目录也可以进行配置。

2、第二次启动浏览器去请求gc.php,然后关闭浏览器,这个时候会产生第二个session文件

3、第三次启动浏览器去请求gc.php,不关闭浏览器,然后不断的去刷新gc.php,都会去调用session_start方法,由于我们前面进行了相应的配置,所以每次session_start的时候都会去调用gc,然后gc去检测一下是否有垃圾文件,如果有垃圾文件,就将其删除,我们会看到前两个文件一个一个的被删除。