Lekce 13 - Paginace (stránkování) v PHP
V minulé lekci, Generátor testovacích dat v PHP - Entity a relace, dokončíme skript generátoru testovacích dat.
V dnešním tutoriálu se naučíme v PHP řešit velmi častou úlohu, kterou je tzv. paginace (stránkování). Jedná se o stránkování výpisu nějakých položek, které by mělo být přítomno asi téměř všude. Když aplikaci vytvoříme, je v ní jen několik uživatelů, článků, automobilů... Po letech používání tam však mohou být tisíce položek a stahování tolika dat z databáze a jejich výpis na jedinou stránku zbytečně zatěžuje server a zpomaluje prohlížeč klienta. Alternativou k paginaci je donačítávání nových položek AJAXem ve chvíli, kdy doscrollujeme na konec dokumentu.
Tutoriál budu psát pro zjednodušení neobjektově. Ti, kteří objekty ještě neumí, ho alespoň budou umět použít a ti, kteří je umí, si ho do objektů převedou během pár minut.
Pro namotivování si ukažme výslednou aplikaci:
Databáze
Aby měla aplikace smysl, nevyhneme se databázi. Vytvořme si nějakou
jednoduchou MySQL databázi (např. automobilka
, porovnávání
bude mít utf8_czech_ci
):
V databázi vytvoříme tabulku automobily. Tabulka bude mít následující sloupce:
automobil_id
(int, auto_increment, primární klíč)znacka
(varchar 20)spz
(varchar 10)barva
(varchar 20)vyrobeno
(date)
Takto to bude vypadat v phpMyAdmin:
Data
Než se pustíme do samotné paginace, měli bychom mít připravená data, která budeme zobrazovat. Samozřejmě nebudeme ručně naklikávat 1000 testovacích automobilů, ale necháme si je vygenerovat. V našem případě to bude docela jednoduché, pro složitější generování dat můžete využít lekci Generátor testovacích dat v PHP.
Pro práci s databází budeme používat místní databázový wrapper,
který je ke stažení v podobě souboru Db.php
v příloze lekce
První
databázová tabulka a MySQL ovladače v PHP. Pro náš projekt si vytvořte
nějakou složku a soubor Db.php
do ní nakopírujte. Dále
vytvořte soubor instalace.php
, který bude mít za úkol vložit
do databáze testovací automobily.
Nejprve se připojíme k databázi a vytvoříme si pole se zásobou značek aut a barev, abychom měli z čeho generovat:
require_once('Db.php'); Db::connect('localhost', 'automobilka', 'root', ''); mb_internal_encoding("UTF-8"); $znacky = array('Škoda', 'BMW', 'Audi', 'Volvo', 'Opel', 'Renault', 'Hyundai', 'Seat', 'Jaguar', 'Alfa Romeo'); $barvy = array('červená', 'černá', 'bílá', 'zelená', 'modrá', 'stříbrná metalíza', 'oranžová', 'fialová', 'žlutá');
Ke generování náhodné SPZ ve tvaru AAA-0000
, kde
A
je znak od 0
do Z
a 0
je
znak (číslo) od 0
do 9
, vytvoříme jednoduchou
funkci:
function generujSpz(): string { $znaky = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $spz = ''; // První 3 znaky for ($i = 0; $i < 3; $i++) { $spz .= $znaky[rand(0, mb_strlen($znaky) - 1)]; } // Pomlčka $spz .= '-'; // Poslední 4 čísla for ($i = 0; $i < 4; $i++) { $spz .= rand(0, 9); } return $spz; }
Generování náhodného data je jednoduché. Čísla dnů budeme generovat jen do 28, abychom nemuseli řešit, kolik má měsíc dnů:
function generujDatum(): string { return rand(1990, 2014) . '-' . rand(1, 12) . '-' . rand(1, 28); }
Nakonec si necháme vygenerovat 1000 náhodných aut a ta uložíme do databáze:
for ($i = 0; $i < 1000; $i++) { $automobil = array( 'znacka' => $znacky[array_rand($znacky)], 'spz' => generujSpz(), 'barva' => $barvy[array_rand($barvy)], 'vyrobeno' => generujDatum(), ); Db::insert('automobil', $automobil); } echo('Hotovo.');
Je dobré podotknout, že není kvůli výkonu úplně dobrý nápad volat
databázový dotaz v cyklu. Měli bychom sestavit jeden příkaz
INSERT
s více položkami a ten potom na databázi spustit. U nás
to při faktu, že skript spouštíme pouze jednou, nijak nevadí. Skript
spustíme v prohlížeči.
Výsledek:
Helper
Zobrazení lištičky pro přepínání stránek není tak triviální
záležitost, jak by se mohlo zdát. Sémanticky by měla být lištička v HTML
reprezentována elementem <ul>
, který nastylujeme do
řádku. Kromě zvýraznění aktuální stránky budeme chtít zobrazit ještě
několik stránek okolo aktuální stránky (např. 5), potom zpravidla napsat
několik teček a první a poslední stránku. Na koncích lištičky budeme
chtít odkazy (šipky) na další a předchozí stránku, které budou
neaktivní pokud budeme na začátku nebo na konci.
Protože obrázek řekne více než tisíc slov, ukažme si několik možností, které mohou v paginaci nastat. Obrázek pochází ze chvíle, kdy jsem paginaci testoval.
- U prvního obrázku vidíme, že se nacházíme na první stránce. Vlevo je již tedy jen neaktivní šipka, vpravo jsou odkazy na 5 dalších stránek, poté tečky a poslední strana. Lišta končí šipkou s odkazem na další stranu.
- Druhý obrázek znázorňuje situaci, kdy má výpis jen jednu stanu.
- Třetí obrázek ukazuje oříznutí poloměru vypisovaných stránek okolo aktuální stránky. Zleva se vypíší jen 2, zprava zas 5 a poslední strana.
- Čtvrtý obrázek je varianta 1.
- Pátý obrázek zobrazuje kompletní poloměr okolo aktuální strany.
Představu o helperu máme, na jeho implementaci se podíváme příště.
V další lekci, Dokončení paginace (stránkování) v PHP, si dokončíme paginační helper pro webové aplikace v PHP.
Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.