Інформація про нас Розроблені нами програми Наші інтернет-розробки Фотогалерея наших робіт Документація до програм, наші статті, а також перезентації наших програм

Вийшла нова версія програми "Склад".


 Виправлено велику кількість помилок.


 Можливість вимкнення заборони негативних чистилів у поточних залишках.


Наші координати

Ел. пошта
rs@corp2.net

Телефон: +38 (067) 901-63-22

Зателефонуйте: +380 63 108 17 00

Напишіть у Telegram: @erpk2

 

Виклик форуму

Динамічна інтернет-сторінка

 


 

Інші посилання


Інші сторінки

Програми
Корпорація

Склад
Корпорація
Бухгалтерія
Зарплата


Програми
Іспит
Розрахунок шаф
Реплікатор
Редактор
VDoc
Календар
Калькулятор
Буфер
Розсилка пошти
Голосування по мережі
Інсталятор
Планувальник
Адміністратор порталу
R-броузер

Документація
Відповіді на запитання
Вся документація
Склад
Розрахунок шаф
Іспит
Реплікатор
Інсталятор

Докумнтація складу
Встановлення програми

Вступ
Введення залишків
Замовлення (купівля)
Заявка
Зовнішній рахунок-фактура
Прихід товару складу
Витрата товару зі складу
Податкова накладна
Внутрішнє переміщення
Списання товару
Повернення товару
Замовлення на закупівлю
Реалізація та консигнація
Відстрочка платежу
Резервування товарів
Рахунок-фактура без рез.
Копіювання документів
Журнали документів
Платіжні документи
Забірний лист
Картка продукції
Калькуляція
Відбраковування товарів
Переоцінка товарів
Бронювання послуг
Анулювання послуг
Рахунок
Журнали документів


Довідник фірм
Довідник активів
Технологічні карти
Прайс-листи
Одиниці виміру
Норми витрати
Місце розташування товару
План рахунків
Сервісні центри
Співробітники
Курси валют
Системні довідники
Фрази

Поточні залишки
Звіт з внутрішнього переміщення
Звіт з продажу
Взаєморозрахунки
Рух матеріалів

Пошук інформації
Штрих-коди, шифри, партії

Об'єднання фірм
Об'єднання товарів
Робота в мережі та інтернет
Визначення прав
Створення та налаштування користувача
Скрипт налаштування користувача
Налаштування фірми
Налаштування складів
Налаштування мов
Типи документів
Налаштування меню
Версії програм та історія
Перевірка розрахунків
Створення та зміна звітів
Створення тіні (дзеркала) бази даних
Відновлення бази даних
Резервне копіювання бази даних

Інформація про програму
Робота з вікнами
Робота з таблицями
Експорт даних у таблицях
Імпорт даних у таблицях
Робота з деревами
Експорт із дизайнера звітів
Опис дизайнера звітів FastReport

Статті
Лічильник
Як заощадити на ліцензіях
Відновлення баз даних Interbase

Послуги
Веб-дизайн
Купівля програм

Інше
Фотогалерея


 

 


Вийшла нова версія програми "Корпорація" (ROffice).

 

 

Переглянути всі новини

 

 

 

 

 








Корпоративний інтернет-лічильник

 

Анотація

 

У цій статті розповідається як створити інтернет-лічильник для корпоративного порталу.

 

Завдання

Лічильник повинен вести докладну інформацію про відвідувачів: адреса, звідки прийшов відвідувач, адреса сторінки, IP-адреса відвідувача, дата, браузер користувача, операційна система.

За IP-адресою можна визначити країну та регіон, звідки прийшов відвідувач.

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

Схема виконання

Для початку розглянемо схему виконання лічильника.

Схема

1.                          Користувач з Інтернету (Користувач1, Користувач2, Користувач3) заходить на нашу інтернет-сторінку, розташовану на сервері провайдера.

2.                          На інтернет-сторінці виконується код на PHP, який визначає IP-адресу користувача, URL звідки прийшов, URL сторінки, браузер та операційну систему користувача. Ці дані програма передає на корпоративний інтернет-сервер.

3.                          На корпоративному інтернет-сервері викликається процедура InterBase, що зберігається, для передачі даних про користувача та отримання статистичної інформації для інтернет-сторінки.

4.                          Статистично дані передаються до програми на Інтернет-сторінці та виводяться для відвідувача.

