Navigace

Hlavní menu

 

Submenu

 

Statistika přístupů v PHP – odkud přicházejí návštěvníci

Dnes nebudeme lovit technické informace o počítačích našich návštěvníků, místo toho si povíme jak zjistit, ze kterých stránek k nám přišli.

Hotovou aplikaci si můžete prohlédnout a vyzkoušet. V ukázkové verzi se provádí statistika přístupů stránek www.czechia.cz/help.

Ke zjištění odkud k nám přicházejí návštěvníci využijeme HTTP hlavičku Referer, která obsahuje URL stránky, z níž uživatel přišel na aktuální stránku. V PHP je obsah této hlavičky v proměnné $HTTP_REFERER. Musíme si však uvědomit, že počítadlo vkládáme do stránek jako obrázek, tudíž proměnná $HTTP_REFERER neobsahuje URL stránky, ze které uživatel přišel, nýbrž URL aktuální stránky.

Jak bylo naznačeno již v minulém díle, musíme použít JavaScript a obrázek (counter.php) volat s několika parametry. Parametr referer bude obsahovat URL stránky, ze které uživatel přišel na stránku s naším javaskriptem. Tuto hodnotu, která se nachází v top.document.referrer, musíme pomocí funkce escape() zakódovat tak, aby byla použitelná v URL. JavaScriptová funkce escape() pracuje obdobně jako PHP funkce URLEncode(). O dalších parametrech již byla řeč v minulém článku.

<script language="JavaScript" type="text/javascript">
<!--
document.write("<img src=\"__vas_server__/counter.php?referer=" + escape(top.document.referrer) + "&screenres=" + screen.width + "x" + screen.height + "&colordepth=" + screen.colorDepth + "\" width=\"1\" height=\"1\" alt=\"\">");
// -->
</script>

Tabulka referer

Do tabulky referer budeme ukládat stránky (servery), ze kterých k nám přicházejí návštěvníci. Tabulku vytvoříme pomocí tohoto SQL dotazu:

CREATE TABLE referer (
    id int(11) NOT NULL auto_increment,
    server varchar(50),
    PRIMARY KEY (id)
);

  • id - unikátní označení každého serveru (primární klíč)
  • server - adresa serveru, ze kterého přicházejí

Do tabulky vložíme i dva základní záznamy, o kterých se za chvíli zmíním:

INSERT INTO referer VALUES (1, 'Přímé volání');
INSERT INTO referer VALUES (2, 'Přechod v rámci serveru');

URL stránky, ze které uživatel přišel ($referer), musíme nejprve zpětně pomocí funkce URLDecode() dekódovat a převést na malá písmena, aby se v databázi neobjevovaly stejné stránky, lišící se pouze velikostí písmen v URL.

Ne vždy přichází návštěvník z cizích stránek, proto musíme rozlišit celkem 3 různé situace. Pokud je proměnná $http_referer prázdná, jedná se o přímé volání, což znamená, že uživatel zadal URL přímo do adresního řádku prohlížeče -> $referer = 1. Dále musíme rozlišit, zda se nejedná pouze o přechod mezi jednotlivými stránkami v rámci serveru. Do proměnné $no_referer nejprve vložíme alespoň částečnou adresu našeho serveru. Pokud se $no_referer nachází v $http_referer, jedná se o logicky o přechod v rámci serveru -> $referer = 2. Jestliže nebyla splněna ani jedna podmínka, přišel návštěvník z cizích stránek.

// REFERER - odkud přišel návštěvník
$no_referer = "nas_server.cz";    // pokud bude $referer obsahovat tuto hodnotu, jedná se o přechod v rámci serveru
$http_referer = URLDecode(StrToLower($referer));    // rozkóduje URL a převede na malá písmena

if ($http_referer == ""):    // přímé volání
    $referer = 1;

elseif (EregI($no_referer, $http_referer)):    // přechod v rámci serveru
    $referer = 2;

