В данной статье рассказывается как создать интернет-счётчик для корпоративного портала.

Задача
Счётчик должен вести подробную информацию о посетителях: адрес откуда пришёл посетитель, адрес страницы, ip-адрес посетителя, дата, браузер пользователя,
операционная система.

По ip-адресу можно определить страну и регион откуда пришёл посетитель.

Кроме того мы должны иметь возможность просматривать статистику посещений по дням, количество новых посетителей (и их ip-адреса), количество уникальних
посетителей (и их ip-адреса), самые лучшие ссылки на на нашу интернет-страницу, самые популярные страницы и т.п..

Схема выполнения
Для начала, рассмотрим схему выполнения счётчика.

Пользователь из интернет (Пользователь1, Пользователь2, Пользователь3) заходит на нашу интернет-страницу, расположенную на сервере провайдера.
На интернет-странице выполняется код на php, который определяет ip-адрес пользователя, url откуда пришёл, url страницы, браузер и операционную систему
пользователя. Эти данные программа передаёт на корпоративный интернет-сервер.
На корпоративном интернет-сервере вызывается хранимая процедура interbase для передачи данных о пользователе и получении статистической информации для
интернет-страницы.
Статистически данные передаются в программу на Интернет-странице и выводятся для посетителя.
Со временем, администратор подключается к interbase-серверу с помощью клиенской программы (написанной на delphi) и обрабатывает информацию.

Примечание: Корпоративный сервер и interbase-сервер можно совместить, но тогда уменьшается уровень защиты информации. Так как зная пароль и имя пользователя
можно будет подключиться к базе данных из интернет.

Структура базы данных
Теперь создадим структуру базы данных.

Таблица project предназначена для хранения названия проекта. Таким образом, мы можем создавать сколько угодно счётчиков.

В таблице countdata накапливается информация о посетителях:

urlfrom – откуда пришёл посетитель,
urlcurr – какую страницу посетили,
datehint – дата (без времени) когда посетили,
fulldate – полная дата,
ipuser – ip-адрес посетителя,
browser – браузер,
systemuser – операционная система пользователя,
systemver – версия операционной системы,
compname – название компьютера посетителя.

В таблице iptable хранятся адреса уникальных ip-адресов.

Скрипт базы данных
Сгенерируем скрипт базы данных по данной структуре:

HTML
Текст

  1. create table countdata (
  2. countdataid integer not null,
  3. projid integer,
  4. urlfrom varchar(1024),
  5. urlcurr varchar(1024),
  6. datehint date,
  7. fulldate date,
  8. ipuser varchar(15),
  9. browser varchar(255),
  10. systemuser varchar(255),
  11. systemver varchar(255)
  12. );

  13. create index if318countdata on countdata
  14. (
  15. projid
  16. );

  17. create index ak_ip on countdata
  18. (
  19. ipuser
  20. );

  21. create index ak_datehint on countdata
  22. (
  23. datehint
  24. );

  25. alter table countdata
  26. add constraint pkcountdata primary key (countdataid);

  27. create table iptable (
  28. ipuser varchar(15) not null,
  29. dateadd date
  30. );

  31. create index akdateadd on iptable
  32. (
  33. dateadd
  34. );

  35. alter table iptable
  36. add constraint pkiptable primary key (ipuser);

  37. create table project (
  38. projid integer not null,
  39. projname varchar(255),
  40. comment blob sub_type 1
  41. );

  42. alter table project
  43. add constraint pkproject primary key (projid);

  44. alter table countdata
  45. add constraint project_countdata
  46. foreign key (projid)
  47. references project;

  48. create exception erwin_parent_insert_restrict "cannot insert parent table because child table exists.";
  49. create exception erwin_parent_update_restrict "cannot update parent table because child table exists.";
  50. create exception erwin_parent_delete_restrict "cannot delete parent table because child table exists.";
  51. create exception erwin_child_insert_restrict "cannot insert child table because parent table does not exist.";
  52. create exception erwin_child_update_restrict "cannot update child table because parent table does not exist.";
  53. create exception erwin_child_delete_restrict "cannot delete child table because parent table does not exist.";

  54. set term ^;

  55. create trigger ti_countdata for countdata after insert as
  56. declare variable numrows integer;
  57. begin
  58. select count(*)
  59. from project
  60. where
  61. new.projid = project.projid into numrows;
  62. if (
  63. new.projid is not null and
  64. numrows = 0
  65. ) then
  66. begin
  67. exception erwin_child_insert_restrict;
  68. end

  69. end ^

  70. create trigger tu_countdata for countdata after update as
  71. declare variable numrows integer;
  72. begin
  73. select count(*)
  74. from project
  75. where
  76. new.projid = project.projid into numrows;
  77. if (
  78. new.projid is not null and
  79. numrows = 0
  80. ) then
  81. begin
  82. exception erwin_child_update_restrict;
  83. end

  84. end ^

  85. create trigger td_project for project after delete as
  86. declare variable numrows integer;
  87. begin
  88. select count(*)
  89. from countdata
  90. where
  91. countdata.projid = old.projid into numrows;
  92. if (numrows > 0) then
  93. begin
  94. exception erwin_parent_delete_restrict;
  95. end

  96. end ^

  97. create trigger tu_project for project after update as
  98. declare variable numrows integer;
  99. begin
  100. if
  101. (old.projid <> new.projid) then
  102. begin
  103. update countdata
  104. set
  105. countdata.projid = new.projid
  106. where
  107. countdata.projid = old.projid;
  108. end

  109. end ^