Згодом адміністратор підключається до Interbase-сервера за допомогою клієнтської програми (написаної на Delphi) і обробляє інформацію.

 

Примітка: Корпоративний сервер та InterBase-сервер можна поєднати, але тоді зменшується рівень захисту інформації. Оскільки знаючи пароль та ім'я користувача можна буде підключитися до бази даних з Інтернету.

Структура бази даних

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

Структура бази даних

Таблиця Project призначена для зберігання назви проекту. Таким чином, ми можемо створювати скільки завгодно лічильників.

У таблиці CountData накопичується інформація про відвідувачів:

URLFrom - Звідки прийшов відвідувач,

URLCurr – яку сторінку відвідали,

DateHint – дата (без часу) коли відвідали,

FullDate – повна дата,

IPUser – IP-адреса відвідувача,

Browser – браузер,

SystemUser - операційна система користувача,

SystemVer – версія операційної системи,

CompName – назва комп'ютера відвідувача.

У таблиці IPTable зберігаються адреси унікальних IP-адрес.

Скрипт бази даних

Згенеруємо скрипт бази даних за цією структурою:

CREATE TABLE CountData (

CountDataID INTEGER NOT NULL,

ProjID INTEGER,

URLFrom VARCHAR(1024),

URLCurr VARCHAR(1024),

DateHint DATE,

FullDate DATE,

IPUser VARCHAR(15),

Browser VARCHAR(255),

SystemUser VARCHAR(255),

SystemVer VARCHAR(255)

);

CREATE INDEX IF318CountData ON CountData

(

ProjID

);

CREATE INDEX ak_IP ON CountData

(

IPUser

);

CREATE INDEX ak_DateHint ON CountData

(

DateHint

);

ALTER TABLE CountData

ADD CONSTRAINT PKCountData PRIMARY KEY (CountDataID);

CREATE TABLE IPTable (

IPUser VARCHAR(15) NOT NULL,

DateAdd DATE

);

CREATE INDEX akDateAdd ON IPTable

(

DateAdd

);

 

ALTER TABLE IPTable

ADD CONSTRAINT PKIPTable PRIMARY KEY (IPUser);

 

CREATE TABLE Project (

ProjID INTEGER NOT NULL,

ProjName VARCHAR(255),

Comment BLOB SUB_TYPE 1

);

 

ALTER TABLE Project

ADD CONSTRAINT PKProject PRIMARY KEY (ProjID);

 

ALTER TABLE CountData

ADD CONSTRAINT Project_CountData

FOREIGN KEY (ProjID)

REFERENCES Project;

 

CREATE EXCEPTION ERWIN_PARENT_INSERT_RESTRICT "Cannot INSERT Parent table because Child table exists.";

CREATE EXCEPTION ERWIN_PARENT_UPDATE_RESTRICT "Cannot UPDATE Parent table because Child table exists.";

CREATE EXCEPTION ERWIN_PARENT_DELETE_RESTRICT "Cannot DELETE Parent table because Child table exists.";

CREATE EXCEPTION ERWIN_CHILD_INSERT_RESTRICT "Cannot INSERT Child table because Parent table does not exist.";

CREATE EXCEPTION ERWIN_CHILD_UPDATE_RESTRICT "Cannot UPDATE Child table because Parent table does not exist.";

CREATE EXCEPTION ERWIN_CHILD_DELETE_RESTRICT "Cannot DELETE Child table because Parent table does not exist.";

 

SET TERM ^;

 

CREATE TRIGGER tI_CountData FOR CountData AFTER INSERT AS

DECLARE VARIABLE numrows INTEGER;

BEGIN

select count(*)

from Project

where

NEW.ProjID = Project.ProjID into numrows;

IF (

NEW.ProjID is not null and

numrows = 0

) THEN

BEGIN

EXCEPTION ERWIN_CHILD_INSERT_RESTRICT;

END

 

END ^

 

CREATE TRIGGER tU_CountData FOR CountData AFTER UPDATE AS

DECLARE VARIABLE numrows INTEGER;

BEGIN

select count(*)

from Project

where

NEW.ProjID = Project.ProjID into numrows;

IF (

NEW.ProjID is not null and

numrows = 0

) THEN

BEGIN

EXCEPTION ERWIN_CHILD_UPDATE_RESTRICT;

