5

I am trying to find a method to execute some PHP code once a user closes the page. In my application, once the user closes or navigates away from the page the server will state the user as 'Offline' in the database. This requires the code to know when the user has navigated away from the page. My application also has an endless load (i.e. it will sleep until the user closes the page).

Dharman
  • 30,962
  • 25
  • 85
  • 135
Joel Kennedy
  • 1,581
  • 5
  • 19
  • 41
  • 3
    Register every user action in the database as `timestamp` and then check whatever a user has been active in the last (n) minutes. That's what everyone do and is the only way that 100% works. – Shoe Feb 01 '11 at 15:46

6 Answers6

13

Reliably sending an event when the user closes the page is close to impossible. There is the onbeforeunload event that could do an Ajax call, but that could fail, not be executed for security reasons, or not be executed at all because the user has JavaScript turned off.

This is usually done through session timeouts: It is checked when a request for a certain session was last made. If it was longer than x minutes ago, the session is treated as expired. Is that not an option?

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • Yes this does seem the best practice. Your answer made me think more about how it would be possible, and it does seem the most logical than other methods mentioned. Thanks! – Joel Kennedy Feb 01 '11 at 16:11
4

Page requests are stateless, meaning you'll never have a 100% working detection method to determine if someone has left the page. You can try to catch the page unloading, but this isn't 100% accurate. You could also try as @Nayena mentioned with AJAX, but this is less than ideal.

Your best bet is to do like most common sites do, use "last activity within N minutes" as an indicator and not try to catch when they navigate away or close the page.

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • you CAN check if the user has LEFT the page (not the website) from within PHP , but this means that the connection will remain open (the loading progress in the browser will be working to infinity) .. check my answer – Rami Dabain Feb 01 '11 at 15:46
  • @Ronan: I could also use an AJAX push service, or a hidden flash plugin that maintains an active connection, or .... (doesn't mean any of them are ideal or good for the server). I'll chose the "timeout" method and keep my server threads open any day of the week over any of the aforementioned. [unless the business model calls for that kind of overhead. but as far as "did the user leave yet?"--not worth the resources] – Brad Christie Feb 01 '11 at 15:50
  • ) i know , but he said 'execute some PHP code' and ' My application also has an endless load (i.e. it will sleep until the user closes the page).' , so why not to use this method ?? – Rami Dabain Feb 01 '11 at 15:54
3

If you put in a ajax script that refreshes after 5-10 seconds, you can update the last updated stamp via the php file that the ajax request calls, and if its older than 10 seconds it went offline. That could certainly be a cleaner solution :-)

Jan Dragsbaek
  • 8,078
  • 2
  • 26
  • 46
0

If you can use Javascript and JQuery, use 'window.onclose' and then an Ajax call to do whatever you want using PHP:

Capture event onclose browser

// Javascript code
window.onclose = closing;

function closing(){
  $.ajax({
     url: 'yoururl.php',
     data: yourdata,
     success: function(content){
          // empty
     }
  })
}
Community
  • 1
  • 1
Fran Verona
  • 5,438
  • 6
  • 46
  • 85
0

Use the Body attribute onunload

http://www.htmlcodetutorial.com/document/_BODY_onUnload.html

Bas
  • 5,904
  • 1
  • 15
  • 8
-1

Simply set ignore_user_abort(true) then enter an infinite while loop of

    while (!connection_aborted()){
      // do nothing ...
    }

//after the while loop :
some_function_to_say_that_the_user_is_offline();

but be carefull , whenever the user navigates out of the page , the function WILL be executed .

EDIT : and the progress bar of the browser will be like "downloading ..." forever ...

Edit 2 : check also http://www.php.net/manual/en/function.register-shutdown-function.php

Rami Dabain
  • 4,709
  • 12
  • 62
  • 106
  • Thanks for the answer, no one else picked up on the PHP method you mentioned. Does this mean that even when the user leaves the page, the code will in effect still be going, and will never stop looping until either the PHP hits its execution time or I restart the PHP server and clear the processes? – Joel Kennedy Feb 01 '11 at 15:50
  • No , once the user closes the browser , or navigates to another page `connection_aborted()` will become true , and the while loop will end , allowing you to proceed with the code that tells that the user is offline and then the script ends normally , in addition , add `set_time_limit(0);` to disable php execution time limit . – Rami Dabain Feb 01 '11 at 15:52
  • Note that if you have thousands of concurrent users then the server will have to maintain thousands of incoming connections. Since there are only 65,000 ish ports, and they can't be reused immediately, you will run into severe loading limitations with any reasonably busy web site. – bikeman868 Nov 29 '16 at 06:05