Paginace (stránkování) v PHP

PHP Ostatní Paginace (stránkování) v PHP

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. To si ukážeme v dalších dílech.

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 screenshot výsledné aplikace:

Paginace v PHP

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í utf8_czech_ci).

Vytvoření databáze pro paginaci v PHP

V databázi vytvoříme tabulku automobily. Tabulka bude mít následující sloupce:

  • automobil_id (int, autoincrement, primární klíč)
  • znacka (varchar 20)
  • spz (varchar 10)
  • barva (varchar 20)
  • vyrobeno (date)
Vytvoření tabulky pro paginaci v PHP

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 Generátor testovacích dat.

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 článku 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 od 0 do 9, vytvoříme jednoduchou funkci:

function generujSpz()
{
        $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()
{
        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 1 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:

Testovací data k paginaci

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.

Případy paginace
  • 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 v příštím dílu, kdy paginaci také dokončíme.


 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (7 hlasů) :
4.428574.428574.428574.42857 4.42857


 



 

 

Komentáře

Avatar
hanpari
Redaktor
Avatar
hanpari:

Hm, nebylo by vhodnější dát sem databázi (například jako soubor sqlite nebo csv k importu)? Samotný článek může být zajímavý, ale v zásadě není o stránkování, ale o přípravě dat.
Popřípadě bych ho alespoň jinak nazval.

 
Odpovědět 23.6.2015 18:05
Avatar
IT Man
Redaktor
Avatar
Odpovídá na hanpari
IT Man:

Protože bez databáze a dat by to nešlo. Pokud si to někdo chce vyzkoušet, tohle se mu bude hodit. Jinak by si pak někdo stěžoval, že tu není to přidávání dat. :)

Odpovědět  +1 23.6.2015 18:09
Když nevíš jak dál, podá ti ruku někdo, od koho by jsi to nečekal. A tu šanci musíš přijmout!
Avatar
hanpari
Redaktor
Avatar
Odpovídá na IT Man
hanpari:

Aha, a četl jsi, co jsem napsal?
Že bych ty data přiložil jako soubor?

 
Odpovědět  ±0 23.6.2015 19:09
Avatar
Filip Stryk
Redaktor
Avatar
Odpovídá na hanpari
Filip Stryk:

jsou ke stažení v dalším díle :)

Odpovědět  +1 23.6.2015 19:12
„Neděláš dobře, když chválíš to, čemu nerozumíš, ale ještě horší je, když to haníš.“ Leonardo DaVinci
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.