Триггера и хранимые процедуры
Уникальные ip-адреса

Уникальные ip-адреса будут фиксироваться автоматически базой данных. Для этого мы напишем пару триггеров.

Триггер вставки уникальных ip-адресов:

HTML
Текст

  1. create trigger rti_countdata for countdata before insert position 0 as
  2. declare variable cnt integer;
  3. begin
  4. new.countdataid=gen_id(gcountdataid,1);
  5. new.datehint="today";
  6. new.fulldate="now";

  7. select count(*)
  8. from iptable
  9. where (ipuser=new.ipuser)
  10. and(projid=new.projid)
  11. into cnt;

  12. if (cnt=0) then
  13. insert into iptable (ipuser, projid)
  14. values (new.ipuser, new.projid);
  15. end
  16. ^

Триггер заполнения даты уникального ip-адреса:

HTML
Текст

  1. create trigger rti_iptable for iptable before insert position 0 as
  2. begin
  3. new.dateadd="today"
  4. end

Регистрация пользователя в базе данных

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

HTML
Текст

  1. /***********************************************************************/
  2. /* Процедура регистрации посетителя интернет странички */
  3. /***********************************************************************/
  4. create procedure proc_count_data
  5. (projid integer,
  6. urlfrom varchar(1024),
  7. urlcurr varchar(1024),
  8. ipuser varchar(15),
  9. browser varchar(255),
  10. systemuser varchar(255),
  11. systemver varchar(255),
  12. compname varchar(255)
  13. )
  14. returns (
  15. mindate date, /* Дата установки счётчика */
  16. number_zagruzk integer, /* Количество загрузок */
  17. number_un_zagruzk integer, /* Количество уникальных загрузок */
  18. number_zagr_date integer, /* Количество загрузок сегодня */
  19. number_zagr_un_date integer) /* Количество уникальных загрузок */
  20. as
  21. begin

  22. insert into countdata (projid, urlfrom, urlcurr, ipuser,
  23. browser, systemuser, systemver, compname)
  24. values (:projid, :urlfrom, :urlcurr, :ipuser,
  25. :browser, :systemuser, :systemver, :compname);

  26. /* Время установки счётчика */
  27. select min(datehint)
  28. from countdata
  29. into :mindate;

  30. if (mindate is null) then mindate="today";

  31. /* Колчичество загрузок */
  32. select count(*)
  33. from countdata
  34. into :number_zagruzk;

  35. /* Количество уникальных загрузок */
  36. select count(*)
  37. from iptable
  38. into :number_un_zagruzk;

  39. /* Колчичество загрузок сегодня */
  40. select count(*)
  41. from countdata
  42. where datehint="today"
  43. into :number_zagr_date;

  44. /* Количество уникальных загрузок сегодня */
  45. select count(*)
  46. from iptable
  47. where dateadd="today"
  48. into :number_zagr_un_date;

  49. suspend;

  50. end
  51. ^

  52. Расшифруем передаваемые поля процедуре:

  53. projid id проекта (счётчика),
  54. urlfrom откуда пришли,
  55. urlcurr куда пришли,
  56. ipuser ip-адрес пользователя,
  57. browser - браузер,
  58. systemuser операционная система пользователя,
  59. systemver версия операционной системы пользователя,
  60. compname название компьютера.

  61. Процедура возвращает статистическую информацию:

  62. mindate - дата установки счётчика,
  63. number_zagruzk integer общее количество загрузок,
  64. number_un_zagruzk integer общее количество уникальных загрузок,
  65. number_zagr_date integer - количество загрузок за сегодня,
  66. number_zagr_un_date integer) - Количество уникальных загрузок за сегодня.

  67. Получение списка повторных посетителей

  68. Хранимая процедура для получения списка повторных посетителей

  69. /***********************************************************************/
  70. /* Процедура для извлечения повторных посетителей */
  71. /***********************************************************************/
  72. create procedure povtor_posetit
  73. (projid integer,
  74. dateot date,
  75. datedo date
  76. )
  77. returns (
  78. ipuser varchar(15)
  79. )
  80. as
  81. begin
  82. for select c.ipuser
  83. from countdata c
  84. where (c.datehint>=:dateot)
  85. and(c.datehint< =:datedo)
  86. and(c.projid>=:projid)
  87. and(c.ipuser not in (select it.ipuser
  88. from iptable it
  89. where (it.dateadd>=:dateot)
  90. and(it.dateadd< =:datedo)
  91. and(it.projid=:projid)
  92. ))
  93. group by c.ipuser
  94. into :ipuser
  95. do
  96. begin
  97. suspend;
  98. end

  99. end
  100. ^

Процедуре мы передаём диапазон за который хотим посмотреть статистику, а она возвращает ip-адреса пользователей, которые повторно посетили наш сайт.

Статистика посещений по дням

Хранимая процедура для расчёты статистики посещений по дням:

HTML
Текст

  1. /***********************************************************************/
  2. /* Статистика посещений по дням */
  3. /***********************************************************************/
  4. create procedure stat_day
  5. (projid integer,
  6. dateot date,
  7. datedo date
  8. )
  9. returns (
  10. date_posetit date, /* Дата посещения */
  11. kol_posesch integer,/* Количество посещений */
  12. kol_unikaln integer, /* Количество уникальных загрузок */
  13. kol_povtorn_poset integer /* Количество повторных посетителей */
  14. )
  15. as
  16. begin

  17. for select datehint
  18. from countdata
  19. where (projid=:projid)
  20. and(datehint>=:dateot)
  21. and(datehint< =:datedo)
  22. group by datehint
  23. into :date_posetit
  24. do
  25. begin

  26. /* Колчичество загрузок */
  27. select count(*)
  28. from countdata
  29. where datehint=:date_posetit
  30. into :kol_posesch;

  31. /* Количество уникальных загрузок */
  32. select count(*)
  33. from iptable
  34. where dateadd=:date_posetit
  35. into :kol_unikaln;

  36. select count(*)
  37. from povtor_posetit(:projid, :date_posetit, :date_posetit)
  38. into kol_povtorn_poset;

  39. suspend;
  40. end

  41. end
  42. ^

  43. Лучшие ссылки на сайт

  44. Хранимая процедура для получения лучших ссылок на сайт

  45. /***********************************************************************/
  46. /* Лучшая ссылка на наш сайт */
  47. /***********************************************************************/
  48. create procedure best_link
  49. (projid integer,
  50. dateot date,
  51. datedo date
  52. )
  53. returns (
  54. urlfrom varchar(1024),
  55. count_urls integer
  56. )
  57. as
  58. begin
  59. for select urlfrom, count(*) count_urls
  60. from countdata
  61. where (projid=:projid)
  62. and(datehint>=:dateot)
  63. and(datehint< =:datedo)
  64. group by urlfrom
  65. into :urlfrom, :count_urls
  66. do
  67. begin
  68. suspend;
  69. end
  70. end
  71. ^

  72. Лучшая интернет-страница

  73. Хранимая процедура для получения статистики по посещаемости наших страниц:

  74. /***********************************************************************/
  75. /* Лучшая наша страничка */
  76. /***********************************************************************/
  77. create procedure best_page
  78. (projid integer,
  79. dateot date,
  80. datedo date
  81. )
  82. returns (
  83. urlcurr varchar(1024),
  84. count_urls integer
  85. )
  86. as
  87. begin
  88. for select urlcurr, count(*) count_urls
  89. from countdata
  90. where (projid=:projid)
  91. and(datehint>=:dateot)
  92. and(datehint< =:datedo)
  93. group by urlcurr
  94. into :urlcurr, :count_urls
  95. do
  96. begin
  97. suspend;
  98. end
  99. end
  100. ^

