Users Online

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 1016 Views - Last Post: 05 April 2010 - 06:26 PM Rate Topic: -----

#1 Jye  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Users Online

Posted 05 April 2010 - 06:36 AM

Just hoping to get a little help in fixing my little problem here.

I am working on an online system at the moment that currently included a registration and log in system. Now i also want to include a Users online section which is giving me trouble.

Currently when a user logs in, once the script has authenticated them it will get their user name then log the details into an "online" database table like so:

if($row['Activated'] > 0)
{

$_SESSION['s_logged_n'] = 'true';
$_SESSION['s_username'] = $username;
$_SESSION['s_name'] = $row['Name'];   

$insertuser="INSERT INTO online(Username) values('$username')";
mysql_query($insertuser) or die("Could not login insert user");
header("Location: index.php");
} 
else 
{


Then in my information center i just pull all results from the "online" table to display the users online.

Now off course by using this method the only possible way a name can be removed from the database is if the user manually hits the logout button where i then run:

$username = $_SESSION['s_username'];
$query = "DELETE FROM online WHERE username = '".mysql_real_escape_string($_SESSION['s_username'])."';";
$result = mysql_query($query); 
$_SESSION['s_logged_n'] = '';
$_SESSION['s_name'] = '';
$_SESSION['s_username'] = '';

session_destroy();


If a user just closes the browser without logging out they will stay logged in for the default php session length before the session is destroyed. The problem here is that it won't remove them from the online table meaning they will always be displayed in users online. When they log in next their name will then appear 2 times in users online and only get taken off if they actually click log out.

And to display them in the users online section i use:

$online = mysql_query("SELECT username FROM online") or die(mysql_error());

if(mysql_num_rows($online) > 0)
{
    echo '<tr class="mainrow"><td>Currently active: ';
    while($row = mysql_fetch_assoc($online))
    {
        $onlineusers[] = '<A href="member_profile.php?username='.$row['username'].'">'.$row['username'].'</a>';
    }

    echo implode(', ' , $onlineusers) . ' </td></tr>';
}
else
{
    echo '<tr class="mainrow"><td>There are currently no users logged in</td></tr>';
}



I am quite bad at sessions but i need to change this and cause the user to get logged out via the session if they have been inactive for 15 minutes which will destroy their session and also remove them from the online list.
I am struggling to get my desired result after a lot of testing so some help would be greatly appreciated.

Currently i have this which is run on each page to check if a user has been active within 15 minutes. Only problem is it doesn't seem to work. As soon as a user logs in, it automatically removes them on the page load after hitting log in.
   session_start();
   if ($_SESSION['last_active'] <= (time() - 900)) // 900 = 15 minutes (60x15)
   {


   $username = $_SESSION['s_username'];
   $query = "DELETE FROM online WHERE username = '".mysql_real_escape_string($_SESSION['s_username'])."';";
   $result = mysql_query($query); 
   $_SESSION['s_logged_n'] = '';
   $_SESSION['s_name'] = '';
   $_SESSION['s_username'] = '';

   session_destroy();

   header("Location: index.php");

   }
   else
   {
      $_SESSION['last_active'] = time();
   }


So my current dilemma, how can i get the above code to work and how i would i properly register the session upon logging in to add them into a database with the current time?
Also how would i show them in the online list once i get it working?

This post has been edited by Jye: 05 April 2010 - 06:37 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Users Online

#2 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2486
  • View blog
  • Posts: 8,527
  • Joined: 08-August 08

Re: Users Online

Posted 05 April 2010 - 06:51 AM

I would add a datetime field to your online table and updated it with the current date and time when a user does anything. Just before updating, I'd check for users whose last activity is more than 15 minutes ago and remove them from the table. Then if I didn't find the user I want to update in the table I'd send them to a login screen.

This post has been edited by CTphpnwb: 05 April 2010 - 06:52 AM

Was This Post Helpful? 0
  • +
  • -

#3 Jye  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Re: Users Online

Posted 05 April 2010 - 06:54 AM

That;s the general idea i have, but the trouble i have is actually implementing it. :)
Was This Post Helpful? 0
  • +
  • -

#4 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 5669
  • View blog
  • Posts: 22,517
  • Joined: 23-August 08

Re: Users Online

Posted 05 April 2010 - 06:58 AM

You need a separate process (a cron job perhaps) that runs every x minutes and marks as logged out any user that has a timestamp older than whatever is your threshold.

Saying

Quote

I am quite bad at sessions
is not a good sign for a PHP developer.
Was This Post Helpful? 0
  • +
  • -

#5 Jye  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Re: Users Online

