|
Пишем счетчик обращений
Ну вот и добрались до чего-то конкретного. Количество посещений страницы - это, конечно, не мощный сервис со статистикой посещений, Топ100 лучших сайтов и тому подобными вещами, но все равно приятно. Итак, что нам нужно?
Для начала нужно где-то сохранить число показов страницы, поскольку данные между обращениями к счетчику в памяти не сохраняются. Вариантов в общем случае два: файл и база данных. Последнее не всгда доступно, впрочем нам для маленького скрипта и не надо. Вот если бы мы делали "систему интернет-статистики", как написано на ХотЛоге... Короче, план такой: открываем файл, считываем из него число, выводим (красиво), увеличиваем число и записываем его в файл. Приступаем:
function Counter($id) //счетчик сделаем в виде функции, чтобы потом не
{ //вставлять весь этот код в текст страницы.
$fname = "cnt".$id.".txt"; //формируем имя файла. что-то вроде cnt01.txt
if(!file_exists($fname)): //если файл не существует
$cnt = 0; //то обнуляем счетчик
else:
$fc = @fopen($fname, "r") //иначе открываем файл для чтения
if ($fc): //проверяем, открылся ли файл
$cnt = fgets($fc); //читаем строку
fclose($fc); //закрываем файл
else:
$cnt = 0; //если не открылся, то обнуляем счетчик
endif;
endif;
//теперь в переменной $cnt - число обращений до нас
$fc = @fopen($fname, "w") //открываем файл для записи
or die('<B>Ошибка при открытии файла для записи.</b>');
//А если не получилось, завершаем выполнение скрипта и выводим сообщение.
fwrite($fc, ++$cnt); //увеличиваем $cnt на 1 и сохраняем новое значение
return($cnt); //возвращаем значение счетчика
}
Теперь достаточно в нужном месте на странице вставить <?php print(Counter('01')); ?> и пользователь, загрузивший страничку увидит например: "Вы - 1024 посетитель нашего сайта." Страничка, правда, должна иметь расширение .php что бы все заработало. Функцию можно убрать в другой файл и вызывать по мере необходимости, предварительно написав include "counter.php";.
Первую часть функции можно переписать короче:
if (!$fc = @fopen($fname, 'r')):
$cnt = 0;
else:
$cnt = fgets($fc);
endif;
или еще короче:
$cnt = (!$fc = @fopen($fname, 'r')) ? 0 : fgets($fc);
Что мы использовали:
- file_exists(строка имя_файла) - возвращает TRUE если указаный файл существует, иначе - FALSE.
- fopen(строка имя_файла, строка режим) - связывает переменную-ресурс с файлом. Файл может быть как на локальной машине так и в Интернете. Параметр режим определяет тип доступа к файлу: "r" - чтение с начала файла, "r+" - чтение и запись с начала файла; "w" - перезапись файла, "w+" - перезапись и чтение; "a", "a+" - добавдение в файл. Если файл не удается открыть, функция возвращает FALSE.
- fgets(ресурс дескриптор, [целое длина]) - возвращает строку из ранее открытого файла, размером длина - 1 байт. С версии PHP 4.3 опускание параметра длина приводит к чтению строки до конца. При возникновении ошибки функция возвращает FALSE.
- fwrite(ресурс дескриптор, строка строка [, целое длина]) - выводит строку в файл. Если указан параметр длина, то процесс остановится, когда будет записано столько байт, если строка не будет записана целиком раньше. Если возникнет ошибка, функция вернет FALSE, иначе - число заисаных байт.
- fclose(ресурс дескриптор) - закрывает ранее открытый файл. Возвращает TRUE если все в порядке и FALSE в противном случае.
- die(строка сообщение) - завершает выполнение скрипта и выводить сообщение Вместо строки можно подставить целое, но оно выведено не будет. Это синоним функции exit(), который, лично мне, встречался чаще. Видимо, авторами виденых скриптов были очень кровожадные люди :).
Оператор @ в последнем примере подавляет вывод ошибок при выполнении fopen(). На время отладки лучше его не ставить, а так пользователю совсем не обязательно знать, почему он всегда первый посетитель :). Файл может не открыться, например, из-за неверно выставленых прав доступа (должны быть права на чтение и запись для всех групп, т.е. '666').
Модернизируем наш счетчик. Теперь он должен будет выводить еще и количество посетителей за сегодняшний день. Для этого мы будем сохранять в файле дату последнего обращения (день, месяц, год), число посетителей в этот день и общее число посетителей. При обращении, будем сравнивать дату с текущей, и если она не совпадет, обнулять счетчик. Поехали:
function Counter($id)
{
$fname = "cnt".$id.".txt";
if (!$fc = @fopen($fname, 'r')): //если файл открыть не получилось
$cnt = 0;
$date = date('dmY'); //обнуляем счетчики и выставляем текущую дату
$dcnt = 0;
else:
$cnt = fgets($fc); //иначе считываем основной счетчик
$date = trim(fgets($fc)); //дату, и одновременно отрезаем символы конца строки
$dcnt = fgets($fc); //и счетчик за сегодня
endif;
$cnt = $cnt + 1; //увеличиваем основной счетчик (автоматически приводим к целому типу)
if (date('dmY') == $date): //если дата не изменилась
$dcnt = $dcnt + 1; //увеличиваем счетчик за сегодня
else:
$dcnt = 1; //иначе сбрасываем
$date = date('dmY'); //и берем новую дату
endif;
$fc = @fopen($fname, "w")
or die('<B>Ошибка при открытии файла для записи.</b>');
fwrite($fc, $cnt."\r\n"); //сохраняем
fwrite($fc, $date."\r\n");
fwrite($fc, $dcnt."\r\n");
$res['cnt'] = $cnt; //возвращать результат будем в виде массива
$res['dcnt'] = $dcnt;
return($res);
}
Поскольку возвращаем мы значения в виде массива, вывод будет выглядеть чуть иначе: Вы <?php $r = Counter('01'); print("{$r['cnt']} ({$r['dcnt']} за сегодня)"); ?> - посетитель этого сайта!.
- trim(строка строка [, строка список_символов]) - удаляет пробелы и некоторые спец. символы (табуляция, конец строки...) из начала и конца строки. Используйте список_символов для указания символов для удаления. Возвращает обрезаную строку.
- date(строка формат [, строка метка_времени]) - возвращает строку с текущей датой/временем, в формате, задаваемом строкой формат если не указана метка_времени. Иначе, по времени, указаному в метке. Подробнее см. в Руководстве.
Графический счетчик
Надписи на странице это конечно хорошо, но есть два момента. Во-первых, необходимо вставлять в страницу PHP код и сохранять ее как .php файл. Во-вторых, где вы сейчас найдете текстовый счетчик? Сплошные картинки. Чтобы не отставать от прогресса, мы тоже сделаем себе такой, благо в PHP входят функции по работе с изображениями. Если вы еще не раскоментировали в php.ini строку "extension=php_gd2.dll" сейчас самое время. Эта строка подключает библиотеку GD2.
В этот раз счетчик должен быть оформлен отдельным файлом:
Файл "gcounter.php"
<?php
$fname = "cnt".$_GET['id'].".txt"; //Создаем название файла с данными счетчика
if (!$fc = fopen($fname, 'r')): //открываем и загружаем
$cnt = 0;
$date = date('dmY');
$dcnt = 0;
else:
$cnt = fgets($fc);
$date = trim(fgets($fc));
$dcnt = fgets($fc);
endif;
$cnt = $cnt + 1; //пересчитываем и сохраняем
if (date('dmY') == $date):
$dcnt = $dcnt + 1;
else:
$dcnt = 1;
$date = date('dmY');
endif;
$fc = @fopen($fname, "w")
or die('<B>Ошибка при открытии файла для записи.</b>');
fwrite($fc, $cnt."\r\n");
fwrite($fc, $date."\r\n");
fwrite($fc, $dcnt."\r\n");
while(strlen($cnt) < 5): //дополняем строку нулями слева
$cnt = "0".$cnt; //зачем? чтобы красиво было :)
endwhile;
header("Content-type: image/png"); //сообщаем браузеру, что сейчас пойдет картинка
if ($im = @imagecreatefrompng("banner1.png")): //создаем изображение из файла
$top = 18;
$left = 44;
$w = imagefontwidth(3);
$w = (5 - strlen($dcnt))*$w; //рассчитываем положение надписей
$text_color = imagecolorallocate($im, 55, 55, 55);
imagestring($im, 3, $left, $top, $cnt, $text_color); //и выводим текст на рисунок
imagestring($im, 3, $left+$w, $top-12, $dcnt, $text_color);
imagepng($im); //посылаем рисунок браузеру
imagedestroy($im); //освобождаем память
endif;
?>
Как поместить такой счетчик на свою страницу? очень просто:
<IMG src="gcounter.php?id=01">
Все. Если счетчик находится на другом сервере, естественно необходимо указать полный путь. Можно еще сделать из него ссылку, и все будет почти как у "взрослых". Этот счетчик, правда, не собирает сведения о посетителе, но думаю, покопавшись в массиве $_SERVER, можно это исправить. Ну и Топ100 без базы данных сделать затруднительно :).
- $_GET['id'] - получение из массива $_GET параметра с именем id. В массиве $_GET хранятся параметры, переданые через адрес (метод HTTP GET). Передача параметров таким способом выглядит так: http://www.somesite.ru/page.php?имя1=значение1&имя2=значение2....
- strlen(строка строка) - возвращает длину строки.
- header(строка строка) - посылает клиенту заголовок HTTP. Мы использовали его, чтобы сообщить браузеру, что посылаем картинку. В принципе, если обращаться к скрипту только через <IMG src = ...>, можно обойтись и без заголовка, но при обращении напрямую к скрипту, в браузере будет масса странных символов.
- imagecreatefrompng(строка имя_файла) - загружает картинку в png формате и возвращает дескриптор рисунка. Если загрузка прошла неудачно, возвращает FALSE
- imagefontwidth(целое шрифт) - возвращает ширину одного символа указаного шрифта.
- imagecolorallocate(ресурс рисунок, целое красный, целое зеленый, целое синий) - создает новый цвет для рисунка, задаваемый RGB. Функцию необходимо вызвать для каждого цвета, который планируется использовать. Она возвращает номер цвета в палитре рисунка или -1 при возникновении ошибки.
- imagestring(ресурс рисунок, целое шрифт, целое x, целое y, строка s, целое цвет) - выводит на рисунок строку s заданым шрифтом, начиная с точки с координатами (x, y). Шрифты с номерами 1, 2, 3, 4, 5 - встроеные.
- imagepng(ресурс рисунок [, строка имя_файла]) - отсылает рисунок браузеру, либо сохраняет его в файл.
- imagedestroy(ресурс рисунок) - освобождает память, занятую рисунком.
Ну вот, на сегодня это все :)
| |