如果您希望在每次登录时更改会话 ID,请确保在登录过程中使用 session_regenerate_id(true)。
<?php
session_start();
session_regenerate_id(true);
?>
[由版主(php dot net 上的 googleguy)编辑]
(PHP 4, PHP 5, PHP 7, PHP 8)
session_destroy — 销毁注册到会话的所有数据
session_destroy() 销毁与当前会话关联的所有数据。它不会取消设置与会话关联的任何全局变量,也不会取消设置会话 Cookie。要再次使用会话变量,必须调用 session_start()。
注意: 您不必从常规代码中调用 session_destroy()。清理 $_SESSION 数组而不是销毁会话数据。
为了完全终止会话,还必须取消设置会话 ID。如果使用 Cookie 传播会话 ID(默认行为),则必须删除会话 Cookie。setcookie() 可用于此目的。
当 session.use_strict_mode 启用时。您不必删除过时的会话 ID Cookie,因为当没有与会话 ID 关联的数据时,会话模块将不接受会话 ID Cookie,并设置新的会话 ID Cookie。建议所有站点都启用 session.use_strict_mode。
立即删除会话可能会导致意外结果。当存在并发请求时,其他连接可能会看到突然的会话数据丢失。例如,来自 JavaScript 的请求和/或来自 URL 链接的请求。
尽管当前会话模块不接受空会话 ID Cookie,但由于客户端(浏览器)端的竞争条件,立即删除会话可能会导致空会话 ID Cookie。这将导致客户端不必要地创建许多会话 ID。
为了避免这些问题,您必须将删除时间戳设置为 $_SESSION 并稍后拒绝访问。或者确保您的应用程序没有并发请求。这也适用于 session_regenerate_id()。
此函数没有参数。
示例 #1 使用 $_SESSION 销毁会话
<?php
// 初始化会话。
// 如果您使用 session_name("something"),请勿忘记现在使用!
session_start();
// 取消设置所有会话变量。
$_SESSION = array();
// 如果需要终止会话,还要删除会话 Cookie。
// 注意:这将销毁会话,而不仅仅是会话数据!
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
// 最后,销毁会话。
session_destroy();
?>
如果您希望在每次登录时更改会话 ID,请确保在登录过程中使用 session_regenerate_id(true)。
<?php
session_start();
session_regenerate_id(true);
?>
[由版主(php dot net 上的 googleguy)编辑]
我花了一段时间才弄清楚如何在 php 中销毁特定会话。请注意,我不确定下面提供的解决方案是否完美,但它似乎对我有用。请随时发布任何更简单的销毁特定会话的方法。因为它对于强制用户离线的功能非常有用。
1. 如果您使用数据库或 memcached 来管理会话,您可以始终直接从数据库或 memcached 中删除该会话条目。
2. 使用通用的 php 会话方法删除特定会话(按会话 ID)。
<?php
$session_id_to_destroy = 'nill2if998vhplq9f3pj08vjb1';
// 1. 如果已启动,则提交会话。
if (session_id()) {
session_commit();
}
// 2. 存储当前会话 ID
session_start();
$current_session_id = session_id();
session_commit();
// 3. 劫持然后销毁指定的会话。
session_id($session_id_to_destroy);
session_start();
session_destroy();
session_commit();
// 4. 恢复当前会话 ID。如果不恢复它,您的当前会话将引用您刚刚销毁的会话!
session_id($current_session_id);
session_start();
session_commit();
?>
我发现,为了在调用 session_destroy() 后真正清除会话数据,您需要刷新页面。例如,通过调用
header('Location: '.$_SERVER['PHP_SELF']."?page=profile");
如果这不是你的预期,那么在 $_SESSION 中仍然存在之前的数据。我不知道这是否是预期的行为,但在我看来有点令人困惑……