Posted 05 April 2010 - 07:01 AM

View PostJackOfAllTrades, on 05 April 2010 - 05:58 AM, said:

You need a separate process (a cron job perhaps) that runs every x minutes and marks as logged out any user that has a timestamp older than whatever is your threshold.

Saying

Quote

I am quite bad at sessions
is not a good sign for a PHP developer.


I was wanting to complete the task without cronjobs and have it done via the php only.
And i am still learning.
Was This Post Helpful? 0
  • +
  • -

#6 ghqwerty  Icon User is offline

  • if($spareTime > 0){ $this->writeCode(); }
  • member icon

Reputation: 40
  • View blog
  • Posts: 876
  • Joined: 08-August 08

Re: Users Online

Posted 05 April 2010 - 10:45 AM

you dont have to use a cron job for this. ill expand on what CTphpnwb said. it would also help if your code was in OOP but it can be done without

in your database have a field called 'lastAction' in the form of a timestamp, and then evry time a user loads a page have a couple of lines of code that will update this timestamp to the current timestamp.
now, when a user wishes to access the users online page run a simple script that loops through every 'online' user and check the lastAction was no more than x minutes ago, id say 10. if the last action a user did was 10 minutes ago then theyve probably clicked the exit button on the browser or gone somewhere else, if they havent they'll have to re-login. back to the code, if the user was inactive for more than x minutes change there status to offline. and then run the rest of your page and then your online list will be accurate to within x mins.

hope this helps
Was This Post Helpful? 2
  • +
  • -

#7 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2486
  • View blog
  • Posts: 8,527
  • Joined: 08-August 08

Re: Users Online

Posted 05 April 2010 - 11:59 AM

View Postghqwerty, on 05 April 2010 - 12:45 PM, said:

you dont have to use a cron job for this. ill expand on what CTphpnwb said. it would also help if your code was in OOP but it can be done without

in your database have a field called 'lastAction' in the form of a timestamp, and then evry time a user loads a page have a couple of lines of code that will update this timestamp to the current timestamp.
now, when a user wishes to access the users online page run a simple script that loops through every 'online' user and check the lastAction was no more than x minutes ago, id say 10.

Nice summary. One thing though; it doesn't need to loop through all users. You can just do a query that removes all items from the table whose timestamp is over xx minutes old.
;)
Was This Post Helpful? 0
  • +
  • -

#8 Jye  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Re: Users Online

Posted 05 April 2010 - 04:13 PM

That is what i am currently doing.
This script is included on each page to check for activity:

session_start();

   $lastonline = time();
   if ($_SESSION['lastonline'] <= (time() - 900)) // 900 = 15 minutes (60x15)
   {
   $username = $_SESSION['s_username'];
   $query = "DELETE FROM online WHERE username = '".mysql_real_escape_string($_SESSION['s_username'])."';";
   $result = mysql_query($query); 
   $_SESSION['s_logged_n'] = '';
   $_SESSION['s_name'] = '';
   $_SESSION['s_username'] = '';

   session_destroy();

   }
   else
   {  
      $username = $_SESSION['s_username'];
      $_SESSION['lastonline'] = time();
      $query = "INSERT INTO online(Username, lastonline) VALUES('${lastonline}')";
      $updateonline="Update online set username='$username',lastonline='$lastonline'";

      mysql_query($updateonline) or die("Could not update online");
   }



Except it does not work, it will log the user out as soon as they login.
Was This Post Helpful? 0
  • +
  • -

#9 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2486
  • View blog
  • Posts: 8,527
  • Joined: 08-August 08

Re: Users Online

Posted 05 April 2010 - 04:31 PM

That's because this:
   $query = "DELETE FROM online WHERE username = '".mysql_real_escape_string($_SESSION['s_username'])."';";


deletes based on the name instead of the date and time of their last activity. You don't have a field for that!
Was This Post Helpful? 0
  • +
  • -

#10 Jye  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Re: Users Online

Posted 05 April 2010 - 05:09 PM

Ah i see, ill add a WHERE into the database query and include the last online details.
I'll see how it works and update after i test is, thanks CTphpnwb.
Was This Post Helpful? 0
  • +
  • -

#11 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2486
  • View blog
  • Posts: 8,527
  • Joined: 08-August 08

Re: Users Online

Posted 05 April 2010 - 05:19 PM

This worked for me in my test table:

$timestamp = mktime(date("H"),date("i")-15,date("s"),date("m"),date("d"), date("Y"));
$dt = date("Y-m-d H:i:s", $timestamp);
$qry = "DELETE FROM online WHERE lastactive < '".$dt."'";