Nejprve stručně k tomu, jakým způsobem budeme provádět statistiku příchodů z cizích stránek. Jasnější to bude na příkladu. Máme tyto adresy, ze kterých návštěvníci přišli: http://interval.cz/clanek.asp?article=754, http://interval.cz/clanek.asp?article=351, http://diskuse.interval.cz/default.asp?idcategory=1. Protože celá adresa stránky, ze které uživatel přišel, nám příliš mnoho neřekne, budeme monitorovat jen doménové adresy stránek, z čehož vyplývá, že 1. návštěvník (http://interval.cz/clanek.asp?article=754) přišel z interval.cz. Protože část "www.", jakožto doména třetí úrovně, nemá prakticky žádný vypovídací význam (server.cz je totéž, co www.server.cz), bude i 2. odkaz (http://interval.cz/clanek.asp?article=351) znamenat, že návštěvník přišel z interval.cz. U třetího odkazu (http://diskuse.interval.cz/default.asp?idcategory=1) je doménou třetí úrovně část "diskuse", což nám říká, že se jedná nejspíš o nějakou diskusní část serveru interval.cz, a proto se bude jednat o přístup z diskuse.interval.cz. Pokud byste chtěli zjišťovat, z jakých konkrétních stránek daného serveru návštěvníci přicházejí, můžete tyto funkce samozřejmě odstranit.

Po trošku delší teorii přichází na řadu praktické řešení dané úlohy. URL ($http_referer) si nejprve rozdělíme na jednotlivé části pomocí funkce Parse_URL(). V poli s indexem host je poté doménová adresa (např. www.interval.cz). Pole obsahuje celou řadu dalších užitečných indexů, podrobnosti lze nalézt v manuálu PHP. Následně odstraníme z adresy část "www." Pomocí známých funkcí a postupů zjistíme, zda daný server v tabulce referer již existuje. Pokud ne, tak ho samozřejmě přidáme. Do proměnné $referer si uložíme id daného serveru, tato proměnná bude součástí SQL dotazu, který uloží do tabulky access všechny informace o daném přístupu.

else:    // návštěvník přišel z cizích stránek
    $url = Parse_URL($http_referer); // rozdělí URL na části
    $host = EregI_Replace("^www\.", "", $url["host"]); // odstraní "www."

    // je stránka v databázi ? (pokud ne, přidáme ji)
    $query = MySQL_Query("SELECT id FROM referer WHERE server = '$host'");
    if ($result = MySQL_Fetch_Array($query)):
        $referer = $result["id"];
    else:
        $query = MySQL_Query("INSERT INTO referer VALUES ('', '$host')");
        $referer = MySQL_Insert_ID();
    endif;

Vyhodnocení

Statistika se bude skládat ze dvou tabulek. V první bude vyjádřen poměr přímých volání a přístupů z cizích serverů. V druhé potom přístupy z jednotlivých serverů. Počet přímých volání za dané období ($sql_access_date) zjistíme tak, že do SQL dotazu přidáme podmínku WHERE referer = 1. Při určování počtu přístupů ze všech cizích serverů použijeme podmínku WHERE referer > 2 (1 = přímé volání, 2 = přechod v rámci našeho serveru). Následně pomocí větší z obou hodnot ($max) a celkového počtu ($sum) vypočítáme šířku obrázku znázorňujícího podíl a samotný podíl v procentech. Tento postup je blíže popsán ve třetím díle.

// PŘÍMÉ VOLÁNÍ X PŘÍSTUPY Z CIZÍCH STRÁNEK

echo '<p align="center" class="heading">Přímé volání X přístupy z cizích stránek</p>';
echo '<table width="550" cellspacing="0" align="center">';
echo '<tr><td width="230" class="tableheader">Typ</td><td width="50" class="tableheader">Počet</td><td width="280" class="tableheader">Podíl</td>';

