9

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=1 or abc.php?page=2 or abc.php?page=3.

So, I need to destroy a session when a user leaves from abc.php page. How can I do it without using a cookie?

Kamran Ahmed
  • 11,809
  • 23
  • 69
  • 101
riad
  • 7,144
  • 22
  • 59
  • 70
  • 4
    possible duplicate of [Close/kill the session when the browser or tab is closed](http://stackoverflow.com/questions/1921941/close-kill-the-session-when-the-browser-or-tab-is-closed) – Quentin Jul 05 '10 at 05:35
  • thx bro.but its an asp solution.i don't get anything from it....How can i keep alive my session until a user visit my page abc.php.when user leave abc.php then just destroy the session. – riad Jul 05 '10 at 05:45
  • Actually, the first answer in the linked thread is the correct one, and not at all ASP specific. – deceze Jul 05 '10 at 06:34
  • @deceze - Correct, yes. Actual solution, far from it. – Valentin Flachsel Jul 05 '10 at 06:39

7 Answers7

23

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 comes from 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:

$_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:

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 and the current page is a different one.

I hope I was able to clearly explain this.

Valentin Flachsel
  • 10,795
  • 10
  • 44
  • 67
  • Thx bro its works...but their have a problem. if i don't come from the abc.php page the session store different data..anyway many thanks for your solution... – riad Jul 05 '10 at 06:23
  • If there is data that you would like to keep in the session array, then instead of destroying it completely, you can simply unset only the variables that were set on abc.php by using `unset($_SESSION['varname']);` instead of `session_destroy()`, like Karthik pointed out. – Valentin Flachsel Jul 05 '10 at 06:28
  • Not very user friendly. What if I'm opening another page in a different tab, but still want to continue using `abc.php` at the same time? – deceze Jul 05 '10 at 06:47
  • + 1 to be honest, but the idea of destroying/unsetting session variables on page *leave, without* using JS is what is generating this flaw to begin with. – Valentin Flachsel Jul 05 '10 at 07:19
4

To trigger when the user actually leaves the 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.

See http://hideit.siteexperts.com/forums/viewConverse.asp?d_id=20684&Sort=0 .

Borealid
  • 95,191
  • 9
  • 106
  • 122
  • Thanks bro for ur ans..but my page is for mobile users so i cannot use the javascript..is it can be solved only using php?? – riad Jul 05 '10 at 05:48
1

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.

Bakerj417
  • 11
  • 2
0

For a particular page you need to destroy the session, then unset the all session variable using

unset($_SESSION['varname']);

For the whole site you can use session_destroy();

Karthik
  • 3,221
  • 5
  • 28
  • 38
  • no bro. if i unset or destroy the variable on the end of the page then i cannot get the value on my second or third page abc.php?page=2 or 3.So i have to use the session until a user leave my abc.php page. How can i do it?? – riad Jul 05 '10 at 05:41
0

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 = "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.

riad
  • 7,144
  • 22
  • 59
  • 70
  • You could actually only use `$_SERVER['REQUEST_URI']` because that's where the file name would be. If you have a single header.php file for all pages (as it is common practice), you can simply use my solution, rather than adding your code in all the pages *EXCEPT* abc.php. – Valentin Flachsel Jul 05 '10 at 06:23
  • 1
    There's no point in using that code if you're not also going to put it on `abc.php`. I don't know what that has to do with http being stateless. And you've still got the same problem as FreekOne's answer with session data being destroyed even when you're not leaving `abc.php`. – Lèse majesté Jul 05 '10 at 06:47
0

You can't tell when a user navigates away from 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.

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.

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 assume the client has left.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • This is getting where I'd like to go. Question: how would I delete the session after some time of inactivity? Similarly to the above approach with where a user navigates _from_, but now using a timestamp? Like: the timestamp in the $_SESSION[] is 10min old, so it's expired? – Jens Nov 05 '12 at 01:35
0

Borealid deserves credit for pointing to the most elegant solution.

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:

<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).

Then you would have to create a cronjob that 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:

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;
}
Lèse majesté
  • 7,923
  • 2
  • 33
  • 44