Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Count online users
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Pinger test</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<h1>Online user counter</h1>
<p id="counter">Users online: <span id="userCount">loading…</span></p>
<script type="text/javascript" charset="utf-8">
$().ready(function (){
var token = '';
var pinger = setInterval(function (){
$.ajax({
cache: false,
data: {
token: token,
},
timeout: 2500,
type: 'GET',
url: 'pinger.php',
dataType: 'json',
success: function (data, status, jqXHR){
$('#userCount').text(data.userCount);
token = data.token;
}
});
}, 5000);
});
</script>
</body>
</html>
<?php
// Look for token
$token = (isset($_GET['token']) && preg_match('/^[0-9a-f]{8}$/', $_GET['token'])) ? $_GET['token'] : false;
if (!$token) {
$token = sprintf('%08x', crc32(microtime()));
}
// get current minute, build APC key
$quadrant = ceil(date_create()->format('s') / 15); // between 1-4
$previousQuadrant = $quadrant - 1 < 1 ? 4 : $quadrant - 1;
$key = 'pinger_'.$quadrant;
$previousKey = 'pinger_'.$previousQuadrant;
// get tokens for the last 30 seconds
$current = apcu_fetch($key);
$previous = apcu_fetch($previousKey);
if (!is_array($current)) {
$current = array();
}
if (!is_array($previous)) {
$previous = array();
}
// Add current token if not found
if (count($current) < 250 && !in_array($token, $current)) {
$current[] = $token;
apcu_store($key, $current, 31);
}
// Build return object: userCount, token
$output = array(
'userCount' => count($current) > 250 ? '250+' : count(array_unique(array_merge($current, $previous))),
'token' => $token,
);
header('Content-Type: application/json');
print json_encode($output);
exit;
@inanimatt
Copy link
Author

inanimatt commented Jun 29, 2012

Shows how many people are on the site "now". Accurate to about 30 seconds. Not for any page expecting more than about 250 concurrent visitors.

If you have multiple servers, this script (and maybe even this whole method) is not for you. You could switch to memcached, but if you have enough users to need more than one server, you probably don't want the extra traffic that this would create.

@dejurin
Copy link

dejurin commented Nov 11, 2015

Good solution, but I recommend use this with Crawler Detect that remove bots.

@andreadd
Copy link

andreadd commented Apr 15, 2018

Hello, can you help me?
My page doesn't work. It always shows "Users online: loading…"
https://www.andreadd.it/appunti/post-laurea/index.html

Thank you very much.

@ArtsyMedia
Copy link

ArtsyMedia commented Apr 29, 2021

Hello, can you help me?
My page doesn't work. It always shows "Users online: loading…"
https://www.andreadd.it/appunti/post-laurea/index.html

Thank you very much.

Same is happening for me.

@inanimatt
Copy link
Author

inanimatt commented Apr 30, 2021

@ArtsyMedia Sorry, this script is nearly 10 years old and… some things have changed! First, it relies on the APC PHP extension which has been replaced with APCU - you'll need to make sure that extension is installed, and then change the function calls apc_fetch and apc_store to the corresponding APCU equivalents apcu_fetch and apcu_store.
Secondly, the jquery dependency is very old. I haven't tried it, but a quick glance at the docs suggests that you can just replace the <script src="…"> tag with <script src="https://code.jquery.com/jquery-3.6.0.min.js" type="text/javascript"></script>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment