Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

   Интернет технологии -> PHP -> И сколько человек на сайте ?


И сколько человек на сайте ?

Всем доброго времени суток!

Наверняка, гуляя по сети в поисках порн..., т.е. в поисках какой-либо информации, вы натыкались на такую фишку, типа:

На сайте: 100 человек

Т.е., когда примерно в таком контексте выводится количество человек, присутствующих в данное время на сайте. Когда я впервые увидел такую фичу, мне она показалось интересной и симпотной.

Недавно, по личной надобности, мне захотелось сделать такое для своего сайта и я реализовал все это дело с использованием PHP+MySQL.

Итак, в этой статье я хочу вам рассказать, как сделать такую фичу для сайта. Это на самом деле проще жареной капусты ;=) и вскоре вы убедитесь в этом.

Все что нам нужно, это - хостинг с поддержкой 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 поля:

    id - ключевое авто_инкрементирующееся поле типа INT с максимальным размеров в 10 символов. Нужно для более оптимизированной работы с таблицой, хотя его можно и опустить. При каждом заходе человека на сайт, поле будет увеличивать свое значение на 1.
  • ip - поле символьного типа VARCHAR с максимальным значением 20 cимволов (лично я не видел еще IP-адреса, размером больше 15 символов, но на всякий случай =). В нем хранятся, соответственно, IP'ы людей. Значение по умолчанию - 0.
  • unix - поле символьного типа VARCHAR с максимальным значением 60 символов. Поле, в котором будет храниться timestamp пользователя. Такое странное название выражено скорее моими личными пристрастиями, чем истинным его предназначением. Хотя скажу, что timestamp-формат принят в операционных системах UNIX, как стандарный. Можете поле назвать как угодно (только мой пример с этим именами полей). По дефолту пустое значение.

Замечу, что поле unix будет иметь тип VARCHAR, а не встроенный разработчиками MySQL тип TIMESTAMP. Это связано с тем, что этот тип слишком неудобен для хранения данных даты\времени в базе, как это может показаться на первый взгляд.

Далее привожу запрос, выполнив который, вы создадите соответствующую таблицу с нужными полями. Запрос можно выполнить функцией PHP mysql_query(), либо в какой-нибудь удобной оболочке для работы с MySQL. Например в PHPMyAdmin.

CREATE TABLE `online` (
`id` int(10) NOT NULL auto_increment,
`ip` varchar(20) NOT NULL default '0',
`unix` varchar(60) NOT NULL default '',
KEY `id` (`id`)
)

Выполнили? Молодцы. Напомню, что команды синтаксиса MySQL лучше всего привыкать писать в верхнем регистре и не для понта, как думают некоторые, а для повышении удобочитаемости кода и просто потому, что так принято.

После выполнения запроса, нам остается только написать код, который будет заниматься, собственно, подсчетом кол-а человек на линии. Этот код я запихнул в отдельную функцию, которая хранится у меня в файле, а сам файл инклюдится ( include(), require() ) на каждой странице моего сайта где-нибудь в самом начале. Я привожу вам пример функции точь-в-точь, какую я написал для своего сайта, разве только немного измененную в целях публичного использования. При наличии необходимых знаний, вы легко сможете отредактировать её под себя.

#------ Файл online.php

/* ф-я подсчитывает пользователей на линии; возвращает кол-во пользователей в отформатированном виде, т.е. для вывода результата нужно лишь прописать в нужном месте типа: echo on_line(); */
function on_line() {
$host = "localhost"; // хост, где расположена база данных MySql
$db_name = ""; // имя базы данных; как правило совпадает с именем юзера (переменная ниже), хотя я категорически против одинаковых имен, ориентируясь на защиту...
$db_user = ""; // пользователь, которому разрешен доступ к базе
$db_password = ""; // пароль пользователя
$wine = 300; // точность он-лайн (секунды); время, в течении которого пользователя, зашедшего на страничку, мы считаем находящимся на сайте
$table_online = "online"; // имя таблицы

// делаем доступной глобальную переменную ИП-адреса
global $REMOTE_ADDR;

// соединяемся с сервером MySQL и выбираем нужную базу
mysql_connect($host,$db_user,$db_password) or die(mysql_error());
mysql_select_db($db_name) or die(mysql_error());

// удаляем всех, кто уже пробыл $wine секунд или у кого ИП текущий
$sql_update = "DELETE FROM $table_online WHERE `unix`+$wine < ".time()." OR `ip` = '$REMOTE_ADDR'";
$result_update = mysql_query($sql_update) or die(mysql_error());

// вставляем свою запись
$sql_insert = "INSERT INTO $table_online VALUES ('','$REMOTE_ADDR','".time()."')";
$result_insert = mysql_query($sql_insert) or die(mysql_error());

// считаем уников он-лайн
$sql_sel = "SELECT `id` FROM $table_online";
$result_sel = mysql_query($sql_sel) or die(mysql_error());

$online_people = mysql_num_rows($result_sel); // кол-во On-Line пользователей
$online_people = (string) $online_people; // приводим к строковому типу (так надо.. см. дальше)

$rain = strlen($online_people) - 1; // номер последнего символа в числе on-line юзеров

// форматирование вывода (я все сделал за вас =)
if($online_people[$rain]==2||$online_people[$rain]==3
||$online_people[$rain]==4
||(strlen($online_people)!=1&&$online_people[strlen($online_people)-2]!=1))
$line = "человека"; else $line = "человек"; // $line - переменная, определяющая формат вывода

// возвращем результат
return "На сайте <strong>".$online_people."</strong>$line";
}

Вот такая вот функция. Где-нибудь в начале файла вам надо будет вставлять её как-нибудь по типу:

include 'online.php';

А в том месте, где нужно вывести кол-во пользователей, писать:

echo on_line();

Теперь разъясню немного код функции, так как в ней самой я все подробно откомментировал. Сначала идут переменные, нужные для удачного коннекта к базе, а также переменная $wine - наша точность. Также делается доступной из функции глобальная переменная $REMOTE_ADDR, которая возвращает IP-адрес клиентского компьютера. После происходит соединение с сервером MySQL. И уже после начинается самое интересное.

Первым запросом к базе ( запросы выполняются ф-й mysql_query() ) мы удаляем все записи, в которых timestamp + $wine меньше текущего timestamp или в которых ИП-адрес совпадает с нашим. Т.е. мы удаляем из таблицы либо старых пользователей, либо самих себя, чтобы не повторяться.

Вторым запросом мы вставляем свою запись со своим IP'м и timestamp'м. Обратите внимание ,что значение первого поля мы оставляем пустым, так как оно инкрементируется от вставки к вставке и само собой заполнится (увеличенным на 1 предыдущим значением).

После всех манипуляций с таблицой, в ней остается действительно истинное кол-во человек на сайте, с момента прихода которых не прошло $wine секунд. Нам остается лишь простым запросом выбрать все записи и подсчитать их кол-во. Это и будет кол-во пользователей в Он-Лайне. Обратите внимание, что мы с вами, как люди умные, не выбираем сразу все поля из всех записей (зачем нам лишние данные, если нужно только подсчитать количество записей), а выбираем только поле id. Это тоже прием для оптимизации запросов, хотя многие о нем забывают или не знают.

А вот потом идет, собственно, форматирование данных. На мой взгляд, я сделал его очень лаконичным и элегантным. Смотреть приятно, хотя с первого раза и не совсем понятно, как происходит процесс. Возможно, такое форматирование вам не понадобится. Вдруг вы захотите как-либо по-другому выводить информацию о кол-во юзверей. Тогда вам остается или убрать форматирование, или подредактировать его (в том числе и под свой дизайн). Так или иначе, переменная $online_people хранит кол-во пользователей и дальше вы вольны делать с ней все, что хотите. Можете просто возвратить её ( return $online_people; ) и сам формат данных осуществлять при непосредственном выводе, а не в теле функции, либо вообще, как я уже говорил, не осуществлять форматирования:

echo "On-Line: ".on_line()

Возможно, так будет даже красивее.

Важные замечания:

  • Переменная $wine на моем сайте равна 300 секундам, т.е. 5 минутам. Вы можете произвольно выставить её значение.
  • При коннекте к базе и выполнении запросов мы используем конструкцию or die(), которая в случае неудачного действия завершает сценарий, но перед этим выводит в выходной поток (броузер) какую-либо строку. В нашем случае мы применяем ф-ю mysql_error(), которая возвращает в строковом виде ошибку, случившуюся во время манипуляции с базой\таблицой. Если вы не хотите завершать сценарий (в самом деле, зачем это надо: ведь из-за одной ошибки в ф-и сайт перестанет работать!), то просто не используйте эту конструкцию. Тем более что при какой-либо ошибке и наличии этой конструкции, пользователь, возможно (если ошибка при соединении с сервером), сможет узнать некоторые данные вашего сервера MySQL, а именно хост, логин пользователя и имя базы, что чревато взломом сайта (я пессимист по натуре - не верьте мне).
  • Переменную $online_people мы приводим к строковому типу, так при формате информации (проверке, что выводить: "человек" или "человека") мы "крутим строкой"! Как мы крутим - думаю, разберетесь сами, после некоторого брожжения мозгов :-). Возможно, можно было сделать все элегантнее и написать меньше кода - не знаю... Если вы так считаете, то пишите на е-майл с кодом, который, на ваш взгляд, лучше моего... или оставляйте комментарии к этой статье. Я их просматриваю иногда (периодически раз в полгода ...=)
  • Ф-я time() занимается тем, что возвращает время в секундах, прошедшее с полуночи 1 января 1970 года по Гринвичу до настоящего момента. Но мы то знаем, что по научному это называется TimeStamp... $-)
  • Форматирование я разделил символами перехода строки, т.к. строка проверок (где много знаков || =) очень длинная, а это приводит к растяжению статьи в ширину, в результате чего становится очень неудобно производить чтении статьи, т.к. глаза бегают туда-сюда-обратно (я не о том, что вы подумали). Вообщем вы меня поняли.
  • Код рабочий - у меня такой же =) Но: несколько дополнений были сделаны только при написании статьи, в частности:
    • Добавлены переменные для коннекта к базе и коннект происходит внутри функции. Естественно, у меня на сайте он происходит задолго до этого и ф-я, используя открытое соединение с MySQL-демоном, выполняет запросы.
    • Форматирование я разделил символом перевода строки (причину см. выше), так что, если сценарий не заработает и выдаст тупую ошибку, типа parse error in ..., то преобразуйте строку проверок в единое целое (чтобы на одной строчке все было). Но, я думаю, вы меня поняли.
    • Ошибки маловероятны, но возможны, так как я правил комменты и т.п. при написании статьи, вдруг какой-нибудь символ точки с запятой забыл. Исправляйте все сами 5=).

Из добавлений, пожалуй, все. Да и статье приходит Зе Енд. Рад, что вы дочитали пособие до этого места, а еще большее эстетического наслаждение мне принисет тот факт, что статья показалось вам занимательной и оставила хорошие впечатления и знания в баш... голове.

Автор: Makswell
Источник: www.progers.ru

Ссылки по теме
Чтение почты через Web-интерфейс
Полезные скрипты на PHP
PHP и формы
Почтовые функции в РНР
Отправка электронной почты с помощью PHP
 

Компьютерная документация от А до Я - Главная

 

 
Интересное в сети
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full


Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
 
Это интересно
 

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.