Триада PHP & MySQL & gd library - Сервис счетчиков обращений
Php - (Hypertext
Preprocessor) - платформо-независимый язык для
динамического наполнения WEB-сайта. Тем неменее, он
позволяет динамически генерировать не только
HTML-документы, но и графические изображения в формате
gif. В статье рассмотрены вопросы обработки параметров
get-запроса, доступа к базе MySQL и генерации
gif-рисунков на практическом примере.
Когда у
вас будет свой сайт вы безусловно захотите вести
статистику посещений. Если вы предоставляете место и
траффик для бесплатного размешения страниц и хотите
предоставить каждому пользователю неограниченное
количество счетчиков, но без права исполнения скриптов,
то эта статья для Вас.
Как это работает?
Web-мастер помещает на свою страницу ссылку на рисунок.
Но не gif или jpeg, а на этот php скрипт. Положим,
ссылка на счетчик страницы 'Об авторе', расположенной на
моем сайте будет выглядеть так:
<img
src="/scripts/counter.php3?SiteID=Vlad&PageID=About">
Здесь
SiteID и PageID - так называемые get-параметры, а Vlad и
About - их значения. Эти get-параметры идентифицируют
счетчик. Скрипт найдет соответсвующую запись в базе,
увеличит значение счетчика на еденицу и построит
рисунок.
Внешний вид счетчика
Мы еще не представляем
как будет выглядеть все остальное но уже можем
обработать get-параметры
$locSiteID = $HTTP_GET_VARS["SiteID"];
$locPageID = $HTTP_GET_VARS["PageID"];
Здесь следует остановиться на важном
моменте. Дело в том, что по правилам php имена
переменных и get-параметров чувствительны к регистру.
Это значит, что если человек напишет ссылку и
get-параметры прописными буквами, то наш скрипт не
сможет распознать такой запрос. Поэтому я предлагаю не
такой изящный, но очень надежный способ интерпреции
get-параметров. Состоит он вот в чем: последоватьным
перебором всех get-параметров попытаемся найти
интересующие нас SiteID и PageID. Причем при поиске
используем нечувствительное к регистру сравнение строк:
$locSiteID = "_";
$locPageID = "_";
while (list($key, $val) = each($HTTP_GET_VARS))
{
if (strcmp(strtoupper($key),"SITEID")==0) $locSiteID = "_" . $val;
if (strcmp(strtoupper($key),"PAGEID")==0) $locPageID = "_" . $val;
}
Здесь префикс "_" необходим для
MySQL-движка. Далее установим базу счетчиков Counters
mysqladmin create Counters
и создадим в ней таблицу Counters.
Таблица как вы наверно уже догадались, состоит из трех
полей: SiteID, PageID, CountValue:
Create Table Counters (
SiteID char(120) not null,
PageID char(120) not null,
CountValue int,
index CounterIndex (SiteID,PageID));
Обратите внимание на индекс
CounterIndex. Поля, входящие в индекс, должны иметь
атрибут NOT NULL, размер ключей (читай полей, входящих в
индекс) не должен превышать 256 символов. И последнее -
порядок полей в индексе должен совпадать с порядком в
секции Where SQL запроса. Если же Вы планируете
небольшую базу и колчество записей невелико, то индекс
можно и не создавать.
Для работы с базой нам
потребуется всего три запроса:
Создать новую
запись в базе при первом обращении к счетчику:
INSERT INTO counters (SiteID,PageID,CountValue)
VALUES ('$locSiteID','$locPageID',1)
Найти значение счетчика:
SELECT * FROM counters WHERE SiteID='$locSiteID' AND PageID='$locPageID'
Увеличить
значение счетчика на еденицу:
UPDATE counters SET CountValue = CountValue+1
WHERE SiteID = '$locSiteID' AND PageID = '$locPageID'
А теперь самое время вспомнить про
префикс "_" значений get-параметров. На самом деле все
очень просто. Посмотрите на структуру таблицы. Поля
SiteID, PageID помечены аттрибутом NOT NULL, и префикс
"_" позволяет пропустить один или даже оба параметра в
get-запросе:
// Нечувствительные к регистру get-параметры
$locSiteID = "_";
$locPageID = "_";
while (list($key, $val) = each($HTTP_GET_VARS))
{
if (strcmp(strtoupper($key),"SITEID")==0) $locSiteID = "_" . $val;
if (strcmp(strtoupper($key),"PAGEID")==0) $locPageID = "_" . $val;
}
// Соеденяемся с базой Counters и запрашиваем значение счетчика
mysql_connect("localhost:3306","root","");
if (!($result = mysql_db_query("Counters","select * from counters
where SiteID='$locSiteID' AND PageID='$locPageID'")))
{
// База Counters не доступна - катапультируемся
echo "Cannot query database Counters\\n";
echo "Query Error " . mysql_errno() . " " . mysql_error();
exit;
}
$FirstVisit=1;
while($row = mysql_fetch_object($result))
{
$FirstVisit=0;
$locCountValue = $row->CountValue;
}
mysql_free_result($result);
if ($FirstVisit==1)
{ // Первое обращение. Создаем запись в базе
$result = mysql_db_query("Counters","Insert Into Counters
(SiteID,PageID,CountValue) Values ('$locSiteID','$locPageID',1)");
$locCountValue = 1;
}
else
{ // Увеличиваем значение счетчика на еденицу
$locCountValue = $locCountValue + 1;
$result = mysql_db_query("Counters","Update Counters Set
CountValue = CountValue+1 Where SiteID = '$locSiteID'
AND PageID = '$locPageID'");
}
Преобразовываем число в строку и
форматируем в шестизначное число.
$strCounterValue = sprintf("%d",$locCountValue);
while(strlen($strCounterValue)<6) $strCounterValue = "0" . $strCounterValue;
$txtlen = strlen($strCounterValue);
Далее показано как пользоваться gd
library в php для динамического рисования счетчика.
Строго говоря, это не самый иллюстративный пример.
Шрифты, входящие в библиотеку gd library могут
различаться по дистрибутивам, поэтому для этого проекта
я использовал спецальный формат представления шрифта и
процедуру его отображения. Тем неменее код достаточно
документирован и, я надеюсь, поможет вам сделать
очередной шаг.
Header("Content-type: image/gif");
$DeskWidth=24; $DeskHeight=48; $DeskSpace=5;
/* Создаем рисунок imgWidth * imgHeight pixels. */
$imgWidth= $txtlen * ($DeskWidth + $DeskSpace) - $DeskSpace;
$imgHeight = $DeskHeight;
$im_out = ImageCreate($imgWidth, $imgHeight);
/* Резервируем цвета в палитре*/
$white = ImageColorAllocate($im_out, 255, 255, 255);
$grey = ImageColorAllocate($im_out, 0, 0, 77);
$blue = ImageColorAllocate($im_out, 40, 5, 250);
$trans = ImageColorAllocate($im_out, 1, 1, 1);
$red = ImageColorAllocate($im_out, 40, 33, 155);
/* Устанавливаем прозрачный цвет и рисуем фон*/
ImageColorTransparent($im_out, $trans);
for ($dy=0; $dy < $imgHeight; $dy++)
ImageLine($im_out, 0, $dy, $imgWidth-1, $dy, $trans);
for ($dy=2; $dy < $imgHeight; $dy=$dy+4)
ImageLine($im_out,0,$dy,$imgWidth-1,$dy,$red);
// Далее выводим цифры по пикселам,
// сначала "тень" со смещением в один пиксел а поверх и "лицо"
$CurColor=$white;
for ($txtcur=0;$txtcur<$txtlen;$txtcur++)
{
$bx=$txtcur*($DeskWidth+$DeskSpace);
for ($dy=0;$dy<$imgHeight;$dy++)
ImageLine($im_out,$bx,$dy,$bx+$DeskWidth-1,$dy,$blue);
$bx=$bx+($DeskWidth-22)/2;
$c=0+$strCounterValue[$txtcur];
if ($c!=0) $CurColor=$white;
if (($c>=0) && ($c<=9))
for ($id=1;$id>=0;$id--)
{
if ($id==1) $CurColor=$grey; else $CurColor=$white;
for ($dy=0;$dy<48;$dy++)
for ($dx=0;$dx<22;$dx++)
{
$my_pos = $c*48*3 + $dy*3 + ($dx>>3);
$my_byte = $CounterDigitData[$my_pos];
if ((($my_byte >> (7-($dx & 7))) & 1) == 1)
ImageSetPixel($im_out,$bx+$dx+$id-1, $dy+$id, $CurColor);
}
}
}
// Отправляем обозревателю картинку ...
ImageGif($im_out);
// ... и освобождаем память
ImageDestroy($im_out);
Источник: www.npksv.ru
|