Když máme na výpis mnoho dat, tak je slušnost je rozdělit na více stránek. Tento článek neřeší praktickou implementaci předávání čísel stránek a vypisování výsledků, pouze teoretické získání hodnot a výpočet optimálního číselníku tak, aby bylo procházení velkého množství stránek co nejvíce uživatelsky přívětivé.
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.';
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}}
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;}
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ý prvekfunction 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ý prvekfunction 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:
Nabízím trénink vývojářů, konzultace, školení a analýzu návrhových vzorů. Osobně v Praze nebo online.
Napište mi, pokud si nevíte rady.
Lektor: Jan Barášek
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | cs