PHP 的会话(session)机制是一种在服务器端存储用户数据的方法,以便在用户浏览网站的不同页面时持久化数据。会话在用户访问网站的不同页面时保持状态信息,使得开发者可以创建动态、个性化的用户体验。
基本概念
-
会话的开始:
- 使用
session_start()
函数来启动一个新的会话或恢复现有会话。这个函数必须在任何输出之前调用,例如在脚本的开头。
<?php session_start(); // 启动会话
- 使用
-
会话变量:
- 使用全局关联数组
$_SESSION
来存储会话数据。会话数据可以是任何类型的变量,如字符串、数组或对象。
$_SESSION['username'] = 'Alice'; $_SESSION['age'] = 30;
- 使用全局关联数组
-
会话的使用:
- 可以在不同的页面中访问和修改会话变量,只要在脚本的开头调用
session_start()
。
<?php session_start(); // 恢复会话 echo 'Username: ' . $_SESSION['username']; // 输出: Username: Alice
- 可以在不同的页面中访问和修改会话变量,只要在脚本的开头调用
-
销毁会话:
- 使用
session_destroy()
函数来销毁会话。需要注意的是,这只会销毁会话数据,但不会删除会话 cookie。
<?php session_start(); // 启动会话 session_destroy(); // 销毁会话
- 使用
工作原理
-
会话 ID:
- 会话机制依赖于一个唯一的会话 ID(通常通过 cookie 传递),用来标识特定用户的会话数据。会话 ID 由服务器生成并发送给客户端。
-
服务器端存储:
- 会话数据存储在服务器端,可以是文件系统、数据库或其他存储机制。PHP 默认使用文件系统来存储会话数据。
-
客户端存储:
- 客户端仅存储会话 ID,这个 ID 通常通过 cookie 传递,也可以通过 URL 参数传递。这种方式确保了会话数据的安全性,因为实际数据存储在服务器端。
示例
sess文件默认会在会话结束后清除,试验时为了便于观察请设置
session.upload_progress.cleanup = Off
<?php
session_start(); $_SESSION['username'] = 'Alice';
$_SESSION['age'] = 30;
你能在/tmp中找到临时的sess_xxx文件,其中xxx的值由PHPSESSID
决定,你应该能看到如下内容
username|s:5:"Alice";age|i:30;
PHP
有一个upload_porcess
机制,可以在$_SESSION
中创建一个键值对,其中的值可控,可以使用以下模板。
POST / HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Connection: keep-alive
Host: 127.0.0.1
Content-Length: 297
sec-ch-ua: "Not?A_Brand";v="99", "Chromium";v="130"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Accept-Language: zh-CN,zh;q=0.9
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarykzIaxe68ihaPsyDo
Upgrade-Insecure-Requests: 1
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Cookie: PHPSESSID=A5rZ------WebKitFormBoundarykzIaxe68ihaPsyDo
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"dwdadwd
------WebKitFormBoundarykzIaxe68ihaPsyDo
Content-Disposition: form-data; name="file"; filename="A5rZ"
Content-Type: text/plainwdfgsfw
------WebKitFormBoundarykzIaxe68ihaPsyDo--
这会在sess_xxx生成如下内容,这些内容在会话没有结束前不会消失
upload_progress_dwdadwd|a:5:{s:10:"start_time";i:1738481644;s:14:"content_length";i:297;s:15:"bytes_processed";i:297;s:4:"done";b:1;s:5:"files";a:1:{i:0;a:7:{s:10:"field_name";s:4:"file";s:4:"name";s:4:"A5rZ";s:8:"tmp_name";s:41:"C:\Install\CTF\Wampserver\tmp\php940D.tmp";s:5:"error";i:0;s:4:"done";b:1;s:10:"start_time";i:1738481644;s:15:"bytes_processed";i:7;}}}username|s:5:"Alice";age|i:30;