END

 

END ^

 

CREATE TRIGGER tD_Project FOR Project AFTER DELETE AS

DECLARE VARIABLE numrows INTEGER;

BEGIN

select count(*)

from CountData

where

CountData.ProjID = OLD.ProjID into numrows;

IF (numrows > 0) THEN

BEGIN

EXCEPTION ERWIN_PARENT_DELETE_RESTRICT;

END

 

END ^

 

CREATE TRIGGER tU_Project FOR Project AFTER UPDATE AS

DECLARE VARIABLE numrows INTEGER;

BEGIN

IF

(OLD.ProjID <> NEW.ProjID) THEN

BEGIN

update CountData

set

CountData.ProjID = NEW.ProjID

where

CountData.ProjID = OLD.ProjID;

END

 

END ^

Тригера та процедури, що зберігаються

Унікальні IP-адреси

Унікальні IP-адреси будуть автоматично фіксуватися базою даних. Для цього ми напишемо кілька тригерів.

Тригер вставки унікальних IP-адрес:

CREATE TRIGGER RTI_COUNTDATA FOR COUNTDATA BEFORE INSERT POSITION 0 AS

DECLARE VARIABLE CNT INTEGER;

BEGIN

NEW.COUNTDATAID=GEN_ID(GCountDataID,1);

NEW.DATEHINT="TODAY";

NEW.FULLDATE="NOW";

SELECT COUNT(*)

FROM IPTABLE

WHERE (IPUSER=NEW.IPUSER)

AND(PROJID=NEW.PROJID)

INTO CNT;

IF (CNT=0) THEN

INSERT INTO IPTABLE (IPUSER, PROJID)

VALUES (NEW.IPUSER, NEW.PROJID);

END

^

Тригер заповнення дати унікальної IP-адреси:

CREATE TRIGGER RTI_IPTABLE FOR IPTABLE BEFORE INSERT POSITION 0 AS

BEGIN

NEW.DATEADD="TODAY";

END

Реєстрація користувача у базі даних

Тепер створимо процедуру, що зберігається, для реєстрації користувача в базі даних і отримання статистичної інформації про відвідування.

/*********************************************/

/* Процедура реєстрації відвідувача інтернет-сторінки */

/*********************************************/

CREATE PROCEDURE PROC_COUNT_DATA

(PROJID INTEGER,

URLFROM VARCHAR(1024),

URLCURR VARCHAR(1024),

IPUSER VARCHAR(15),

BROWSER VARCHAR(255),

SYSTEMUSER VARCHAR(255),

SYSTEMVER VARCHAR(255),

COMPNAME VARCHAR(255)

)

RETURNS (

MINDATE DATE, /* Дата встановлення лічильника */

NUMBER_ZAGRUZK INTEGER, /* Кількість завантажень */

NUMBER_UN_ZAGRUZK INTEGER, /* Кількість унікальних завантажень */

NUMBER_ZAGR_DATE INTEGER, /* Кількість завантажень сьогодні */

NUMBER_ZAGR_UN_DATE INTEGER) /* Кількість унікальних завантажень */

AS

BEGIN

INSERT INTO COUNTDATA (PROJID, URLFROM, URLCURR, IPUSER,

BROWSER, SYSTEMUSER, SYSTEMVER, COMPNAME)

VALUES (:PROJID, :URLFROM, :URLCURR, :IPUSER,

:BROWSER, :SYSTEMUSER, :SYSTEMVER, :COMPNAME);

/* Час встановлення лічильника */

SELECT MIN(DATEHINT)

FROM COUNTDATA

INTO :MINDATE;

IF (MINDATE IS NULL) THEN MINDATE="TODAY";

/* Кількість завантажень */

SELECT COUNT(*)

FROM COUNTDATA

INTO :NUMBER_ZAGRUZK;

/* Кількість унікальних завантажень */

SELECT COUNT(*)

FROM IPTABLE

INTO :NUMBER_UN_ZAGRUZK;

/* Кількість завантажень сьогодні */

SELECT COUNT(*)

FROM COUNTDATA

WHERE DATEHINT="TODAY"

INTO :NUMBER_ZAGR_DATE;

/* Кількість унікальних завантажень сьогодні */

SELECT COUNT(*)

FROM IPTABLE

WHERE DATEADD="TODAY"

