Lekce 12 - Objektové počítadlo návštěv v PHP a PDO
V předešlém cvičení, Řešené úlohy k 9.-11. lekci OOP v PHP, jsme si procvičili nabyté zkušenosti z předchozích lekcí.
Na dnešek si ukážeme reálný příklad. Půjde o objektovou práci s databází pomocí ovladače PDO, se kterým se v tomto dílu seznámíme. Zkusíme si naprogramovat webové počítadlo návštěv.
Metodika počítání přístupů
Při počítání návštěv webu se většinou rozlišuje mezi třemi termíny:
- Zobrazení - Počet všech zobrazení webu. Započítá se při každém přístupu. Pokud tedy nějaký uživatel zobrazí na webu 10 stránek za hodinu, připočte se 10 zobrazení.
- Návštěva - Návštěvník se započítá jen jednou asi za 30 minut. Pokud si tedy za hodinu 1 uživatel přečte 10 článků, bere se to jako že web 2x navštívil.
- UIP - Unikátní návštěvníci, přesněji počet unikátních IP adres za určité období. Pokud si uživatel přečte za měsíc 1000 článků, bere se to jen jako 1 unikátní zobrazení.
Zobrazení jsou samozřejmě nejvyšší a UIP nejnižší. UIP mají nejvyšší vypovídací hodnotu. Návštěvy jsou něco mezi a v našem případě je ukládat nebudeme, jelikož je není úplně jednoduché rozlišit. Budeme ukládat pouze zobrazení stránek a počet UIP z nich později jednoduše zjistíme tak, že si vybereme jen unikátní zobrazení za určitý časový úsek.
Databáze
Zobrazení tedy budeme ukládat do databáze. Při každém zobrazení stránky na našem webu vložíme do databáze řádek s aktuálním datem a IP adresou návštěvníka. Daly by se ukládat i další věci, jako prohlížeč nebo jazyk, ale to zanedbáme.
U hodně navštěvovaných webů se návštěvnost neukládá do databáze při každém zobrazení stránky, jelikož by to databázi příliš zatěžovalo. Zobrazení se logují do textového souboru a za nějaký čas se spustí skript, který je ze souboru uloží do databáze. K DB tedy není přistupováno tak často a zátěž je nižší. V našem případě toto můžeme určitě zanedbat a budeme ukládat zobrazení rovnou do databáze.
Zakládací skripty
Vytvořme si databázovou tabulku zobrazeni
, která bude mít 3
sloupce:
zobrazeni_id
(INT
, AI, primární klíč)ip
(VARCHAR
40)datum
(INT
)
Datum a čas zde uložíme jako celé číslo. Je to druhá alternativa
oproti databázovému typu DATETIME
. Já osobně ji používám
více, tak si alespoň zkusíme zas něco jiného. Datum uložíme jako počet
vteřin od roku 1970. Dělá se to tak často a rok 1970 není náhodný, jedná
se o začátek Unixové epochy. PHP na to má samozřejmě funkce.
Tabulku si klidně naklikejte v PHPMyAdmin:

Případně zde máte zakládací skripty:
CREATE TABLE IF NOT EXISTS `zobrazeni` ( `zobrazeni_id` int(11) NOT NULL AUTO_INCREMENT, `ip` varchar(40) COLLATE utf8_czech_ci NOT NULL, `datum` int(11) NOT NULL, PRIMARY KEY (`zobrazeni_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci AUTO_INCREMENT=1 ;
Databázi máme připravenou.
První seznámení s PDO
Minule jsme si vysvětlili, že se v PHP pro práci s databází používá
téměř výhradně objektový ovladač PDO. PDO
je třída, která
je součástí jazyka PHP. Ukažme si, jak by vypadalo připojení se k
databázi a vložení nového řádku do tabulky zobrazeni
pomocí
tohoto ovladače.
Připojení
Vytvoříme si úplně nový projekt s novou složku pocitadlo/
a dovnitř umístíme index.php
. Do indexu vložíme následující
řádky:
<?php $nastaveni = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8' ); $spojeni = new PDO("mysql:host=localhost;dbname=pocitadlo_db", 'root', '', $nastaveni);
Nejprve si vytvoříme pole s nastavením pro PDO. První klíč je způsob,
jakým chceme, aby byly zpracovávány chyby. Zvolili jsme výjimky
(exceptions), k těm se dostaneme dále v seriálu. Ten druhý určuje, že
nechceme, aby PDO emulovalo prepared statements pro starší verze MySQL, které
ho nepodporovaly. Bez tohoto nastavení bychom nemohli používat např.
parametry v klauzuli LIMIT
. Třetí klíč je inicializační
příkaz pro databázi, zde chceme nastavit kódování na UTF-8.
Klíčové je vytvoření spojení, což provedeme jako vytvoření instance
PDO
. První parametr konstruktoru PDO je řetězec obsahující
připojovací údaje. Prvním je host (localhost
), druhým název
databáze (u mně pocitadlo_db
). Další 2 parametry konstruktoru
jsou uživatelské jméno (u mne root) a heslo (u mne prázdné). Jako poslední
parametr předáme naše nastavení. Pokud vám to po zapsání tohoto řádku
nevypsalo žádnou chybu, jste úspěšně připojení k DB. Pokud ne, opravte
si připojovací údaje.
Dotazy
Jakmile máme instanci PDO
spojení, můžeme na ni volat
databázové dotazy. Na rozdíl od zastaralých ovladačů podporuje PDO tzv.
prepared statements. Jedná se o oddělení vkládání samotného dotazu a
parametrů do tohoto dotazu. Jelikož je dotaz od svých parametrů oddělený,
nemůže dojít k SQL injekci. Databáze si přijaté parametry sama ošetřuje.
V minulosti se v PHP pro podobnou ochranu používaly funkce jako
mysql_real_escape_string()
, na které už můžete zapomenout
Připišme do index.php
další řádky:
$dotaz = $spojeni->prepare('INSERT INTO `zobrazeni` (`ip`, `datum`) VALUES (?, ?)'); $parametry = array($_SERVER['REMOTE_ADDR'], time()); $dotaz->execute($parametry);
Kód si popišme. Nejprve si vytvoříme instanci dotazu. Tu nám vrátí
metoda prepare()
na instanci PDO
spojení. Do
parametru metody napíšeme normálně SQL dotaz jako textový řetězec.
Namísto parametrů dotazu však vložíme otazníky. Nikdy nebudeme
vkládat proměnné nebo hodnoty přímo do dotazu! Jedná se o bezpečnostní
riziko.
Parametry potom vložíme do nového pole v tom pořadí, v jakém jsou
otazníky v dotazu. $_SERVER['REMOTE_ADDR']
obsahuje IP adresu (na
lokálním počítači budete mít dost možná hodnotu :1 nebo něco
podobného). Funkce time()
vrátí aktuální čas jako UNIX
timestamp (počet sekund od 1.1.1970).
Vytvořený dotaz nakonec spustíme metodou execute()
, které
předáme pole s parametry, které se do dotazu mají vložit. Zkuste
index.php
navštívit a podívat se do tabulky, bude tam nový
řádek.
POZOR! Pokud máte v PHP zapnuté chybové hlášky a máte nějakou chybu v dotazu, vypíše se chybová zpráva. Ovladač PDO vyhazuje při chybách výjimky (což je správně) a jelikož se ty vypisují spolu se stopou stacku, mohou zobrazit spolu s částí kódu i vaše heslo k databázi! Je velmi důležité, abyste o tom věděli a měli vypnuté chyby na produkčním serveru (kde samozřejmě vypnuté být mají).
To by bylo pro dnešek vše. Dnešní zdrojový kód včetně exportu DB je jako vždy připojen pod článkem ke stažení.
V příští lekci, Objektové počítadlo návštěv v PHP - Databáze, si vytvoříme objekt, který bude zaznamenávat návštěvy, analyzovat je a vypisovat.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 968x (1.97 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP