Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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) . '">&laquo;</a></li>';
    else
        $html .= '<li class="neaktivni">&laquo;</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">&hellip;</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">' . '&hellip;' . '</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) . '">&raquo;</a></li>';
    else
        $html .= '<li class="neaktivni">&laquo;</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:

Paginace v PHP
index.php?strana=6

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 422x (22.56 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

Předchozí článek
Paginace (stránkování) v PHP
Všechny články v sekci
Knihovny pro PHP
Přeskočit článek
(nedoporučujeme)
Stromové menu z databáze v PHP
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
23 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity