在页面离开时销毁 PHP 会话
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3177364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Destroy PHP session on page leaving
提问by riad
I need to destroy a session when user leave from a particular page. I use session_destroy()on the end of the page but its not feasible for me because my page has pagination. My page is: abc.php?page=1or abc.php?page=2or abc.php?page=3.
当用户离开特定页面时,我需要销毁会话。我session_destroy()在页面末尾使用,但对我来说不可行,因为我的页面有分页。我的页面是:abc.php?page=1orabc.php?page=2或abc.php?page=3。
So, I need to destroy a session when a user leaves from abc.phppage. How can I do it without using a cookie?
因此,当用户离开abc.php页面时,我需要销毁会话。如何在不使用 cookie 的情况下做到这一点?
回答by Valentin Flachsel
Doing something when the user navigates away from a page is the wrong approach because you don't know if the user will navigate to a whole different page (say contact.php for the sake of the argument) or he/she will just go to the next page of abc.php and, as Borealid pointed out, you can't do it without JS. Instead, you could simply add a check and see if the user comesfrom abc.php:
当用户离开页面时做某事是错误的方法,因为你不知道用户是否会导航到一个完全不同的页面(为了争论而说contact.php),或者他/她只会去abc.php 的下一页,正如 Borealid 指出的那样,没有 JS 就做不到。相反,您可以简单地添加一个检查并查看用户是否来自abc.php:
First, in your abc.php file set a unique variable in the $_SESSION array which will act as a mark that the user has been on this page:
首先,在您的 abc.php 文件中,在 $_SESSION 数组中设置一个唯一变量,该变量将作为用户已在此页面上的标记:
$_SESSION['previous'] = basename($_SERVER['PHP_SELF']);
Then, add this on all pages, before any output to check if the user is coming from abc.php:
然后,在所有页面上添加这个,在任何输出之前检查用户是否来自 abc.php:
if (isset($_SESSION['previous'])) {
if (basename($_SERVER['PHP_SELF']) != $_SESSION['previous']) {
session_destroy();
### or alternatively, you can use this for specific variables:
### unset($_SESSION['varname']);
}
}
This way you will destroy the session (or specific variables) only if the user is coming from abc.php andthe current page is a different one.
这样,只有当用户来自 abc.php并且当前页面是不同的时,您才会销毁会话(或特定变量)。
I hope I was able to clearly explain this.
我希望我能够清楚地解释这一点。
回答by Borealid
To trigger when the user actually leavesthe page, you must use Javascript to send an asynchronous request back to the server. There's no way for the server to magically know the user has "left" a page.
要在用户实际离开页面时触发,您必须使用 Javascript 将异步请求发送回服务器。服务器无法神奇地知道用户已经“离开”了一个页面。
See http://hideit.siteexperts.com/forums/viewConverse.asp?d_id=20684&Sort=0.
请参阅http://hideit.siteexperts.com/forums/viewConverse.asp?d_id=20684&Sort=0。
回答by Bakerj417
I had a similar issue but mine was on a page reload I wanted variables that I had printed to be destroyed. It was for my login for my web design class I was making error feed back for if user put in a bad username or password. I could get the error to display but if I hit refresh page they errors would just stay there. I found that by just setting the variable to nothing after it printed would kill it. Take a look at what i did:
我有一个类似的问题,但我的问题是在重新加载页面上,我希望我打印的变量被销毁。这是为了我登录我的网页设计课程,如果用户输入错误的用户名或密码,我正在制作错误反馈。我可以显示错误,但如果我点击刷新页面,他们的错误就会留在那里。我发现在打印后仅将变量设置为空就会杀死它。看看我做了什么:
<p>To access my website please Login:</p>
<form name='login' action="./PHP_html/PHP/login.php" method='post'>
Username: <input type='text' name='username' /><div><?php print $_SESSION['baduser']; $_SESSION['baduser'] = "";?></div><br />
<div style="padding-left: 4px">Password: <input type='password' name='password' /><div><?php print $_SESSION['badpass']; $_SESSION['badpass'] = "";?></div></div>
<input type='submit' value='Login' /> or you can <a href="./Terms.php">Register</a>
I don't know if this helps at all but it worked for me.
我不知道这是否有帮助,但它对我有用。
Also, thanks to all you that post on sites like this to help those of us who are still learning.
另外,感谢您在此类网站上发帖以帮助我们这些仍在学习的人。
回答by Karthik
For a particular page you need to destroy the session, then unset the all session variable using
对于特定页面,您需要销毁会话,然后使用取消设置所有会话变量
unset($_SESSION['varname']);
unset($_SESSION['varname']);
For the whole site you can use session_destroy();
对于整个站点,您可以使用 session_destroy();
回答by riad
I solve the problem.First take the current url then chk the page stay on current url.if page is not in the current url then destroy the session.
我解决了这个问题。首先获取当前 url,然后 chk 页面停留在当前 url 上。如果页面不在当前 url 中,则销毁会话。
$url = "http" . ((!empty($_SERVER['HTTPS'])) ? "s" : "") . "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$page_name="abc.php";
if (!preg_match("/$page_name/",$url))
{
session_destroy();
}
But this code should be used on another pages.Because http is a stateless processes so no way to find when a user leave the page.
但是这段代码应该用在其他页面上。因为http是一个无状态进程,所以没有办法找到用户何时离开页面。
回答by deceze
You can't tell when a user navigates awayfrom the page, it's simply not possible in any reliable manner.
您无法判断用户何时离开页面,这根本不可能以任何可靠的方式进行。
The best you can do is exploit how cookies work. When starting a session, you're sending a cookie to the client which identifies the client on each subsequent visit, and hence activates the associated session. It is up to the client to send this identification on subsequent visits, and it's up to the client to "forget" his identification.
您能做的最好的事情就是利用 cookie 的工作原理。启动会话时,您将向客户端发送一个 cookie,该 cookie 在每次后续访问时标识客户端,从而激活关联的会话。由客户在随后的访问中发送此标识,由客户“忘记”他的标识。
You can instruct the client to only send the cookie for certain pages, and you can instruct him to forget the cookie when closing the browser (with a lifetime of 0). This can be set using session_set_cookie_params.
您可以指示客户端只发送某些页面的cookie,也可以指示他在关闭浏览器时忘记cookie(生命周期为0)。这可以使用session_set_cookie_params.
Other than that, you can simply ignore the session parameters on pages where they don't matter. You can delete the session (or certain values of it) after some time of inactivity when you assumethe client has left.
除此之外,您可以简单地忽略不重要的页面上的会话参数。当您假设客户端已离开时,您可以在一段时间不活动后删除会话(或其某些值)。
回答by Lèse majesté
Borealid deserves credit for pointing to the most elegant solution.
Borealid 指出了最优雅的解决方案,值得称赞。
A more kludgey solution is to keep an iframe on the page that is pointed to another "monitor" page which is set to refresh every few seconds. This can be done without JavaScript using:
更麻烦的解决方案是在页面上保留一个 iframe,该 iframe 指向另一个“监视器”页面,该页面设置为每隔几秒刷新一次。这可以在没有 JavaScript 的情况下使用:
<meta http-equiv="refresh" content="10">
This refreshes the monitor page every 10 seconds. When this happens, the monitor page can record the time (overwriting the previously recorded time) and session ID on the server somewhere (DB or file).
这会每 10 秒刷新一次监视器页面。发生这种情况时,监控页面可以在服务器某处(DB 或文件)上记录时间(覆盖之前记录的时间)和会话 ID。
Then you would have to create a cronjobthat checks the file/DB for any sessions that are more than 10~12 seconds old and delete them manually. The session data is usually stored in a directory (specified by your PHP config) in a file named sess_the-session-ID. You could use a PHP function like this:
然后,您必须创建一个cronjob来检查文件/数据库中是否存在超过 10 到 12 秒的任何会话并手动删除它们。会话数据通常存储在名为sess_the-session-ID. 您可以使用这样的 PHP 函数:
function delete_session($sessId) {
$sessionPath = session_save_path();
// you'll want to change the directory separator if it's a windows server
$sessFile = "$sessionPath/sess_$sessId";
if (file_exists($sessFile) && unlink($sessFile)) return true;
return false;
}