INTO :NUMBER_ZAGR_UN_DATE;

SUSPEND;

END

^

Розшифруємо поля, що передаються процедурі:

PROJID – ID проекту (лічильника),

URLFROM – звідки прийшли,

URLCURR – куди прийшли,

IPUSER – IP-адреса користувача,

BROWSER - браузер,

SYSTEMUSER – операційна система користувача,

SYSTEMVER – версія операційної системи користувача,

COMPNAME – назва комп'ютера.

Процедура повертає статистичну інформацію:

MINDATE - дата встановлення лічильника,

NUMBER_ZAGRUZK INTEGER – загальна кількість завантажень,

NUMBER_UN_ZAGRUZK INTEGER – загальна кількість унікальних завантажень,

NUMBER_ZAGR_DATE INTEGER - кількість завантажень за сьогодні,

NUMBER_ZAGR_UN_DATE (INTEGER) - Кількість унікальних завантажень за сьогодні.

Отримання списку повторних відвідувачів

Збережена процедура для отримання списку повторних відвідувачів

/*****************************************/

/* Процедура для отримання повторних відвідувачів */

/*****************************************/

CREATE PROCEDURE POVTOR_POSETIT

(PROJID INTEGER,

DATEOT DATE,

DATEDO DATE

)

RETURNS (

IPUSER VARCHAR(15)

)

AS

BEGIN

FOR SELECT C.IPUSER

FROM COUNTDATA C

WHERE (C.DATEHINT>=:DATEOT)

AND(C.DATEHINT<=:DATEDO)

AND(C.PROJID>=:PROJID)

AND(C.IPUSER NOT IN (SELECT IT.IPUSER

FROM IPTABLE IT

WHERE (IT.DATEADD>=:DATEOT)

AND(IT.DATEADD<=:DATEDO)

AND(IT.PROJID=:PROJID)

))

GROUP BY C.IPUSER

INTO :IPUSER

DO

BEGIN

SUSPEND;

END

END

^

Процедурі ми передаємо діапазон, за який хочемо подивитися статистику, а вона повертає IP-адреси користувачів, які повторно відвідали наш сайт.

Статистика відвідувань днями

Зберігається процедура для розрахунку статистики відвідувань днями:

/*****************************************/

/* Статистика відвідувань днями */

/*****************************************/

CREATE PROCEDURE STAT_DAY

(PROJID INTEGER,

DATEOT DATE,

DATEDO DATE

)

RETURNS (

DATE_POSETIT DATE, /* Дата відвідування */

KOL_POSESCH INTEGER,/* Кількість відвідувань */

KOL_UNIKALN INTEGER, /* Кількість унікальних завантажень */

KOL_POVTORN_POSET INTEGER /* Кількість відвідувачів повторно */

)

AS

BEGIN

FOR SELECT DATEHINT

FROM COUNTDATA

WHERE (PROJID=:PROJID)

AND(DATEHINT>=:DATEOT)

AND(DATEHINT<=:DATEDO)

GROUP BY DATEHINT

INTO :DATE_POSETIT

DO

BEGIN

/* Кількість завантажень */

SELECT COUNT(*)

FROM COUNTDATA

WHERE DATEHINT=:DATE_POSETIT

INTO :KOL_POSESCH;

/* Кількість унікальних завантажень */

SELECT COUNT(*)

FROM IPTABLE

WHERE DATEADD=:DATE_POSETIT

INTO :KOL_UNIKALN;

 

SELECT COUNT(*)

FROM POVTOR_POSETIT(:PROJID, :DATE_POSETIT, :DATE_POSETIT)

INTO KOL_POVTORN_POSET;

 

SUSPEND;

END

END

^

Найкращі посилання на сайт

Збережена процедура для отримання найкращих посилань на сайт

/**************************************/

/* Краще посилання на наш сайт */

/**************************************/

CREATE PROCEDURE BEST_LINK

(PROJID INTEGER,

DATEOT DATE,

DATEDO DATE

)

RETURNS (

URLFROM VARCHAR(1024),

COUNT_URLS INTEGER

)

AS

BEGIN

FOR SELECT URLFROM, COUNT(*) COUNT_URLS

FROM COUNTDATA

where (PROJID=:PROJID)

And(DATEHINT>=:DateOt)

And(DATEHINT<=:DateDo)

GROUP BY URLFROM