lastactive is a mysql datetime field in the table. It's a good idea to set it as your primary key for this table.
Was This Post Helpful? 0
  • +
  • -

#12 Jye  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Re: Users Online

Posted 05 April 2010 - 05:25 PM

I'll give something like that a try.
I included a WHERE into the query which worked to the point where the user could log in and it would leave the logged in however it didn't remove them after 15 minutes of inactivity.

EDIT:

Ok i almost have it working.
Currently i have:

session_start();

   $lastonline = time();
   if ($_SESSION['lastonline'] <= (time() - 900)) // 900 = 15 minutes (60x15)
   {
   $username = $_SESSION['s_username'];
   $query = "DELETE FROM online WHERE username = '".mysql_real_escape_string($_SESSION['s_username'])."';";
   $result = mysql_query($query); 
   $_SESSION['s_logged_n'] = '';
   $_SESSION['s_name'] = '';
   $_SESSION['s_username'] = '';

   session_destroy();

   }
else
   {  
      $username = $_SESSION['s_username'];

	

  $time = time();

	

  $updateonline = (isset($_SESSION['lastonline'])) ? "Update online set lastonline='$lastonline' WHERE username='$username'" : "INSERT INTO online(Username, lastonline) VALUES('$username','$time')";
      $_SESSION['lastonline'] = $time;
      mysql_query($updateonline) or die("Could not update online");
   }


It works and logs the user in correctly without removing them right away, the only problem is that it won't remove them after 15 minutes unless they try and request a page. So the user can sit on a single page for 15 minutes but it won't remove them from the online table until they request a new page after 15 minutes.

This post has been edited by Jye: 05 April 2010 - 05:28 PM

Was This Post Helpful? 0
  • +
  • -

#13 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2486
  • View blog
  • Posts: 8,527
  • Joined: 08-August 08

Re: Users Online

Posted 05 April 2010 - 05:34 PM

Look at this line:
$timestamp = mktime(date("H"),date("i")-15,date("s"),date("m"),date("d"), date("Y"));

The date("i")-15 portion tells mktime to subtract 15 minutes from the timestamp it generates. Then the next line formats the results to agree with mysql's version of datetime.

View PostJye, on 05 April 2010 - 07:25 PM, said:

It works and logs the user in correctly without removing them right away, the only problem is that it won't remove them after 15 minutes unless they try and request a page. So the user can sit on a single page for 15 minutes but it won't remove them from the online table until they request a new page after 15 minutes.

Even if you get it to work in the sense that it functions, your method won't be very efficient. Over time, you could have thousands of users that leave without logging out, so they'll never get removed. The table will grow to the point where it slows your site down. The way I posted will remove all inactive users when anyone does anything, so the table will only have active users in it. It will not grow.
Was This Post Helpful? 0
  • +
  • -

#14 Jye  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 29-March 09

Re: Users Online

Posted 05 April 2010 - 05:48 PM

So if i replace what i had with that it does the same thing, changing the trow name to mine off course:

session_start();



   $lastonline = time();
   if ($_SESSION['lastonline'] <= (time() - 180)) // 900 = 15 minutes (60x15)
   {
   $timestamp = mktime(date("H"),date("i")-15,date("s"),date("m"),date("d"), date("Y"));
   $dt = date("Y-m-d H:i:s", $timestamp);
   $qry = "DELETE FROM online WHERE lastonline < '".$dt."'";
   $result = mysql_query($query); 
   $_SESSION['s_logged_n'] = '';
   $_SESSION['s_name'] = '';
   $_SESSION['s_username'] = '';

   session_destroy();

   }
else
   {  
      $username = $_SESSION['s_username'];

	

  $time = time();

	

  $updateonline = (isset($_SESSION['lastonline'])) ? "Update online set lastonline='$lastonline' WHERE username='$username'" : "INSERT INTO online(Username, lastonline) VALUES('$username','$time')";
      $_SESSION['lastonline'] = $time;
      mysql_query($updateonline) or die("Could not update online");
   }

Was This Post Helpful? 0
  • +
  • -

#15 CTphpnwb  Icon User is online

  • D.I.C Lover
  • member icon

Reputation: 2486
  • View blog
  • Posts: 8,527
  • Joined: 08-August 08

Re: Users Online

Posted 05 April 2010 - 06:02 PM

Delete this if statement:
   if ($_SESSION['lastonline'] <= (time() - 180)) // 900 = 15 minutes (60x15)


The query should be run every time the page is accessed.

Then, after the delete query is run, you should check that table to see if the user is still active.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2