// přímé volání
$query = MySQL_Query("SELECT count(*) FROM access WHERE referer = 1 AND $sql_access_date");
$result = MySQL_Fetch_Array($query);
$count_direct = $result["count(*)"];    // počet

// přístupy z cizích stránek
$query = MySQL_Query("SELECT count(*) FROM access WHERE referer > 2 AND $sql_access_date");
$result = MySQL_Fetch_Array($query);
$count_referer = $result["count(*)"];    // počet

$max = Max($count_direct, $count_referer);    // maximální hodnota (kvůli měřítku)
$sum = $count_referer+$count_direct;

// šířky obrázků
$width_direct = Round($count_direct/$max*200);
$width_referer = Round($count_referer/$max*200);

// podíl
$rate_direct = BCDiv($count_direct, ($sum/100), 2);
$rate_referer = BCDiv($count_referer, ($sum/100), 2);

echo '<tr><td>Přímé volání</td><td>' . $count_direct . '</td><td><img src="1.gif" width="' . $width_direct . '" height="8" border="0" alt=""> ' . $rate_direct .' %</td></tr>';
echo '<tr><td>Odjinud</td><td>' . $count_referer . '</td><td><img src="1.gif" width="' . $width_referer . '" height="8" border="0" alt=""> ' . $rate_referer . ' %</td></tr>';

echo '</table><br>';

Výpis počtu přístupů z jednotlivých serverů provedeme spojením tabulek referer a access, kde položka id v tabulce referer je primárním klíčem a položka referer v tabulce access cizím klíčem. Podrobnější vysvětlení, byť se jedná o statistiku prohlížečů, najdete opět ve třetím díle.

// REFERER
echo '<p align="center" class="heading">Z jakých stránek přišli</p>';
echo '<table width="550" cellspacing="0" align="center">';
echo '<tr><td width="230" class="tableheader">Server</td><td width="50" class="tableheader">Počet</td><td width="280" class="tableheader">Podíl</td>';

// vybíráme servery podle jejich zastoupení
$query = MySQL_Query("SELECT server, count(*) AS count_it FROM referer, access WHERE referer.id > 2 AND referer.id = referer AND $sql_access_date GROUP BY referer ORDER BY count_it DESC");
$max = MySQL_Result($query, 0, "count_it");    // počet přístupů z nejvíce zastoupeného serveru
$move = MySQL_Data_Seek($query, 0);    // přesuneme se znovu na začátek

while($result = MySQL_Fetch_Array($query)):
    $width = Round($result["count_it"]/$max*200);    // šířka obrázku znázorňujícího podíl
    $rate = BCDiv($result["count_it"], ($count_referer/100), 2);    // podíl v procentech
    echo '<tr><td>' . $result["server"] . '</td><td>' . $result["count_it"] . '</td><td><img src="1.gif" width="' . $width . '" height="8" border="0" alt=""> ' . $rate . ' %</td></tr>';
endwhile;

echo '</table><br>';

V příštím pokračování, které do určité míry souvisí s tím dnešním, se dozvíte, jak zjistit, které fráze používají návštěvníci stránek v různých vyhledávačích (Seznam, Atlas, Google...).

Předchozí díly:
Statistika přístupů v PHP – rozlišení a barevná hloubka
Statistika přístupů v PHP – detekce operačního systému
Statistika přístupů v PHP – detekce prohlížeče
Statistika přístupů v PHP – počet unikátních návštěvníků

Kebrt, Michal (20.6. 2002)
Diskuze: Statistika přístupů v PHP – odkud přicházejí návšt ...
2002-06-26 08:27:38IvrisZjistovani unikatnich navstevniku pomoc...
2002-06-26 18:29:45Michal KebrtZjistovani unikatnich navstevniku pomo...
2002-06-27 08:36:28ivrisZjistovani unikatnich navstevniku pom...
2002-06-30 21:49:18Martin Vondrafunkce MkDir
2003-09-30 09:46:26AldakDotaz
2003-09-30 12:27:33MichalDotaz