INTO :URLFROM, :COUNT_URLS

DO

BEGIN

SUSPEND;

END

END

^

Найкраща інтернет-сторінка

Збережена процедура для отримання статистики відвідуваності наших сторінок:

/*************************************/

/* Краща наша сторінка */

/*************************************/

CREATE PROCEDURE BEST_PAGE

(PROJID INTEGER,

DATEOT DATE,

DATEDO DATE

)

RETURNS (

URLCURR VARCHAR(1024),

COUNT_URLS INTEGER

)

AS

BEGIN

FOR SELECT URLCURR, COUNT(*) COUNT_URLS

FROM COUNTDATA

where (PROJID=:PROJID)

And(DATEHINT>=:DateOt)

And(DATEHINT<=:DateDo)

GROUP BY URLCURR

INTO :URLCURR, :COUNT_URLS

DO

BEGIN

SUSPEND;

END

END

^

На нашому сервері
(код на PHP)

Насамперед, необхідно налаштувати Apache на нашому сервері. Як його встановлювати та налаштовувати Ви можете у численних статтях Інтернету.

Скрипт для підключення до нашої бази даних InterBase, передачі інформації про користувача та отримання статистичної інформації.

acounter.php

<?php

/*include("config.php");*/

include "classdb.php3";

class acounter {

var $config = array();

var $conn;

var $dbname;

var $dbuser;

var $dbpass;

var $NUMBER_ZAGRUZK;

var $NUMBER_UN_ZAGRUZK;

var $NUMBER_ZAGR_DATE;

var $NUMBER_ZAGR_UN_DATE;

var $MINDATE;

var $okrugl;

function acounter () {

/*Підключення до БД*/

include "config.php";

$this->okrugl = $okrugl;

$this->dbname = $dbname;

$this->dbuser = $dbuser;

$this->dbpass = $dbpass;

$this->conn=ibase_connect($this->dbname,$this->dbuser,

$this->dbpass);

/* URL to the digitset */

$this->config['img'] = "http://MySite.com.ua/MyCounter/digits/";

/* URL to the animated digitset */

$this->config['animated_img'] = "http://MySite.com.ua/MyCounter/digits_ani/";

/* How many digits to show */

$this->config['pad'] = 6;

/* digit width and height */

$this->config['width'] = 16;

$this->config['height'] = 22;

/* timeout (minutes) */

$this->config['block_time'] = 15;

}

//Отримує кількість записів у таблиці CountData(кількість відвідувань)

function ibase_fetch_array($res) {

return get_object_vars(ibase_fetch_object($res));

}

function ibase_num_rows($query) {

$i=0;

while (ibase_fetch_row($query)){

$i++;}

return $i;

}

 

function GetCounterValue() {

$sqlExpr="select * from CountData";

$sth = ibase_query($this->conn,$sqlExpr);

$CounterValue=$this->ibase_num_rows($sth);

return $CounterValue;

}

//

function InsertData($ip='',$urlFrom='',$urlCurr='',$host='') {

//Beru vid brausera, versiu brauzera, platformu mashini;

$info=getenv("HTTP_USER_AGENT");

// $urlFrom=getenv("HTTP_REFERER");

$Gateway=getenv("GATEWAY_INTERFACE");

$Connect=getenv("SERVER_PROTOCOL");

//Beru ip-adres;

// $ip = getenv("REMOTE_ADDR");

 

$db = new CConnectionIBase();

$sqlExpr="SELECT * FROM PROC_COUNT_DATA(1, '".$urlFrom."'

, '".$urlCurr."', '".$ip."', '', '".$info."', '','".$host."')";

 

$sth = ibase_query($this->conn,$sqlExpr);

$mas=$this->ibase_fetch_array($sth);

$this->NUMBER_ZAGRUZK = $mas[NUMBER_ZAGRUZK];

$this->NUMBER_UN_ZAGRUZK = $mas[NUMBER_UN_ZAGRUZK];

$this->NUMBER_ZAGR_DATE = $mas[NUMBER_ZAGR_DATE];

$this->NUMBER_ZAGR_UN_DATE = $mas[NUMBER_ZAGR_UN_DATE];

$this->MINDATE = $mas[MINDATE];

}

 

function create_output($ip='',$urlFrom='',$urlCurr='',$host='') {

$this->InsertData($ip,$urlFrom,$urlCurr,$host);

//Vivogu Col. zagruzok

 

$html_output = "<table cellpadding=\"0\" cellspacing=

\"0\" border=\"0\"><tr>\n";

$html_output .="<font size='1' color='#0000FF'>

Всього завантажень:</font></tr>\n<tr align=\"center\">\n";

$html_output .= "<font size='3' color='#800080'>

<b>".sprintf($this->okrugl,$this->NUMBER_ZAGRUZK)."</b></font>";

$html_output .= "</tr></table>\n";

//Vivogu col. unikalnih zagruzok

 

$html_output .= "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr>\n";

$html_output .="<font size='1' color='#0000FF'>

Усього унікальних завантажень: </font></tr>\n<tr align=\"center\">\n";

$html_output .= "<font size='3' color='#800080'>

<b>".sprintf($this->okrugl,$this->NUMBER_UN_ZAGRUZK).

"</b></font>";

$html_output .= "</tr></table>\n";

//Vivogu col. zagruzok segodnia

 

$html_output .= "<table cellpadding=\"0\"

cellspacing=\"0\" border=\"0\"><tr>\n";

$html_output .="<font size='1' color='#0000FF'>

Завантажень за день: </font></tr>\n<tr align=\"center\">\n";

$html_output .= "<font size='3' color='#800080'>

<b>".sprintf($this->okrugl,$this->NUMBER_ZAGR_DATE).

"</b></font>";

$html_output .= "</tr></table>\n";

//Vivogu col. unikalnih zagruzok segodnia

 

$html_output .= "<table cellpadding=\"0\"

cellspacing=\"0\" border=\"0\"><tr>\n";

$html_output .="<font size='1' color='#0000FF'>

Унікальних завантажень за день:</font></tr>\n

<tr align=\"center\">\n";

$html_output .= "<p align='center'><font size='3' color='#800080'><b>".sprintf($this->okrugl,$this

->NUMBER_ZAGR_UN_DATE)."</b></font></p>";

$html_output .= "</tr></table>\n";

 

//Vivogu datu ustanovki schetchika

$html_output .= "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr>\n";

$html_output .="<font size='1' color='#0000FF'>

Дата встановлення лічильника: </font></tr>\n<tr align=\"center\">\n";

$str=substr($this->MINDATE,0,10);

$html_output .= "<font size='1' color='#800080'>".$str."</font>";

$html_output .= "</tr></table>\n";

 

return $html_output;

}

 

}

 

?>

 

classdb.php3

 

<?php

//-------------------------------------------------------------

class CConnection {

var $err_logon = "Can't connect to database %s!";

 

var $descriptor = 0; // database descriptor

var $result; // result array

var $countRow = 0; // number of records in result array

var $countField = 0; // number of fields in result array

 

// Clears result array. For internal use.

function freeQuery() {

unset($this->result);

$this->countRow = 0;

$this->countField = 0;

}

 

// Returns content of specified cell of result array or null if $col or

// $row is wrong.

// $col can to hold the field name or field index

function getData($col, $row) {

if ((0 <= $row) && ($row < $this->countRow)) {

if (!is_string($col)) {

reset($this->result);

for ($fno = 0; $fno < $col; $fno++) next($this->result);

$col = current($this->result);

return $col[$row];

} else return $this->result[strtoupper($col)][$row];

} else return null;

}

 

// Returns field name by field index or empty string if $col is wrong

function getFieldName($col) {

if (is_integer($col) && (0 <= $col) && ($col < $this->countField)) {

reset($this->result);

for ($fno = 0; $fno < $col; $fno++) next($this->result);

list($key, $val) = each($this->result);

return $key;

} else return "";

}

}

 

//----------------------------------------------------------------------

