为什么PHP的session_destroy()函数没有起作用?

51

我尝试使用session_destroy()方法来销毁所有的会话变量,但是在使用该方法后,这些值并没有被销毁。

为什么session_destroy()不起作用?

在PHP中还有其他销毁会话的方法吗?

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) 
{   
    session_destroy();   
    session_unset();     
}

1
请展示您正在使用的代码。 - Charles
2
“这不是一个很明确的问题。您能解释一下哪里出了问题吗?例如,您可以使用array_dump函数来输出$_SESSION变量的值。” - Kevin Ji
1
我仍然很想知道你在http://stackoverflow.com/questions/6471182/how-to-configure-gmail-in-php-at-run-time中所说的意思。 - Mike B
2
session_destroy(); 之后仅使用 unset($_SESSION['LAST_ACTIVITY']); 将清除该变量。 - yitwail
10个回答

127
确保在销毁会话之前先初始化它。
session_start();
session_destroy();

你不能在logout.php中销毁一个在index.php中初始化的会话。你必须在销毁会话之前在logout.php中启动会话。

11
“session_destroy”不能在没有“session_start”的情况下使用,因此这个回答应该被接受。 - Andrew
这个答案是不正确的。首先,压制错误是一种不好的做法。其次,它会销毁会话,但不会取消会话变量或使会话 cookie 失效。这个答案非常不完整。 - Nilpo
@Nilpo,这里的问题是“为什么session_destroy不起作用”,而不是“取消session变量”。OP误解了session_destroy的真正作用。 - keanu_reeves
@keanu_reeves:OP说(除了拼写错误等):“我尝试使用session_destroy()销毁所有会话变量,但是使用此方法后,值并未被销毁。” OP似乎已经接受了正确的答案。 (但是,仍然存在一个谜团,即为什么session_unset()对他没有起作用。) - Sz.
@keanu_reeves,啊,但是“研究”问题的编辑历史,里面潜藏着一个完整的替代故事情节! :) 很可能第一位编辑者(kevinji)也误解了问题,然后OP误解了更新的意图,批准了更改,然后似乎一切都已经无望地偏离了轨道。 :) (尽管如此,结果是一个信息丰富的页面。) - Sz.
帮助了我的情况...我创建了一个logout.php并执行了session destroy。忘记先启动会话了。谢谢。 - Allen Johnson

65

使用session_destroy()函数后,会在幕后销毁会话。由于某些原因,这不会影响已经填充到此请求中的$_SESSION中的值,但是在将来的请求中它将为空。

如果需要,您可以手动清除$_SESSION$_SESSION = [];)。


作为一条注释,如果操作者需要的话,有一个名为session_unset的函数。 - Gabi Purcaru
15
@Gabi,“session_unset”用于PHP3时代的全局注册,不应再使用。 - Charles
4
session_destroy()函数不能移除会话cookie,需要手动作废。 - Nilpo
谢谢您的 $_SESSION = [];。我知道我不应该使用它,但它清除了会话,这正是我所需要的。黑客就是生活。 - BeNice

18
如果您需要清除 $_SESSION 的值,请将该数组设置为空数组:
$_SESSION = array();

当使用session_destroy函数后,你不能在其他页面访问$_SESSION的值,因此这并不太重要。

请尝试以下操作:

session_destroy();
$_SESSION = array(); // Clears the $_SESSION variable

2
不,你不需要调用 session_unset。它是针对 PHP3 时代的全局注册机制,现在没有人应该使用它。 - Charles
@Charles 我也是这样认为的,但我不想修改原始帖子中的代码。话虽如此,还是被删除了。 - Kevin Ji
很棒的答案 - 返回导航不再显示变量。 - Leo
我找到了这个方法:http://www.hackingwithphp.com/10/3/5/ending-a-session 这是正确的做法吗? - Skadoosh

5

我还需要删除会话cookie,方法如下:

session_start(); 
$_SESSION = []; 

// If it's desired to kill the session, also 
// delete the session cookie. 
// Note: This will destroy the session, and 
// not just the session data! 
if (ini_get("session.use_cookies")) { 
    $params = session_get_cookie_params(); 
    setcookie(session_name(), '', time() - 42000, 
        $params["path"], $params["domain"], 
        $params["secure"], $params["httponly"] 
    ); 
} 

// Finally, destroy the session. 
session_destroy();

Source: geeksforgeeks.org


1
不错,干净而完整。自7.3以来,您还可以执行setcookie(session_name(), '', session_get_cookie_params()),如果回溯到期日不是很重要(空会话ID应该足够了,并且大多数应用程序很快会设置新的cookie)。当然,如果PHP提供了一些unsetcookie($name[, $params]),那就更好了。(顺便说一句,现在[]array()更受欢迎。;)) - Sz.

4

实际上,它是有效的,但你还需要在session_destroy之后执行$_SESSION = array();来清除$_SESSION变量。然而,避免使用unset($_SESSION),因为那会使会话无效。


使用session_destroy()销毁会话将使会话变得无用。 - Ivo Pereira
@IvoPereira PHP手册指出两者都是必需的。仅使用session_destroy()不足以完成任务。 - Nilpo
2
session_destroy() 使特定的会话无用。unset($_SESSION) 同样会使未来的会话无用。从 PHP 手册中,注意 不要使用 unset($_SESSION) 取消整个 $_SESSION,因为这将禁用通过 $_SESSION 超全局变量注册会话变量。 - yitwail

1

session_destroy()在页面加载完成后生效。因此,在第二次上传时,会终止会话。但是使用unset()也可以在页面内注销。


1

嗯,对我来说似乎是一个新问题,使用一个新的php服务器。过去从未遇到会话不结束的问题。

在测试会话时,我设置了一个会话,运行了一个会话计数++并关闭了会话。重新加载页面,令人惊讶的是变量仍然存在。

我尝试了mc10发布的以下建议。

session_destroy();
$_SESSION = array(); // Clears the $_SESSION variable

然而,那并没有起作用。我认为它不可能有效,因为会话在销毁后不再活动,所以我反转了它。
$_SESSION = array();
session_destroy();

这样做有效,重新加载页面、启动会话并审查设置的变量都显示为空/未设置。

真的不确定为什么session_destroy()在这个PHP版本5.3.14服务器上不起作用。

只要知道如何清除会话,就不太在意了。


0
如果你在127.0.0.1上销毁会话,它不会影响到localhost,反之亦然。

-1

它能够工作,但有时候会出现问题(请查看下面的示例)

<?php
session_start();
$_SESSION['name']="shankar";
if(isset($_SESSION['name']))
{
    echo $_SESSION['name']; // Outputs shankar
}
session_destroy();
echo $_SESSION['name']; // Still outputs shankar

奇怪!!对吧?


如何克服这个问题?

在上述情况下,如果您将session_destroy();替换为unset($_SESSION['name']);,它将按预期工作。

但我想销毁所有变量而不仅仅是一个!

是的,这也有解决方法。只需取消设置$_SESSION数组即可。[由Ivo Pereira提供]

unset($_SESSION);

不必使用foreach循环来销毁$_SESSION中的每个键,您可以使用unset($_SESSION)将它们全部删除。 - Ivo Pereira
@shankar,当您的页面加载后,“$ _SESSION ['name']”已被定义为您所定义的“shankar”。接下来您尝试销毁您的会话。 因此,“session_destroy();”函数已从服务器中删除所有会话。 但问题是“$ _SESSION ['name']”已经由“shankar”定义。 当然,您的会话已被销毁。 它将仅影响下一页加载..明白了吗? - Elavarasan
是的,我知道[请参见此问题的第一个答案]。我指的是当前页面。 - Shankar Narayana Damodaran
Shankar,请看一下我在你上面回答中的最后一条评论。PHP手册说你不应该取消设置$_SESSION。相反,你可以设置$_SESSION = array(),这将取消设置你示例中的$_SESSION['name']。这是手册页面:http://php.net/manual/en/function.session-unset.php。 - yitwail

-3
在 !Doctype 声明之前添加 session_start();。
    <?php session_start(); ?>
    <!doctype html>
    <html>
    <body>
<?php 
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) 
{   
    session_destroy();   
    session_unset();     
} 
?>
</body>
</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接