Lekce 14 - Dokončení paginace (stránkování) v PHP
V minulé lekci, Paginace (stránkování) v PHP, jsme si založili databázi s 1000 testovacími automobily a popsali jsme si, jak by měl fungovat helper, který bude zobrazovat naši paginaci.
V dnešní lekci se podíváme na helper paginace, styly a celý skript pro otestování stránkování.
paginace.php
Vytvořte si soubor paginace.php
, do kterého vložíme funkce
pro výpis navigační lišty s čísly stránek:
function urlStrany(string $url, int $strana) { return str_replace('{strana}', $strana, $url); } function paginace(int $strana, int $stran, string $url) { $polomer = 5; // Poloměr oblasti kolem aktuální stránky $html = '<nav class="centrovany"><ul class="paginace">'; // Šipka vlevo if ($strana > 1) $html .= '<li><a href="' . urlStrany($url, $strana - 1) . '">«</a></li>'; else $html .= '<li class="neaktivni">«</li>'; $left = $strana - $polomer >= 1 ? $strana - $polomer : 1; $right = $strana + $polomer <= $stran ? $strana + $polomer : $stran; // Umístění jedničky if ($left > 1) $html .= '<li><a href="' . urlStrany($url, 1) . '">1</a></li>'; // Tečky vlevo if ($left > 2) $html .= '<li class="neaktivni">…</li>'; // Stránky v radiusu for ($i = $left; $i <= $right; $i++) { if ($i == $strana) // Aktivní stránka $html .= '<li class="aktivni">' . $i . '</li>'; else $html .= '<li><a href="' . urlStrany($url, $i) . '">' . $i . '</a></li>'; } // Tečky vpravo if ($right < $stran - 1) $html .= '<li class="neaktivni">' . '…' . '</li>'; // Umístění poslední stránky if ($right < $stran) $html .= '<li><a href="' . urlStrany($url, $stran) . '">' . $stran . '</a></li>'; // Šipka vpravo if ($strana < $stran) $html .= '<li><a href="' . urlStrany($url, $strana + 1) . '">»</a></li>'; else $html .= '<li class="neaktivni">«</li>'; $html .= '</ul></nav>'; return $html; }
Soubor obsahuje dvě funkce. První funkce urlStrany()
vrátí
URL adresu pro přechod na danou stránku a to tak, že převezme URL adresu se
značkou {strana}
a na místo této značky
vloží číslo dané stránky. Když funkci pošleme parametry:
['index.php?strana={strana}', 2]
Vrátí nám:
index.php?strana=2
Tímto způsobem budeme generovat odkazy na stránky, aby byl soubor
paginace.php
univerzální a mohli jsme ho použít pro jakýkoli
tvar URL, např. zamestnanci.php?stranka={strana}
.
Druhá funkce vygeneruje HTML kód navigační lišty a to podle aktuální
stránky a počtu stránek. V proměnné $polomer
se nachází
informace, kolik stránek chceme okolo aktuální stránky zobrazovat. Postupně
vložíme šipku vlevo, 1. stránku, tečky, rozsah stránek okolo té
aktuální, tečky a šipku vpravo. Všimněte si, že je navigace kvůli
sémantice vložena v elementu <nav>
.
styl.css
Založíme si soubor styl.css
, do kterého vložíme něco k
nastylování lišty:
/* * Paginace */ ul.paginace li { display: inline-block; padding: 4px 10px; border: 1px solid #DDDDDD; margin-left: -1px; text-align: center; } ul.paginace li:hover { background: #fAfAfA; } ul.paginace li.neaktivni { color: #DDDDDD; } ul.paginace li.aktivni { color: white; background: #3b94e0; } ul.paginace a { text-decoration: none; } /* * Ostatní */ .centrovany { text-align: center; }
Zajímavá je změna vlastnosti display
na hodnotu
inline-block
, což zapříčiní, že se položky v seznamu řadí
za sebe a také trik s vlastností margin-left: -1px
, což
způsobí spojení rámečků sousedících položek do jednoho.
Rovnou do stylu dodejme i jednoduché stylování tabulky, do které budeme automobily vypisovat:
/* * Tabulka */ .tabulka { width: 100%; color: #444444; text-align: center; border-collapse: collapse; border: 1px solid #C9CBCD; } .tabulka th, .tabulka td { padding: 5px; border-collapse: collapse; border: 1px solid #C9CBCD; } .tabulka th { color: black; background: #f5f5f5; } .tabulka tr:nth-child(2n) { background-color: #F6F6F6; }
Zajímavé jde zde asi jen proužkování pomocí selektoru
.tabulka tr:nth-child(2n)
, který vybere každý druhý
řádek.
index.php
Konečně se dostáváme k hlavnímu skriptu. Zprvu si načteme databázovou knihovnu a helper pro zobrazení paginační lišty. Připojíme se k databázi:
require('Db.php'); require('paginace.php'); Db::connect('localhost', 'automobilka', 'root', '');
Dále si připravíme dvě funkce (objektově zdatní si vytvoří nějaký
SpravceAutomobilu
, ve kterém budou tyto dvě metody
umístěné):
function vratAutomobily(int $strana, int $naStranu): mixed { return Db::queryAll('SELECT * FROM automobil ORDER BY vyrobeno DESC LIMIT ?, ?', ($strana - 1) * $naStranu, $naStranu); }
Funkce vratAutomobily()
vrátí automobily na základě
aktuální stránky a počtu automobilů na stranu. V SQL dotazu se nám
objevila klauzule nastavující LIMIT
a OFFSET
. Offset
nastavíme na ($strana - 1) * $naStranu
, protože stránky
číslujeme od jedničky a chceme přeskočit tolik položek, kolik máme před
sebou stránek × počet položek na jedné stránce. Limit je parametr
$naStranu
, to je kolik chceme po přeskočení položek vybrat. U
dotazu nesmíme zapomenout na řazení ORDER BY
, jinak by nám
přišly výsledky pokaždé jinak rozházené a stránkování by nedávalo
smysl.
Funkce vratPocetAutomobilu()
vrátí celkový počet všech
automobilů v databázi:
function vratPocetAutomobilu(): mixed { return Db::querySingle('SELECT COUNT(*) FROM automobil'); }
Funkci potřebujeme proto, abychom mohli paginační liště předat celkový počet stránek. Na akci tedy potřebujeme dva databázové dotazy, nelze ji efektivně provést jedním, jelikož chceme dvě odlišné věci.
Číslo stránky budeme předávat pomocí pole $_GET
, neboli
formulářové metody GET. Pokud není zadána, budeme předpokládat první
stranu. Následně si vytvoříme proměnné $naStranu
s počtem
položek na stránku, dále proměnnou $automobily
s automobily na
zobrazované stránce a proměnnou $stran
s celkovým počtem
stran. Ten zjistíme tím, že celkový počet automobilů vydělíme
proměnnou$naStranu
a zaokrouhlíme nahoru funkcí
ceil()
(protože 1,5 strany jsou 2 strany 🙂):
$strana = $_GET['strana'] ?? 1; $naStranu = 15; $automobily = vratAutomobily($strana, $naStranu); $stran = ceil(vratPocetAutomobilu() / $naStranu);
První řádek výše bychom mohli nahradit delší podmínkou, dělají totéž:
if (isset($_GET['strana'])) $strana = $_GET['strana']; else $strana = 1;
Za kód umístíme část šablony pro výpis tabulky a paginační lišty:
<!DOCTYPE html> <html lang="cs-cz"> <head> <meta charset="utf-8" /> <title>Automobily</title> <link rel="stylesheet" href="styl.css" type="text/css"/> </head> <body> <h1>Automobily</h1> <table class="tabulka"> <tr> <th>Značka</th> <th>SPZ</th> <th>Barva</th> <th>Vyrobeno</th> </tr> <?php foreach ($automobily as $automobil) { echo(' <tr> <td>' . htmlspecialchars($automobil['znacka']) . '</td> <td>' . htmlspecialchars($automobil['spz']) . '</td> <td>' . htmlspecialchars($automobil['barva']) . '</td> <td>' . date('j.n. Y', strtotime($automobil['vyrobeno'])) . '</td> </tr>' ); } ?> </table> <?= paginace($strana, $stran, '?strana={strana}') ?> </body> </html>
Máme hotovo. Výsledek:
Odnesli jste si univerzální stránkovací nástroj, projekt máte ke stažení v příloze. A já se na vás budu těšit zas u dalšího tutoriálu
V další lekci, Stromové menu z databáze v PHP, si ukážeme, jak na udělat interaktivní stromové menu z databáze.
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 429x (22.56 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP