Paginator a stránkování výpisu výsledků v PHP
Kolik máme k dispozici výsledků
Na začátku musíme zjistit, kolik máme vůbec k dispozici výsledků. Pokud data pochází z databáze, tak je lze velice efektivně spočítat následujícím SQL příkazem:
SELECT COUNT(*) FROM tabulka
Výpočet to je velice rychlý, protože si databáze vede statistiky v pomocném souboru, proto na data vůbec nesahá.
Pokud data pochází odjinud (a máme je například v poli), tak je lze spočítat funkcí count():
$cisla = [3, 1, 4, 1, 5, 9, 2];
echo 'Pole obsahuje ' . count($cisla) . ' čísel.';
Omezení počtu výsledků
Další problém je omezení počtu výsledků. Pokud jsou data v databázi, tak stačí do SQL příkazu vložit parametr LIMIT
:
SELECT * FROM tabulka WHERE (cokoli) LIMIT 10
Tímto příkazem dostaneme vždy maximálně 10 výsledků, zároveň bude také dotaz rychlejší, protože databáze nebude muset procházet celé datové soubory.
Pokud máme data z jiného zdroje (zase opět pole), tak můžeme výsledky omezit také na úrovni PHP s použití pomocné proměnné $iterator
:
$pole = [...];
$iterator = 0;
$limit = 10;
foreach ($pole as $prvek) {
// tady se vypisují data
$iterator++;
if ($iterator >= $limit) {
break; // Zastaví cykl, až proběhne 10x
}
}
Přeskočení prvních X výsledků
Když jsme na první stránce, je to celkem jednoduché, to stačí pouze za pomoci LIMITu
omezit počet výsledků. Ale co když jsem na třetí stránce? Pak musíme prvních X
výsledků přeskočit.
V SQL na to máme opět elegantní zápis:
SELECT * FROM tabulka WHERE (cokoli) LIMIT 10 OFFSET 20
Přeskočí prvních 20 výsledků a další výpis omezí na 10 výsledků, vypíše proto tedy interval <21 - 30>
.
V čistém PHP se toto řeší dvěma způsoby.
Pokud známe indexy pole, tak jej můžeme začít číst až od určitého místa (což je velice rychlé):
$pole = [...];
$start = 20;
$limit = 10;
for ($i = $start; ($i <= $start + $limit && isset($pole[$i])); $i++) {
// tady se vypisují data
}
Ovšem u neznámého pole musíme opět použít iterátor a položky přeskočit:
$pole = [...];
$iterator = 0;
$start = 20;
$limit = 10;
foreach ($pole as $prvek) {
if ($iterator < $start) {
$iterator++;
continue;
}
// tady se nějak vypisují data
$iterator++;
if ($iterator >= $start + $limit) break;
}
Zobrazení optimálního paginatoru / krokovače
Dejme tomu, že známe celkový počet položek, počet položek na stránce a číslo aktuální stránky. Nyní chceme vykreslit lištu, která umožní rychlé procházení všech stránek s výsledky hledání. Protože je ovšem stránek hodně (řádově tisíce), tak nemůžeme vypsat všechny najednou, musíme si proto inteligentně vybrat je nějaké reprezentativní, které nejlépe vystihují rozmezí mezi stránkami.
Vypadat to může třeba takto:
1 | 15 | 30 | 36 | 45 | 60 | 72
Zadání:
Jsem na stránce 36 ze 72, jak optimálně rozmístit čísla stránek? No přeci přes posloupnost.
Tip: Praktickým pozorováním jsem zjistil, že levou část Paginatoru je vhodné počítat přes aritmetickou posloupnost (abych se mohl lineárně přesouvat o stejný počet kroků) a pravou část přes geometrickou posloupnost, která zase umožňuje snadno udělat velký krok. Pokud se tedy chci dostat na nějakou konkrétní stránku, tak nejprve přeskočím velké množství nepotřebných položek a poté zpřesňuji volbu vracením směrem doleva.
Teorie aritmetické posloupnosti (stále přičítáme stejné číslo):
$d = 10; // velikost kroku
$a[1] = 1; // první prvek
$a[2] = $a[1] + $d; // druhý prvek
$a[3] = $a[1] + 2 * $d;
$a[3] = $a[2] + $d;
$a[$n] = $a[1] + ($n - 1) * $d; // n-tý prvek
function getAritmeticItem(int $start, int $step, int $n): int
{
return $start + ($n - 1) * $step;
}
Teorie geometrické posloupnosti (stále násobíme stejným číslem):
$q = 10; // velikost kroku
$a[1] = 1; // první prvek
$a[2] = $a[1] * $q; // druhý prvek
$a[3] = $a[1] * $q * $q;
$a[3] = $a[1] * pow($q, 2);
$a[3] = $a[2] * $q;
$a[$n] = $a[1] * pow($q, $n - 1); // n-tý prvek
function getGeometricItem(int $start, int $step, int $q): int
{
return $start * pow($q, $step - 1);
}
$start = 1;
$current = 36;
$end = 72;
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Kontakt Spolupráce