На нашем сервере (код на php)

Прежде всего, необходимо настроить apache на нашем сервере. Как его устанавливать и настраивать Вы можете во многочисленных статьях интернета.

Скрипт для подключения к нашей базе данных interbase, передачи информации о пользователе и получения статистической информации.

acounter.php

HTML
Текст

  1. < ?php
  2. /*include("config.php");*/
  3. include "classdb.php3";
  4. class acounter {
  5. var $config = array();
  6. var $conn;
  7. var $dbname;
  8. var $dbuser;
  9. var $dbpass;
  10. var $number_zagruzk;
  11. var $number_un_zagruzk;
  12. var $number_zagr_date;
  13. var $number_zagr_un_date;
  14. var $mindate;
  15. var $okrugl;

  16. function acounter () {

  17. /*Подключение к БД*/
  18. include "config.php";
  19. $this->okrugl = $okrugl;
  20. $this->dbname = $dbname;
  21. $this->dbuser = $dbuser;
  22. $this->dbpass = $dbpass;
  23. $this->conn=ibase_connect($this->dbname,$this->dbuser,$this->dbpass);

  24. /* url to the digitset */
  25. $this->config['img'] = "http://mysite.com.ua/mycounter/digits/";

  26. /* url to the animated digitset */
  27. $this->config['animated_img'] = "http://mysite.com.ua/mycounter/digits_ani/";

  28. /* how many digits to show */
  29. $this->config['pad'] = 6;

  30. /* digit width and height */
  31. $this->config['width'] = 16;
  32. $this->config['height'] = 22;

  33. /* timeout (minutes) */
  34. $this->config['block_time'] = 15;
  35. }

  36. //Получает количество записей в таблице countdata(количество посещений)
  37. function ibase_fetch_array($res) {
  38. return get_object_vars(ibase_fetch_object($res));
  39. }

  40. function ibase_num_rows($query) {
  41. $i=0;
  42. while (ibase_fetch_row($query)){
  43. $i++;}
  44. return $i;
  45. }

  46. function getcountervalue() {
  47. $sqlexpr="select * from countdata";
  48. $sth = ibase_query($this->conn,$sqlexpr);
  49. $countervalue=$this->ibase_num_rows($sth);
  50. return $countervalue;
  51. }
  52. //
  53. function insertdata($ip='',$urlfrom='',$urlcurr='',$host='') {
  54. //beru vid brausera, versiu brauzera, platformu mashini;
  55. $info=getenv("http_user_agent");
  56. // $urlfrom=getenv("http_referer");
  57. $gateway=getenv("gateway_interface");
  58. $connect=getenv("server_protocol");
  59. //beru ip-adres;
  60. // $ip = getenv("remote_addr");

  61. $db = new cconnectionibase();
  62. $sqlexpr="select * from proc_count_data(1, '".$urlfrom."', '".$urlcurr."', '".$ip."', '', '".$info."', '','".$host."')";

  63. $sth = ibase_query($this->conn,$sqlexpr);
  64. $mas=$this->ibase_fetch_array($sth);
  65. $this->number_zagruzk = $mas[number_zagruzk];
  66. $this->number_un_zagruzk = $mas[number_un_zagruzk];
  67. $this->number_zagr_date = $mas[number_zagr_date];
  68. $this->number_zagr_un_date = $mas[number_zagr_un_date];
  69. $this->mindate = $mas[mindate];
  70. }

  71. function create_output($ip='',$urlfrom='',$urlcurr='',$host='') {
  72. $this->insertdata($ip,$urlfrom,$urlcurr,$host);
  73. //vivogu col. zagruzok

  74. $html_output = "< table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">< tr>n";
  75. $html_output .="< font size='1' color='#0000ff'>Всего загрузок:< /font>< /tr>n< tr align=\"center\">n";
  76. $html_output .= "< font size='3' color='#800080'>< b>".sprintf($this->okrugl,$this->number_zagruzk)."< /b>< /font>";
  77. $html_output .= "< /tr>< /table>n";
  78. //vivogu col. unikalnih zagruzok

  79. $html_output .= "< table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">< tr>n";
  80. $html_output .="< font size='1' color='#0000ff'>Всего уникальных загрузок:< /font>< /tr>n< tr align=\"center\">n";
  81. $html_output .= "< font size='3' color='#800080'>< b>".sprintf($this->okrugl,$this->number_un_zagruzk)."< /b>< /font>";
  82. $html_output .= "< /tr>< /table>n";
  83. //vivogu col. zagruzok segodnia

  84. $html_output .= "< table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">< tr>n";
  85. $html_output .="< font size='1' color='#0000ff'>Загрузок за день:< /font>< /tr>n< tr align=\"center\">n";
  86. $html_output .= "< font size='3' color='#800080'>< b>".sprintf($this->okrugl,$this->number_zagr_date)."< /b>< /font>";
  87. $html_output .= "< /tr>< /table>n";

  88. //vivogu col. unikalnih zagruzok segodnia

  89. $html_output .= "< table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">< tr>n";
  90. $html_output .="< font size='1' color='#0000ff'>Уникальных загрузок за день:< /font>< /tr>n< tr align=\"center\">n";
  91. $html_output .= "< p align='center'>< font size='3' color='#800080'>< b>".sprintf($this->okrugl,$this->number_zagr_un_date)."< /b>< /font>< /p>";
  92. $html_output .= "< /tr>< /table>n";

  93. //vivogu datu ustanovki schetchika
  94. $html_output .= "< table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">< tr>n";
  95. $html_output .="< font size='1' color='#0000ff'>Дата установки счётчика:< /font>< /tr>n< tr align=\"center\">n";
  96. $str=substr($this->mindate,0,10);
  97. $html_output .= "< font size='1' color='#800080'>".$str."< /font>";
  98. $html_output .= "< /tr>< /table>n";

  99. return $html_output;
  100. }

  101. }

  102. ?>

