Navigace

Hlavní menu

 

Submenu

 

Statistika přístupů v PHP – kalendář

Seriál o statistice přístupů se pomalu blíží ke konci. V dnešním pokračování si povíme, jak vytvořit kalendář, na kterém si můžeme zvolit období, pro které se zpracuje statistika. Věřím, že se vám kalendář bude hodit i v jiných aplikacích, a proto si ho již dnes budete moci stáhnout.

Nebudu se příliš rozepisovat o tom, jak bude kalendář vypadat, mnohem lepší bude ukázka v podobě obrázku a možnost prohlédnout si kalendář v ukázkové verzi statistiky přístupů.

Kalendář

Pro přechod mezi jednotlivými měsíci budeme používat proměnné $month a $year. Jestliže však pomocí odkazu přecházíme z prosince na leden (následujícího roku) a naopak, máme v proměnných $month a $year nekorektní hodnoty (v $month je 13 resp. 0 a $year zůstává stejné). O převod na správné hodnoty se postará funkce Date() v kombinaci s funkcí MkTime(), která přijímá i nekorektně zadané datum.

// pokud nejsou proměnné zinicializovány, vloží aktuální hodnoty
if(!IsSet($month)) $month = Date("m");
if(!IsSet($year)) $year = Date("Y");

// převod na korektní hodnoty
$year = Date("Y", MkTime(0,0,0, $month, 1, $year));
$month = Date("m", MkTime(0,0,0, $month, 1, $year));

Pomocí znaku "t" použitého ve funkci Date() získáme počet dnů v daném měsíci. Abychom každé datum mohli v další části skriptu zapsat do správného řádku a sloupečku, přiřadíme nyní ke každému dni jeho číslo v týdnu (1 = pondělí, 2 = úterý, ..., 7 = neděle). Protože znak "w" použitý ve funkci Date() přiřazuje k neděli 0, musíme pomocí podmínky změnit tuto 0 na 7. Do proměnné $first uložíme číslo prvního dne v měsíci.

$count_days = Date("t", MkTime(0,0,0, $month, 1, $year)); // počet dnů v měsíci

// ke každému dni přiřadí jeho číslo v týdnu (1 = pondělí, ...)
for($i=1;$i<=$count_days;$i++):
    $date[$i] = Date("w", MkTime(0,0,0,$month,$i,$year));
    if($date[$i]==0) $date[$i] = 7;
endfor;

$first = $date[1];    // číslo prvního dne v měsíci (1 = pondělí, ...)

Protože vytvoření odkazů pro zobrazení statistiky za určité období není úplně jednoduchá záležitost, popíšu nejdříve kalendář bez těchto odkazů. Na první řádek tabulky zapíšeme právě zobrazený měsíc a rok a na každou stranu odkazy pro přechod na předchozí a následující měsíc. Ještě jednou se vrátím k problematice popsané v úvodu. Právě v těchto odkazech máme při přechodech prosinec - leden a naopak v proměnné $month nekorektní hodnoty 13 resp. 0.

<table cellspacing="0" align="center">
<tr><td align="center" colspan="8">

<?

// předchozí, aktuální a následující měsíc
echo '<a href="stat.php?month=' . ($month-1) . '&year=' . $year . '"><<</a>   ';
echo $month . " / " . $year;
echo '   <a href="stat.php?month=' . ($month+1) . '&year=' . $year . '">>></a>';

?>

</td></tr>
<tr><td>T</td><td>Po</td><td>Út</td><td>St</td><td>Čt</td>
<td>Pá</td><td>So</td><td>Ne</td></tr>

Kalendář vytvoříme pomocí cyklu postupně vytvářejícího jednotlivé řádky kalendáře, kterých může být nejvýše 6 (viz úvodní obrázek). Do prvního sloupečku zapíšeme číslo týdne ($x+1). Další sloupečky vyplníme pomocí druhého cyklu. Zde se uplatní výše zmíněná proměnná $first obsahující číslo prvního dne v měsíci (1 = pondělí, ...) a pole $date, kde u každého dne máme jeho pořadí v týdnu. Vzorec, který počítá obsah proměnné $day, se dá slovy popsat jen velmi zdlouhavě a složitě. Mnohem lepší bude uvést jeden příklad. Řekněme, že měsíc začíná nedělí (viz úvodní obrázek), $first je tedy 7. Při prvních šesti průchodech cyklem obsahuje proměnná $day hodnoty -5 až 0, a proto nemůže platit rovnost $date[$day] == $i, prvních šest "buněk" kalendáře tak bude prázdných. Pro $i=7 však dostáváme $day = 0*7+7-7+1 = 1. Rovnost $date[$day] == $i nebo-li $date[7] == 1 pak platí a do buňky můžeme zapsat první den. Do dalších řádků se poté bez problémů zapíší následující dny. Obdobná situace jako v úvodu nastává až v šestém řádku, kdy při posledních pěti průchodech cyklem obsahuje proměnná $day hodnoty 32-36, rovnost neplatí a buňky zůstanou prázdné. Na závěr je použita ještě jedna podmínka testující, zda následující den ve skutečnosti existuje. Pokud ne, je celý cyklus ukončen a tabulka s kalendářem uzavřena. Podmínka se uplatní v případech, kdy je kalendář jen na pěti řádcích, výjimečně i na čtyřech (když "nepřestupný" únor začíná v pondělí). V podmínce je použita funkce CheckDate(měsíc, den, rok) testující platnost data.