class CConnectionIBase extends CConnection {

// Constructor. Creates class.

function CConnectionIBase() {}

 

// Opens specified database.

// Returns database descriptor.

function open($database, $username = "sysdba",

$password = "masterkey", $charset="WIN1251") {

$this->close();

$this->descriptor = ibase_connect($database,

$username, $password, $charset);

return $this->descriptor;

}

 

// Closes current database connection

function close() {

if ($this->descriptor) {

$this->freeQuery();

ibase_close($this->descriptor);

$this->descriptor = 0;

}

}

 

// Prepares data to storing in BLOBs. Used in query & execute functions

// Returns query statement descriptor

function execCode($code, $blobs=0) {

$statement = 0;

$this->freeQuery();

if ($this->descriptor) {

$cmd = "$"."statement = ibase_query("."$".

"this->descriptor, "."$"."code";

if (is_array($blobs) && count($blobs)) {

reset($blobs);

$fno = 0;

while (list($key, $val) = each($blobs)) {

$finfo[$fno] = array("blob_id" =>

ibase_blob_create(), "blob_str" => "");

if (is_string($val)) ibase_blob_add($finfo[$fno]["blob_id"], $val);

else ibase_blob_add($finfo[$fno]["blob_id"],

"Not supported yet, sorry");

$finfo[$fno]["blob_str"] = ibase_blob_close($finfo[$fno]["blob_id"]);

$cmd = $cmd.", $"."finfo[$fno][\"blob_str\"]";

$fno++;

}

}

$cmd = $cmd.");";

eval($cmd);

}

return $statement;

}

 

// Executes SELECT statement and fills result array by dataset contents

// Returns number of records placed to result array

function query($code, $blobs=0) {

if ($statement = $this->execCode($code, $blobs)) {

while ($row = ibase_fetch_row($statement)) {

while(list($fno, $val) = each($row)) {

// Getting information about fields existing in current row

if ($this->countField < count($row)) $this->countField = count($row);

$finfo = ibase_field_info($statement, $fno);

$fname = $finfo["alias"];

$ftype = $finfo["type"];

unset($finfo);

 

if (!strcmp($ftype, "BLOB")) {

// Getting data from BLOB field

if (($finfo = ibase_blob_info($val)) &&

($finfo["length"] > 0) &&

($val = ibase_blob_open($val))) {

$blob = ibase_blob_get($val, $finfo["length"]);

ibase_blob_close($val);

} else $blob = "";

$this->result[$fname][$this->countRow] = $blob;

unset($blob);

} else {

// Getting data from another field

if (isset($val)) {

if (is_string($val))

$this->result[$fname][$this->countRow] = trim($val);

else $this->result[$fname][$this->countRow] = $val;

} else $this->result[$fname][$this->countRow] = "";

}

}

$this->countRow++;

// Cleaning temporary variables

unset($row);

unset($fno);

unset($val);

unset($finfo);

unset($fname);

unset($ftype);

}

ibase_free_result($statement);

unset($statement);

}

return $this->countRow;

}

 

// Executes INSERT, DELETE or UPDATE statements. Result array is empty.

// Returns nonzero if all OK

function execute($code, $blobs=0) {

if ($statement = $this->execCode($code, $blobs)) {

@ibase_free_result($statement);

return 1;

}

return 0;

}

 

// Commits current transaction

function commit() { ibase_commit(); }

 

// Rollbacks current transaction

function rollback() { ibase_rollback(); }

}

 

//------------------------------------------------------------------

class CConnectionOCI extends CConnection {

function CConnectionOCI() {}

 

function open($database = "", $username = "system",

$password = "manager") {

$this->close();

if (($database) && strlen($database))

$this->descriptor = OCILogon($username, $password, $database);

else $this->descriptor = OCILogon($username, $password);

return $this->descriptor;

}

 

function close() {

if ($this->descriptor) {

$this->freeQuery();

OCILogOff($this->descriptor);

$this->descriptor = 0;

}

}

 

function query($code) {

$this->freeQuery();

if ($this->descriptor) {

if ($code && ($statement = OCIParse($this->descriptor, $code))) {

OCIExecute($statement, OCI_DEFAULT);

$this->countRow = OCIFetchStatement($statement, $this->result);

$this->countField = count($this->result);

OCIFreeStatement($statement);

}

}

return $this->countRow;

}

 

function execute($code, $blob=0) {

$res = 0;

$this->freeQuery();

if ($this->descriptor) {

if ($code) {

if ($blob) $lob = OCINewDescriptor($this->descriptor, OCI_D_LOB);

if ($statement = OCIParse($this->descriptor, $code)) {

if ($blob) OCIBindByName($statement, ":blob", &$lob, -1,

OCI_B_CLOB);

OCIExecute($statement, OCI_DEFAULT);

if ($lob) {

if ($lob->save($blob)) $res = 1;

OCIFreeDescriptor($lob);

} else $res = 1;

OCIFreeStatement($statement);

}

}

}

return $res;

}

 

function commit() {

if ($this->descriptor) OCICommit($this->descriptor);

}

 

function rollback() {

if ($this->descriptor) OCIRollback($this->descriptor);

}

}

 