classdb.php3

HTML
Текст

  1. < ?php
  2. //---------------------------------------------------------------------------------------------
  3. class cconnection {
  4. var $err_logon = "can't connect to database %s!";

  5. var $descriptor = 0; // database descriptor
  6. var $result; // result array
  7. var $countrow = 0; // number of records in result array
  8. var $countfield = 0; // number of fields in result array

  9. // clears result array. for internal use.
  10. function freequery() {
  11. unset($this->result);
  12. $this->countrow = 0;
  13. $this->countfield = 0;
  14. }

  15. // returns content of specified cell of result array or null if $col or $row is wrong.
  16. // $col can to hold the field name or field index
  17. function getdata($col, $row) {
  18. if ((0 < = $row) &#038;& ($row <  $this->countrow)) {
  19. if (!is_string($col)) {
  20. reset($this->result);
  21. for ($fno = 0; $fno < $col; $fno++) next($this->result);
  22. $col = current($this->result);
  23. return $col[$row];
  24. } else return $this->result[strtoupper($col)][$row];
  25. } else return null;
  26. }

  27. // returns field name by field index or empty string if $col is wrong
  28. function getfieldname($col) {
  29. if (is_integer($col) &#038;& (0 < = $col) &#038;& ($col <  $this->countfield)) {
  30. reset($this->result);
  31. for ($fno = 0; $fno < $col; $fno++) next($this->result);
  32. list($key, $val) = each($this->result);
  33. return $key;
  34. } else return "";
  35. }
  36. }

  37. //---------------------------------------------------------------------------------------------
  38. class cconnectionibase extends cconnection {
  39. // constructor. creates class.
  40. function cconnectionibase() {}

  41. // opens specified database.
  42. // returns database descriptor.
  43. function open($database, $username = "sysdba", $password = "masterkey", $charset="win1251") {
  44. $this->close();
  45. $this->descriptor = ibase_connect($database, $username, $password, $charset);
  46. return $this->descriptor;
  47. }

  48. // closes current database connection
  49. function close() {
  50. if ($this->descriptor) {
  51. $this->freequery();
  52. ibase_close($this->descriptor);
  53. $this->descriptor = 0;
  54. }
  55. }

  56. // prepares data to storing in blobs. used in query &#038; execute functions
  57. // returns query statement descriptor
  58. function execcode($code, $blobs=0) {
  59. $statement = 0;
  60. $this->freequery();
  61. if ($this->descriptor) {
  62. $cmd = "$"."statement = ibase_query("."$"."this->descriptor, "."$"."code";
  63. if (is_array($blobs) &#038;& count($blobs)) {
  64. reset($blobs);
  65. $fno = 0;
  66. while (list($key, $val) = each($blobs)) {
  67. $finfo[$fno] = array("blob_id" => ibase_blob_create(), "blob_str" => "");
  68. if (is_string($val)) ibase_blob_add($finfo[$fno]["blob_id"], $val);
  69. else ibase_blob_add($finfo[$fno]["blob_id"], "not supported yet, sorry");
  70. $finfo[$fno]["blob_str"] = ibase_blob_close($finfo[$fno]["blob_id"]);
  71. $cmd = $cmd.", $"."finfo[$fno][\"blob_str\"]";
  72. $fno++;
  73. }
  74. }
  75. $cmd = $cmd.");";
  76. eval($cmd);
  77. }
  78. return $statement;
  79. }

  80. // executes select statement and fills result array by dataset contents
  81. // returns number of records placed to result array
  82. function query($code, $blobs=0) {
  83. if ($statement = $this->execcode($code, $blobs)) {
  84. while ($row = ibase_fetch_row($statement)) {
  85. while(list($fno, $val) = each($row)) {
  86. // getting information about fields existing in current row
  87. if ($this->countfield < count($row)) $this->countfield = count($row);
  88. $finfo = ibase_field_info($statement, $fno);
  89. $fname = $finfo["alias"];
  90. $ftype = $finfo["type"];
  91. unset($finfo);

  92. if (!strcmp($ftype, "blob")) {
  93. // getting data from blob field
  94. if (($finfo = ibase_blob_info($val)) &#038;&
  95. ($finfo["length"] > 0) &#038;&
  96. ($val = ibase_blob_open($val))) {
  97. $blob = ibase_blob_get($val, $finfo["length"]);
  98. ibase_blob_close($val);
  99. } else $blob = "";
  100. $this->result[$fname][$this->countrow] = $blob;
  101. unset($blob);
  102. } else {
  103. // getting data from another field
  104. if (isset($val)) {
  105. if (is_string($val))
  106. $this->result[$fname][$this->countrow] = trim($val);
  107. else $this->result[$fname][$this->countrow] = $val;
  108. } else $this->result[$fname][$this->countrow] = "";
  109. }
  110. }
  111. $this->countrow++;
  112. // cleaning temporary variables
  113. unset($row);
  114. unset($fno);
  115. unset($val);
  116. unset($finfo);
  117. unset($fname);
  118. unset($ftype);
  119. }
  120. ibase_free_result($statement);
  121. unset($statement);
  122. }
  123. return $this->countrow;
  124. }

  125. // executes insert, delete or update statements. result array is empty.
  126. // returns nonzero if all ok
  127. function execute($code, $blobs=0) {
  128. if ($statement = $this->execcode($code, $blobs)) {
  129. @ibase_free_result($statement);
  130. return 1;
  131. }
  132. return 0;
  133. }

  134. // commits current transaction
  135. function commit() { ibase_commit(); }

  136. // rollbacks current transaction
  137. function rollback() { ibase_rollback(); }
  138. }

  139. //---------------------------------------------------------------------------------------------
  140. class cconnectionoci extends cconnection {
  141. function cconnectionoci() {}

  142. function open($database = "", $username = "system", $password = "manager") {
  143. $this->close();
  144. if (($database) &#038;& strlen($database))
  145. $this->descriptor = ocilogon($username, $password, $database);
  146. else $this->descriptor = ocilogon($username, $password);
  147. return $this->descriptor;
  148. }

  149. function close() {
  150. if ($this->descriptor) {
  151. $this->freequery();
  152. ocilogoff($this->descriptor);
  153. $this->descriptor = 0;
  154. }
  155. }

  156. function query($code) {
  157. $this->freequery();
  158. if ($this->descriptor) {
  159. if ($code &#038;& ($statement = ociparse($this->descriptor, $code))) {
  160. ociexecute($statement, oci_default);
  161. $this->countrow = ocifetchstatement($statement, $this->result);
  162. $this->countfield = count($this->result);
  163. ocifreestatement($statement);
  164. }
  165. }
  166. return $this->countrow;
  167. }

  168. function execute($code, $blob=0) {
  169. $res = 0;
  170. $this->freequery();
  171. if ($this->descriptor) {
  172. if ($code) {
  173. if ($blob) $lob = ocinewdescriptor($this->descriptor, oci_d_lob);
  174. if ($statement = ociparse($this->descriptor, $code)) {
  175. if ($blob) ocibindbyname($statement, ":blob", &#038;$lob, -1, oci_b_clob);
  176. ociexecute($statement, oci_default);
  177. if ($lob) {
  178. if ($lob->save($blob)) $res = 1;
  179. ocifreedescriptor($lob);
  180. } else $res = 1;
  181. ocifreestatement($statement);
  182. }
  183. }
  184. }
  185. return $res;
  186. }

  187. function commit() {
  188. if ($this->descriptor) ocicommit($this->descriptor);
  189. }

  190. function rollback() {
  191. if ($this->descriptor) ocirollback($this->descriptor);
  192. }
  193. }

  194. //---------------------------------------------------------------------------------------------
  195. ?>

Файл для конфигурирования счётчика:

config.php

HTML
Текст

  1. < ?

  2. $dbname = "server:c:databasecounter.gdb";
  3. $dbuser = "sysdba";
  4. $dbpass = "masterkey";
  5. $okrugl = "%07s";
  6. ?>

  7. $dbname название базы данных,
  8. $dbuser- имя пользователя interbase,
  9. $dbpass пароль,
  10. $okrugl количество цифр в счётчики (например, 0000012).
  11. Файл, который вызывается из интернет-страницы:

test.php

HTML
Текст

  1. < ?php
  2. include_once "acounter.php";
  3. $ani_counter = new acounter();
  4. echo $ani_counter->create_output($_get["ip"],$_get["urlfrom"],$_get["urlcurr"],$_get["host"]);

  5. ?>

На интернет-странице (код на php)
Эта часть находится на сервере провайдера (там, где находится наша интернет-страница).

Создаём скрипт для определения данных о пользователе:

counter.inc

HTML
Текст

  1. < ?php

  2. // phpinfo();
  3. //beru vid brausera, versiu brauzera, platformu mashini;

  4. $info=getenv("http_user_agent");
  5. $urlfrom=getenv("http_referer");
  6. $urlcurr=$_server["request_uri"];
  7. $host=getenv("http_host");
  8. //beru ip-adres;
  9. $ip = getenv("remote_addr");
  10. readfile('http://client70.ukrtelebud.com.ua/rudjukcounter/test.php?ip='.$ip.'&#038;urlfrom='.$urlfrom.'&#038;urlcurr='.$urlcurr.'&#038;host='.$host);

  11. // readfile('http://mysite.com.ua/mycounter/test.php?ip='.$ip.'&#038;urlfrom='.$urlfrom);
  12. // readfile('http://mysite.com.ua/mycounter/test.php')

  13. ?>

На самой интернет-странице прописываем скрипт, который и будет запускать весь счётчик:

HTML
Текст

  1. < ?php
  2. include ("counter_inc.php")
  3. ?>

Примечание: Для того, чтобы счётчик работал корректно необходимо файлы интернет-страницы называть с расширением php, а не htm.

Клиентская часть
Саму обработку статистических данных удобнее всего сделать на delphi.

Реализацию на delphi я оставляю читателю, приведу лишь sql-запросы для получения необходимых данных.

HTML
Текст

  1. sql-запросы

  2. Получение подробной информации о посетителях:

  3. select *
  4. from countdata
  5. where (projid=:projid)
  6. and(datehint>=:dateot)
  7. and(datehint< =:datedo)
  8. order by countdataid

  9. Статистика по дням:

  10. select *
  11. from stat_day(:projid, :dateot, :datedo) order by date_posetit

  12. Лучшие ссылки на интернет-страницу:

  13. select *
  14. from best_link(:projid, :dateot, :datedo)
  15. order by count_urls desc

  16. Лучшие интернет-страницы:

  17. select *
  18. from best_page(:projid, :dateot, :datedo) order by count_urls desc

  19. Уникальные ip-адреса:

  20. select *
  21. from iptable
  22. where (projid=:projid)
  23. and(dateadd>=:dateot)
  24. and(dateadd< =:datedo)

  25. ip-адреса повторных посетителей:

  26. select *
  27. from povtor_posetit(:projid, :dateot, :datedo) order by ipuser

Заключение
В программе есть ряд неточностей, а так же не определяются страны по ip-адресу. Эти задачи я оставляю за читателями.



Постоянные ссылки

При копировании ссылка на TeaM RSN обязательна!

URI

Html (ЖЖ)

BB-код (Для форумов)

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.