当你打开一个网站,浏览网站的内容,向网站提交一些数据,然后关闭了这个网站,这就是一次session。你自己的电脑知道你何时打开和关闭这个网站,但是,由于HTTP协议是无状态的,网站并不知道你是谁、你做了什么。

session变量就是来解决这个问题的。在session变量中存储了用户的一些信息(用户名、刚才执行的动作等等),当用户从一个网页跳转到另一个网页时,网站就可以通过这些信息来获知当前是哪一用户做了哪些事情。

为了实现这机制,网站在用户的浏览器中存储了一个session cookie,该cookie的名称默认为PHPSESSID,在我的电脑上是这样的:

PHPSESSID中存储的值为当前session的id,通过该id,网站可以获取当前用户的session。

这些选项都是在php.ini中设置的:

1
2
3
4
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.cookie_lifetime = 0
  • 第一条配置是设置session使用cookie(session cookie)来存储session id。
  • 第二条配置是设置session只使用session cookie来存储session id。
  • 第三条配置是设置session cookie的名称为PHPSESSID
  • 第四条配置是设置seesion cookie的生存周期,默认情况下,浏览器一旦关闭,session就会被销毁。

注:
PHP的session只在用户的本地session cookie中存储了session id。与persistent cookie
将数据存储在用户端不同, session的数据主要是存储在服务端,所以session的数据对用户
不可见,用户可以直接修改本地的persistent cookie。从这个角度看,session比persistent cookie
要安全一些。所以,如果如果你的数据只需要在当前会话中使用,建议使用session机制。

如果用户完全禁用cookie,服务端就无法在用户本地保存session id,我们需要一种变通的方法来实现session机制。

测试代码如下:

index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php

ini_set("session.use_cookies", 0);
ini_set("session.use_only_cookies", 0);
ini_set("session.use_trans_sid", 1);

session_start();

if (!empty($_REQUEST['firstname']) && !empty($_REQUEST['lastname'])) {
$_SESSION['firstname'] = $_REQUEST['firstname'];
$_SESSION['lastname'] = $_REQUEST['lastname'];
}

echo session_id() . "<br>";
var_dump($_SESSION); echo "<br>";
?>

<!DOCTYPE html>
<html>
<body>
<form action="/">
First name:<br>
<input type="text" name="firstname" ><br>
Last name:<br>
<input type="text" name="lastname" ><br>
<input type="submit" value="Submit">
</form>
</body>
</html>

我使用ini_set这一方法来配置php的一些选项,前两条是禁用cookie,这样服务端就不能使用默认的方式来实现session机制。在第三条中,当session.use_trans_sid选项设置为1时,如果我们向服务端传送数据,就会在URL后自动加上当前的session id参数。就像这样:

第一次提交之后,我将客户端发来的数据存储到session中,并打印$_SESSION变量。如下:

当我们再次提交按钮,得到如下的结果:

于是,通过每次将session id以url参数的形式传给后端,我们实现了无cookie情况下得session机制。

不过,由于这种方式将session id以参数形式传送,所以,有可能造成会话劫持。建议还是尽量还是使用默认的session cookie机制来存储session id。