<?
$day = 0;
for($x=0;$x<=5;$x++):
    echo '<tr><td align="center"><b>';
    echo $x+1;
    echo '</b></td>';
    
    for($i=1;$i<=7;$i++):
        echo '<td align="center">';
        $day = $x*7+$i-$first+1; // na základě obou cyklů postupně počítá den
        
        if($date[$day] == $i)
            echo $day;
        else
            echo "&nbsp;"

        echo '</td>';
    endfor;
    echo '</tr>';

    if(!CheckDate($month, $day+1, $year)) break; // pokud neexistuje následující datum, ukončí cyklus
endfor;
?>

</table>

Doufám, že všem je nyní jasné vytvoření kalendáře. Zbývá tedy doplnit odkazy pro zobrazení denní, týdenní a měsíční statistiky přístupů. Úvodní část skriptu zůstává stejná, přibyla nám funkce DateLink($from, $to, $text) vypisující odkazy pro zobrazení statistiky za dané období. První parametr označuje den, OD kterého se statistika počítá, druhý parametr den, DO kterého se počítá a třetí obsahuje text uvedený v odkazu. Abychom nedávali odkazy i k obdobím, která ještě nenastala, musíme použít podmínku zjišťující, zda datum OD je menší nebo roven aktuálnímu datu. Pokud ne, vypíšeme samotný text bez odkazu.

// vypisuje odkazy pro zobrazení statistiky za dané období
function DateLink($from, $to, $text)
  {
     global $month, $year;

     if(MkTime(0,0,0,$month,$from,$year) <= MkTime(0,0,0, Date("m"), Date("d"), Date("Y"))):
         echo '<a href="stat.php?month=' . $month . '&year=' . $year . '&from_date=' . $year . '-' . $month . '-' . $from . '&to_date=' . $year . '-' . $month . '-' . $to . '">';
         echo $text;
         echo '</a>';
     else:
         echo $text;
     endif;
  }

Funkci DateLink() použijeme nejprve pro odkaz na měsíční statistiku. Den OD je samozřejmě 1, den DO je pak proměnná $count_days obsahující počet dnů v měsíci.

<table cellspacing="0" align="center">
<tr><td align="center" colspan="8">

<?

// předchozí, aktuální a následující měsíc
echo '<a href="stat.php?month=' . ($month-1) . '&year=' . $year . '"><<</a>   ';
DateLink(1, $count_days, $month . " / " . $year);    // odkaz na měsíční statistiku
echo '   <a href="stat.php?month=' . ($month+1) . '&year=' . $year . '">>></a>';

?>

</td></tr>
<tr><td>T</td><td>Po</td><td>Út</td><td>St</td><td>Čt</td>
<td>Pá</td><td>So</td><td>Ne</td></tr>

Nejproblematičtější je odkaz na týdenní statistiku. Pro výpočet posledního dne v daném týdnu použijeme podmínku. V prvním týdnu je poslední den roven vzorečku $end = 7-$first+1, pro ilustraci jeden příklad: začíná-li měsíc ve středu, $first je 3 a $end bude 4. V posledním týdnu je poslední den logicky roven počtu dní v daném měsíci. To, zda-li se jedná o poslední týden, zjistíme z podmínky $day+7>=$count_days, kde $day je naposled vypsaný den. Ve zbylých týdnech platí $end = $day+7. Do funkce DateLink() pak jako první parametr vložíme den následující po naposled vypsaném dni, o druhém parametru byla řeč před chvílí a třetí parametr bude číslo týdne v měsíci. Pro vytvoření odkazu na denní statistiku stačí do všech parametrů funkce DateLink() vložit tutéž proměnnou $day.

<?
$day = 0;
for($x=0;$x<=5;$x++):
    echo '<tr><td align="center"><b>';

    // poslední den v týdnu
    
    if($x==0)    // první týden
        $end = 7-$first+1;
    elseif($day+7>=$count_days)    // poslední týden
        $end = $count_days;
    else    // zbylé týdny
        $end = $day+7;

    // odkaz na týdenní statistiku
    DateLink($day+1, $end, $x+1);

    echo '</td>';
    
    for($i=1;$i<=7;$i++):
        echo '<td align="center">';
        $day = $x*7+$i-$first+1; // na základě obou cyklů postupně počítá den
        
        if($date[$day] == $i)
            DateLink($day, $day, $day); // odkaz na denní statistiku
        else
            echo "&nbsp;"

        echo '</td>';
    endfor;
    echo '</tr>';

    if(!CheckDate($month, $day+1, $year)) break; // pokud neexistuje následující datum, ukončí cyklus
endfor;
?>

</table>

Jelikož kalendář je ve statistice přístupů samostatným skriptem, můžete si ho stáhnout již nyní a použít třeba v úplně jiné aplikaci. K dispozici dávám dvě verze - bez odkazů a s odkazy. Příští článek bude zaměřen na tvorbu profesionálních grafů zachycujících různé statistické veličiny.

Předchozí díly:

Statistika přístupů v PHP – hodinová a denní návštěvnost
Statistika přístupů v PHP – regionální lokalizace
Statistika přístupů v PHP – domény nejvyšší úrovně
Statistika přístupů v PHP – vyhledávací fráze
Statistika přístupů v PHP – odkud přicházejí návštěvníci
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 (30. 8. 2002)
Diskuze: Statistika přístupů v PHP – kalendář
2002-09-02 10:49:41mimadownload
2002-09-02 18:46:59Michal Kebrtdownload
2002-09-10 19:58:29To bys chtěl vědět, co?Kdy to bude?
2002-09-10 20:27:43To bys chtěl vědět, co?Můj Mail
2002-09-10 20:30:01To bys chtěl vědět, co?@
2002-09-12 16:12:03JarkaJestli to jde....
2002-09-17 07:43:36VaKuJa taky
2003-04-04 15:21:27Smouladownload
2003-04-04 20:13:29Michal Kebrtdownload
2003-10-24 18:56:00Daviddownload
2003-10-24 18:56:57Daviddownload