//----------------------------------------------------------------------

?>

 

Файл конфігурації лічильника:

 

config.php

 

<?

 

$dbname = "Server:C:\DataBase\Counter.GDB";

$dbuser = "SYSDBA";

$dbpass = "masterkey";

$okrugl = "%07s";

?>

 

$dbname – назва бази даних,

$dbuser-ім'я користувача InterBase,

$dbpass - пароль,

$okrugl – кількість цифр у лічильники (наприклад, 0000012).

 

Файл, який викликається з веб-сторінки:

 

test.php

 

<?php

include_once "acounter.php";

$ani_counter = new acounter();

echo $ani_counter->create_output($_GET["ip"],$_GET["urlFrom"]

,$_GET["urlCurr"],$_GET["host"]);

?>

На інтернет-сторінці (код на PHP)

Ця частина знаходиться на сервері провайдера (там, де знаходиться наша веб-сторінка).

Створюємо скрипт для визначення даних про користувача:

 

Counter.inc

 

<?php

 

// phpinfo();

//Beru vid brausera, versiu brauzera, platformu mashini;

$info=getenv("HTTP_USER_AGENT");

$urlFrom=getenv("HTTP_REFERER");

$urlCurr=$_SERVER["REQUEST_URI"];

$host=getenv("HTTP_HOST");

//Beru ip-adres;

$ip = getenv("REMOTE_ADDR");

readfile('http://client70.ukrtelebud.com.ua/

RudjukCounter/test.php?ip='.

$ip.'&urlFrom='.$urlFrom.'&urlCurr='.$urlCurr.'&host='.$host);

 

// readfile('http://MySite.com.ua/MyCounter/test.php?ip='

.$ip.'&urlFrom='.$urlFrom);

// readfile('http://MySite.com.ua/MyCounter/test.php')

 

?>

 

На самій інтернет-сторінці прописуємо скрипт, який і запускатиме весь лічильник:

<?php

include ("counter_inc.php")

?>

 

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

Клієнтська частина

 

Саму обробку статистичних даних найзручніше зробити на Delphi.

Реалізацію на Delphi я залишаю читачеві, наведу лише SQL-запити отримання необхідних даних.

SQL-запити

 

Отримання детальної інформації про відвідувачів:

select *

from COUNTDATA

where (PROJID=:PROJID)

And(DATEHINT>=:DateOt)

And(DATEHINT<=:DateDo)

ORDER BY COUNTDATAID

 

 

Статистика днями:

SELECT *

FROM STAT_DAY(:ProjID, :DateOt, :DateDo) ORDER BY DATE_POSETIT

 

Найкращі посилання на інтернет-сторінку:

SELECT *

FROM BEST_LINK(:ProjID, :DateOt, :DateDo)

ORDER BY COUNT_URLS DESC

 

Найкращі інтернет-сторінки:

SELECT *

FROM BEST_PAGE(:ProjID, :DateOt, :DateDo) ORDER BY COUNT_URLS DESC

 

Унікальні IP-адреси:

select *

from IPTable

where (ProjID=:ProjID)

And(DateAdd>=:DateOt)

And(DateAdd<=:DateDo)

 

IP-адреси повторних відвідувачів:

SELECT *

FROM POVTOR_POSETIT(:ProjID, :DateOt, :DateDo) ORDER BY IPUSER

Ось що вийшло

Отримання детальної інформації про відвідувачів:

Детальна інформація про відвідувачів

Статистика днями:

Статистика днями

Найкращі посилання:

Найкращі посилання

Найкращі сторінки:

Найкращі сторінки

Унікальні IP-адреси:

Унікальні IP-адреси

Повторні IP-адреси:

Повторні IP-адреси

 

Висновок

У програмі є ряд неточностей, а так само не визначаються країни щодо IP-адресою. Ці завдання я залишаю за читачами.

Завантажити текст Php-програм та SQL-скрипти Ви можете на http://old.rudjuk.kiev.ua/downloads/InetCounter/InetCounter.exe

 

Автори: Рудюк С.А
Лутай Д.А.