Наверное, путешествуя в Сети, вы не раз натыкались на подобного типа надпись «Сейчас на сайте 99 человек», что означает, что кроме вас в данный момент этот сайт просматривает 98 человек. Скорее всего, вы хотели написать такую вещь, но не знали как. Следующая статья покажет как самому написать скрипт, считающий количество посетителей на сайте в данный момент, то есть онлайн.
В Интернете много готовых скриптов, позволяющих считать пользователей онлайн, но раз вы читаете эту статью, значит, вы как и я не особо любите ковыряться в чужом коде. Ну, в таком, случае, давайте, напишем такой скрипт сами. Но прежде поговорим о его преимуществах и недостатках.
Преимущества
Ему не нужна реляционная база данных, что согласитесь, в нашем Рунете (я имею в виду относительно бесплатную его часть), является несомненным преимуществом.
Опять же несомненным преимуществом является скорость. Я не поленился написать подобный скрипт с использованием БД и при помощи функции microtime() (в самом низу – результат ее работы – «Время генерации: …») измерил время выполнения:
- Используя сессии – 0,7 мс
- Используя БД – 14,2 мс
То есть преимущество в скорости – более чем в 19 раз! Вы можете сказать : «Тоже мне большое дело. Всего 13 мс разница», да они будут правы – а если посещаемость большая? Растет нагрузка на сервер и тогда действительно такое преимущество становится очевидным.
Еще одно преимущество – то, что информация в сессиях хранится пока не закрыт браузер или 1440 секунд (стоит по умолчанию в php.ini), в БД информацию о юзерах вам пришлось бы удалять вручную.
И последнее – простота, чтобы объявить сессию достаточно вызвать функцию session_start(), а чтобы настроить правильных образом БД нужно написать целых 15 строк кода.
Недостатки
Нет детальной статистики – в сможете только узнать количество пользователей в данный момент, для ведения статистики (хиты, хосты…) придется все-таки работать с БД.
Нужен PHP4 – как это ни парадоксально – еще не все хостеры поставили себе PHP4.
ЗАМЕЧАНИЕ: Если у вас нет специальной директории для хранения сессий, просто сразу первой строчкой добавьте:
Теперь пройдемся по отдельным частям кода:
Следующая строка кода — это объявление некоторой константы, в течении которой пользователи будет считаться активными, то есть присутствующими в данный момент на сайте. В нашем примере — 180 секунд, то есть, если пользовательь не перешел на новую страницу или не перезагрузил эту в течении 3 минут, то он считается ушедшим с сайта и мы его уже не учитываем:
Теперь мы объявляем функцию getonlineuser() и сразу открываем "сессионную" директорию:
Далее идет часть кода, которая собственно и отвечает за подсчет пользователей, функция возвращает кол-во пользователей онлайн:
И пожалуй, разумно будет вывод количества юзеров в конце:
Всем доброго времени суток!
Наверняка, гуляя по сети в поисках порн. т.е. в поисках какой-либо информации, вы натыкались на такую фишку, типа:
Т.е., когда примерно в таком контексте выводится количество человек, присутствующих в данное время на сайте. Когда я впервые увидел такую фичу, мне она показалось интересной и симпотной.
Недавно, по личной надобности, мне захотелось сделать такое для своего сайта и я реализовал все это дело с использованием PHP+MySQL. На нашем портале Progers.ru вы можете видеть (вверху) красующуюся надпись о количестве пользователей On-Line.
Итак, в этой статье я хочу вам рассказать, как сделать такую фичу для сайта. Это на самом деле проще жареной капусты ;=) и вскоре вы убедитесь в этом.
Все что нам нужно, это — хостинг с поддержкой PHP и MySQL и пара минут времени. Может быть, некоторые возразят, зачем здесь база данных, когда все можно реализовать на файлах. Скажу вам , что MySQL в данном конкретном случае подходит как нельзя лучше. С использованием файлов же, пришлось бы писать гораздо больше кода и заниматься в большинстве своем рутиной, которая нам ни к чему; в то время как с помощью базы данных все делается парой-другой запросов.
Я надеюсь, что вы умеете хоть как-то обращаться с сервером MySQL и знаете в целом, что такое базы данных и для чего они служат. В противном случае, не могу ничем помочь, кроме как посоветовать обратиться к друзьям, владеющим искусством составлять SQL-запросы. Хотя, в принципе, вы можете просто скопировать мой код и все. Однако, сама база данных все же должна быть настроена.
Итак, постепенно переходим от теории к практической ипостаси. В PHP, к сожалению (да и в других серверных языках веб-программирования), отсутствует такая, на мой взгляд, полезная технология, которая позволяла бы определять момент времени, в который человек покинул сайт. Неважно, каким способом, он это сделал: закрыл окно браузера или перешел по другой ссылке. Раз PHP пасует, сами сделаем кое-какую подобную технологию; естественно, о точности и отсутствии погрешностей здесь не говорю. Однако, все так делают и мы так сделаем. Далее опишу, как мы будем, собственно, определять кол-во юзеров на линии теоретически (не касаясь MySql и PHP конкретно). Если вы уловите мысль, то тотчас же реализуете эту возможность на любом языке веб-программирования и любым доступным для вас методом (файлы, к примеру).
Для начала, нам нужно установить переменную Точность — время, в течении которого посетитель будет считаться на линии, т.е. бродящем по сайту. Значит, при заходе на страницу, мы должны определить сперва-наперво IP-адрес зашедшего и его timestamp. Никакой экзотики, TimeStamp — это представление времени, которое равняется "кол-ву секунд, прошедших с полуночи 1 января 1970 года по Гринвичу до настоящего момента". Это весьма универсальное представление времени и, в частности, именно с этим форматом работает большинство PHP-х ф-й для работы с "датой-временем". Весьма удобная метка, поверьте мне на слово. Т.е., чем больше число TimeStamp, чем дольше "мы живем" и чем больше "сейчас времени", извиняюсь за сумбурность. После, мы открываем какое-либо хранилище (файлы, базы данных, сессионный массив и т.п.) и удаляем из него все записи (каждая запись — информация об одном зашедшем на страничку пользователе), в которых TimeStamp + Точность меньше текущего TimeStamp’а, или где IP-адрес совпадает с текущим Ip’м. Т.е., уничтожаем старые записи. Далее записываем данные о зашедшем пользователе (оставляем запись): IP и timestamp. Все, подсчитываем количество записей — это и есть кол-во человек на сайте в данное время.
Честно говоря, получилось так, что ориентир все равно велся на MySQL, а не на файлы. В самом деле, наше ли это дело, сначала лезть в файл и удалять там-то, потом опять лезть в него, чтобы записать, а потом только считывать. Куда проще сначала считать файл в массив, удалить из массива старые записи и добавить запись о юзере, если это требуется и уж потом записать массив обратно в файл. При выводе данных же руководствоваться кол-м значений в массиве.
Надеюсь, основную мысль вы все же уловили. Мы просто подсчитываем кол-во юзверей, со времени захода которых не прошло время, которое мы установили (Точность).
Итак, переходим наконец-то к практике. Повторюсь, для хранения информации будет юзаться база MySQL. Для всего этого дела мы создадим отдельную таблицу. Назовем её online. В таблице создадим 3 поля:
-
>Замечу, что поле unix будет иметь тип VARCHAR, а не встроенный разработчиками MySQL тип TIMESTAMP. Это связано с тем, что этот тип слишком неудобен для хранения данных датывремени в базе, как это может показаться на первый взгляд.
Далее привожу запрос, выполнив который, вы создадите соответствующую таблицу с нужными полями. Запрос можно выполнить функцией PHP mysql_query(), либо в какой-нибудь удобной оболочке для работы с MySQL. Например в PHPMyAdmin.
Выполнили? Молодцы. Напомню, что команды синтаксиса MySQL лучше всего привыкать писать в верхнем регистре и не для понта, как думают некоторые, а для повышении удобочитаемости кода и просто потому, что так принято.
После выполнения запроса, нам остается только написать код, который будет заниматься, собственно, подсчетом кол-а человек на линии. Этот код я запихнул в отдельную функцию, которая хранится у меня в файле, а сам файл инклюдится ( include(), require() ) на каждой странице моего сайта где-нибудь в самом начале. Я привожу вам пример функции точь-в-точь, какую я написал для своего сайта, разве только немного измененную в целях публичного использования. При наличии необходимых знаний, вы легко сможете отредактировать её под себя.
Вот такая вот функция. Где-нибудь в начале файла вам надо будет вставлять её как-нибудь по типу:
А в том месте, где нужно вывести кол-во пользователей, писать:
Теперь разъясню немного код функции, так как в ней самой я все подробно откомментировал. Сначала идут переменные, нужные для удачного коннекта к базе, а также переменная $wine — наша точность. Также делается доступной из функции глобальная переменная $REMOTE_ADDR, которая возвращает IP-адрес клиентского компьютера. После происходит соединение с сервером MySQL. И уже после начинается самое интересное.
Первым запросом к базе ( запросы выполняются ф-й mysql_query() ) мы удаляем все записи, в которых timestamp + $wine меньше текущего timestamp или в которых ИП-адрес совпадает с нашим. Т.е. мы удаляем из таблицы либо старых пользователей, либо самих себя, чтобы не повторяться.
Вторым запросом мы вставляем свою запись со своим IP’м и timestamp’м. Обратите внимание ,что значение первого поля мы оставляем пустым, так как оно инкрементируется от вставки к вставке и само собой заполнится (увеличенным на 1 предыдущим значением).
После всех манипуляций с таблицей, в ней остается действительно истинное кол-во человек на сайте, с момента прихода которых не прошло $wine секунд. Нам остается лишь простым запросом выбрать все записи и подсчитать их кол-во. Это и будет кол-во пользователей в Он-Лайне. Обратите внимание, что мы с вами, как люди умные, не выбираем сразу все поля из всех записей (зачем нам лишние данные, если нужно только подсчитать количество записей), а выбираем только поле id. Это тоже прием для оптимизации запросов, хотя многие о нем забывают или не знают.
А вот потом идет, собственно, форматирование данных. На мой взгляд, я сделал его очень лаконичным и элегантным. Смотреть приятно, хотя с первого раза и не совсем понятно, как происходит процесс. Возможно, такое форматирование вам не понадобится. Вдруг вы захотите как-либо по-другому выводить информацию о кол-во юзверей. Тогда вам остается или убрать форматирование, или подредактировать его (в том числе и под свой дизайн). Так или иначе, переменная $online_people хранит кол-во пользователей и дальше вы вольны делать с ней все, что хотите. Можете просто возвратить её ( return $online_people; ) и сам формат данных осуществлять при непосредственном выводе, а не в теле функции, либо вообще, как я уже говорил, не осуществлять форматирования:
Возможно, так будет даже красивее.
Важные замечания:
- Переменная $wine на моем сайте равна 300 секундам, т.е. 5 минутам. Вы можете произвольно выставить её значение.
- При коннекте к базе и выполнении запросов мы используем конструкцию or die(), которая в случае неудачного действия завершает сценарий, но перед этим выводит в выходной поток (браузер) какую-либо строку. В нашем случае мы применяем ф-ю mysql_error(), которая возвращает в строковом виде ошибку, случившуюся во время манипуляции с базойтаблицей. Если вы не хотите завершать сценарий (в самом деле, зачем это надо: ведь из-за одной ошибки в ф-и сайт перестанет работать!), то просто не используйте эту конструкцию. Тем более что при какой-либо ошибке и наличии этой конструкции, пользователь, возможно (если ошибка при соединении с сервером), сможет узнать некоторые данные вашего сервера MySQL, а именно хост, логин пользователя и имя базы, что чревато взломом сайта (я пессимист по натуре — не верьте мне).
- Переменную $online_people мы приводим к строковому типу, так при формате информации (проверке, что выводить: "человек" или "человека") мы "крутим строкой"! Как мы крутим — думаю, разберетесь сами, после некоторого брожения мозгов :-). Возможно, можно было сделать все элегантнее и написать меньше кода — не знаю. Если вы так считаете, то пишите на Е-мэйл с кодом, который, на ваш взгляд, лучше моего. или оставляйте комментарии к этой статье. Я их просматриваю иногда (периодически раз в полгода . =)
- Ф-я time() занимается тем, что возвращает время в секундах, прошедшее с полуночи 1 января 1970 года по Гринвичу до настоящего момента. Но мы то знаем, что по научному это называется TimeStamp. $-)
- Форматирование я разделил символами перехода строки, т.к. строка проверок (где много знаков || =) очень длинная, а это приводит к растяжению статьи в ширину, в результате чего становится очень неудобно производить чтении статьи, т.к. глаза бегают туда-сюда-обратно (я не о том, что вы подумали). Вообщем вы меня поняли.
- Код рабочий — у меня такой же =) Но: несколько дополнений были сделаны только при написании статьи, в частности:
- Добавлены переменные для коннекта к базе и коннект происходит внутри функции. Естественно, у меня на сайте он происходит задолго до этого и ф-я, используя открытое соединение с MySQL-демоном, выполняет запросы.
- Форматирование я разделил символом перевода строки (причину см. выше), так что, если сценарий не заработает и выдаст тупую ошибку, типа parse error in . , то преобразуйте строку проверок в единое целое (чтобы на одной строчке все было). Но, я думаю, вы меня поняли.
- Ошибки маловероятны, но возможны, так как я правил комменты и т.п. при написании статьи, вдруг какой-нибудь символ точки с запятой забыл. Исправляйте все сами 5=).
Из добавлений, пожалуй, все. Да и статье приходит Зе Енд. Рад, что вы дочитали пособие до этого места, а еще большее эстетического наслаждение мне принесет тот факт, что статья показалось вам занимательной и оставила хорошие впечатления и знания в баш. голове. Если вы заметили ошибкинеточностибаги в статье или у вас что-то не получилось, то оставляйте комменты ниже или пишите на мыло. Я обязательно вас выслушаю и отвечу. Естественно, буду рад и добрым пожеланиям. Как же без них. Хотя критика принесет мне большую пользу.
Пример работы функции подсчета посетителей On-Line вы можете увидеть на нашем портале — Progers.Ru. Кроме этого, здесь вы можете найти много хороших статей и справочников по программированию, в частности, на PHP, с использованием MySQL.
На этом позвольте проститься с вами и пожелать удачи и. конечно же, попутного кода!
Сервис проверки посещаемости чужого сайта без открытых счетчиков и статистики.
Не точность данных
Мы не несем отвественности за предоставленные данные. Посещаемость рассчитывается по особой формуле, которая показывает только примерные данные. Не стоит полученные данные принимать за эталон.