Сессию можно открывать в любой момент. По сути, нам нужен только идентификатор сессии. Если очень утрировать, идентификатор сессии – это нечто вроде фразы от клиента - серверу: "Сервер, я - вот такой вот клиент. Можешь в будущем узнавать меня по этой строке".
Вариант примерно такой:
Создать таблицу MySQL "online":
session (text, primary) | time (int)
SQL-запрос (dbname поменяйте на имя БД):
CREATE TABLE `dbname`.`online` (`session` TEXT NOT NULL , `time` INT NOT NULL , PRIMARY KEY (`session`(64))) ENGINE = InnoDB;
online.php:
// где-то тут должно быть соединение с БД, $db = объект mysqli
if (isset($_COOKIE['PHPSESSID'])) {
$db->query("insert into `online` (`session`,`time`) values ('".$_COOKIE['PHPSESSID']."', '".time()."') on duplicate key update `time`='".time()."'");
}
$db->query("delete from `online` where `time`<'".(time()-60)."'");
$online = $db->query("select count(*) as `online` from `online`")->fetch_assoc()['online'];
echo $online;
Что делаем тут?
1. Проверяем, существует ли в куках идентификатор сессии пользователя (на тот случай, если PHPSESSID по какой то причине не записан, например если сессия начинается позже этого куска скрипта или если у пользователя отключены куки)
2. Если сессия указана – вносим информацию о сессии и времени посещения в базу данных. Если строка с таким же именем сессии уже существует – просто обновляем ей время, вписывая актуальное время (за обновление отвечает кусок "on duplicate key update")
3. Удаляем из таблицы все записи, где время входа – меньше текущего времени на 1 минуту (т.е. как бы "убираем" из списка онлайна тех, кто вышел с сайта минуту назад и более) (меняется в куске "(time()-60)", где 60 – количество секунд)
4. Получаем количество "оставшихся" на сайте людей, то есть которые не были удалены в п.3
Далее простой запрос через AJAX: получаем данные из PHP-скрипта (количество людей онлайн), засовываем в блок id="online" строку "Онлайн: Х чел." и зацикливаем это действие с повторением каждые 5 секунд.
function getOnline() {
$.ajax({
url: 'online.php',
success: function(result) {
$("#online").html("Онлайн: "+result+" чел.");
}
});
}
getOnline();
setInterval(function(){getOnline()},5000);
JS-код вставляем в любое место на сайте.
Там, где есть этот код – оттуда будут обновляться пользователи. То есть если пользователь зайдёт на страницу, где этого кода нет – этот пользователь в онлайне учитываться не будет.
Если нужно просто уведомить сервер, что человек зашел на сайт, но при этом не выводить количество людей онлайн, можно просто отсылать запрос, не обрабатывая ответ. Например:
setInterval(()=>{$.ajax("online.php");},5000);
При этом пользователь запишется в БД, но количество пользователей этому пользователю на страницу выведено не будет.
Конечно хранить онлайны посетителей в таком виде – не самая лучшая идея, поскольку будет много обращений к БД при большом трафике, да и время надо подкорректировать в зависимости от возможностей железа. Но на небольших проектах – почему бы и нет?
Хотя, думаю, существуют реализации и получше.
Может вы подскажите хороших вариант решения заголовка к этому вопросу?