0

我有以下基本的注销脚本,我认为它的功能很奇怪:

<?php
session_start();

$_SESSION['customerState'] = array("abbr"=>"TX","full"=>"Texas");
$_SESSION['agent']['url'] = "jmarston4";

$fart = isset($_SESSION['customerState']) ? $_SESSION['customerState'] : array();
$url = isset($_SESSION['agent']['url']) ? $_SESSION['agent']['url'] : '';

$_SESSION = array();

if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}

echo "Fart1: ";
print_r($fart);

session_destroy();

echo "<br>Fart2: ";
print_r($fart);

session_start();

echo "<br>Fart3: ";
print_r($fart);

$_SESSION['fart'] = $fart;

echo "<br>Fart4: ";
print_r($_SESSION['fart']);

#exit;

header('Location: https://'. $_SERVER['HTTP_HOST'] . '/' .$url);

此页面使用引用 URL(称为 $url)重定向到站点主页 (index.php)。这可以正常工作。为了测试起见,这里是 index.php 上所有代码的屏幕截图:

http://imgur.com/EmkRAh0

如果我允许exit;处理,以下内容将输出到屏幕:

Dart1: Array ( [abbr] => TX [full] => Texas )

Fart2:数组([缩写] => TX [完整] => 德克萨斯)

Dart3: 数组 ( [abbr] => TX [full] => Texas )

Dart4: Array ( [abbr] => TX [full] => Texas )

(或视觉:http: //imgur.com/A6WuRfx

在这个脚本 (logout.php) 中,我想从客户会话中保留一个 SESSION 变量(而不是手动取消设置 100 多个其他变量),以便我可以将其传递回主页以供内部使用。为此,脚本执行以下操作:

  • 设置 SESSION 变量 'fart' 等于一个数组
  • 然后在整个 SESSION 被销毁之前将局部变量设置为等于 SESSION 'fart'
  • 会话数据被清除
  • 会话 cookie 被删除
  • 会话被破坏
  • SESSION 'fart' 被创建并设置回 $fart 数组
  • 页面重定向到主页。

问题

按照设计,PHP SESSIONS 是否应该以这种方式运行?如果是这样,一个人怎么能从本质上破坏会话(例如出于注销目的),同时维护在该用户会话期间收集的会话信息。

注意:我使用的是 SESSION 数组,因此出于 GET 目的传入 URL 不适用于此处。

更新说明:

  • 我将这个问题的标题从“PHP 会话的行为是否符合规范?”

  • 所有这些都适用于脚本本身,但是,当我尝试访问主页上的 $_SESSION['fart'] 时,它没有设置。我可以随时在页面上设置、操作或更改 SESSION 变量,包括在session_destroy()调用之后。例如,如果我想执行以下操作:

    ... session_destroy()

    $_SESSION['eatmyshorts'] = "你好!";

    回声 $_SESSION['eatmyshorts']; // 将显示你好!……

    但是,一旦脚本(页面)结束,与会话相关的任何内容(即使$_SESSION['eatmyshorts']在这种情况下,在任何其他页面上都不可用并且被忽略。

4

3 回答 3

1

一旦你调用session_destroy了会话,那么会话数据就会被销毁,并且会话数据的服务器端存储也会被删除。之后操作$_SESSIONviariable 没有任何效果,因为它不再“绑定”到实际会话(即,当脚本结束时,您设置的数据不会写入会话数据存储)。

于 2013-08-21T20:23:32.527 回答
1

如果您调用session_destroy存储的会话数据将被销毁,$_SESSION被清空,并且“会话状态”会像之前一样session_start重置。在这种状态下,数据$_SESSION仅在运行时存在。现在,如果您调用session_startafter session_destroy,会话处理的行为与运行时中的第一个活动会话完全相同:如果客户端请求包含语法上有效的会话 ID,它将使用它进行此会话。

这一切按预期工作。

但是,您没有考虑的是当您删除包含 ID 的会话 cookie 时会话的行为方式。因为当您发送 cookie 以撤销客户端的会话 ID 时,客户端不会在下一个请求中发送会话 ID,而是session_id会生成一个新的会话 ID。由于它是一个新会话,$_SESSION因此是空的。

如果要撤销当前会话 ID 并生成新会话 ID,请使用session_regenerate_id(true)session_unset

于 2013-08-21T21:20:32.150 回答
0

所有这些都适用于脚本本身然后您提供的代码没有任何问题(除了缺少 session_start(),但您说您将其放入 - 您应该在上面编辑您的代码,因为人们正在根据它进行回复一个明显的错误)我在上面尝试了您的代码并确认它可以独立运行。

要获得帮助,您应该解释或(理想情况下)显示其余代码,以便对其进行评估并发现问题的根本原因。

尝试将您的底部代码更改为此并告诉我们结果

echo "Fart1: ".$fart;

session_destroy();

echo "<br>Fart2: ".$fart;

session_start();

echo "<br>Fart3: ".$fart;

$_SESSION['fart'] = $fart;
//header('Location: /'); exit; <-- commented out

echo "<br>session: ".$_SESSION['fart'];

尽管您自己让它工作,并且确定session_start()它存在于它重定向到的文件中并且在任何 HTML 输出之前位于文件的顶部,但也尝试重定向到实际页面名称以排除其他内容,即

header('Location: index.php'); exit; //or whatever filename is your homepage

还要回答您关于如何正确执行此操作的其他问题,您的操作方式很好,因为您将 var 设置为该值,再次启动会话并将 $_SESSION 设置为 var 值。您可以直接访问 $_SESSION 数据,例如

$_SESSION['userlogin']['username'] = 'james';
//log me out from the session =
$_SESSION['userlogin']['username'] = '';
于 2013-08-21T20:26:49.403 回答