Find out how many users are online in PHP?
Each visit to my website updates the individual user counter and updates the column for time()
based on their IP address and ID stored in the cookie. So when you post the output, what's a more efficient way of my following code with fewer database queries, as it is essentially a copy itself:
<?
$last1Min = time()-60;
$last5Mins = time()-300;
$last1Hr = time()-6000;
$last1Dy = time()-144000;
$last1Wk = time()-1008000;
$last1Mnth = time()-30240000;
//last1Min
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Min";
while($rows = mysql_fetch_array(mysql_query($sql))) {
echo "Users online in the last minute: " . $rows['COUNT(*)'] . "<br />\n";
}
//last5Mins
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last5Mins";
while($rows = mysql_fetch_array(mysql_query($sql))) {
echo "Users online in the last 5 minutes: " . $rows['COUNT(*)'] . "<br />\n";
}
//last1Hr
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Hr";
while($rows = mysql_fetch_array(mysql_query($sql))) {
echo "Users online in the last hour: " . $rows['COUNT(*)'] . "<br />\n";
}
//last1Dy
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Dy";
while($rows = mysql_fetch_array(mysql_query($sql))) {
echo "Users online in the last day: " . $rows['COUNT(*)'] . "<br />\n";
}
//last1Wk
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Wk";
while($rows = mysql_fetch_array(mysql_query($sql))) {
echo "Users online in the last week: " . $rows['COUNT(*)'] . "<br />\n";
}
//last1Mnth
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Mnth";
while($rows = mysql_fetch_array(mysql_query($sql))) {
echo "Users online in the last month: " . $rows['COUNT(*)'] . "<br /><br />\n";
}
If there is a more efficient way of presenting this data, I want to expand it to show not only the number of users for each of these metrics that are online across my site, but also the recording and output of data for every page on my site.
a source to share
SELECT
SUM(lastOnline <= 60) AS one_minute,
SUM(lastOnline <= 300) AS five_minutes,
...
SUM(lastOnline <= 30240000) AS one_month
FROM usersonline
Using this method, you can get everything you need in one query with a single table scan; it doesn't get much more efficient than that. As others have pointed out, you should cache the result as it is relatively expensive (even in this optimized form). There is no point in calculating this on every page load, especially if you see several hits per second (which is very likely if, say, you land on the first page of digg)
lastOnline <= 60 evaluates to 1 for rows where the condition is true and 0 for rows where the condition is false; SUM () sums these 1s and zeros, giving you the number of rows for which the condition is true.
Learned this technique from user comment in mysql docs a few years ago; there are similar examples elsewhere
a source to share