Dokončení paginace (stránkování) v PHP

PHP Ostatní Dokončení paginace (stránkování) v PHP

V minulém tutoriálu o tvorbě 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ím dílu aplikaci dokončíme.

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:

<?php

function urlStrany($url, $strana)
{
        return str_replace('{strana}', $strana, $url);
}

function paginace($strana, $stran, $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 2 funkce. První funkce 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?stran­ka={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žte 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 display na inline-block, což zapříčiní, že se položky v seznamu řadí za sebe a také trik s 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:

<?php
require('Db.php');
require('paginace.php');
Db::connect('localhost', 'automobilka', 'root', '');

Dále si připravíme 2 funkce (objektově zdatní si vytvoří nějaký SpravceAutomobilu, ve kterém budou tyto 2 metody umístěné).

function vratAutomobily($strana, $naStranu)
{
        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 $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.

function vratPocetAutomobilu()
{
        return Db::querySingle('SELECT COUNT(*) FROM automobil');
}

Funkce vratPocetAuto­mobilu() vrátí celkový počet všech automobilů v databázi. Ten potřebujeme proto, abychom mohli paginační liště předat celkový počet stránek. Na akci tedy potřebujeme 2 databázové dotazy, nelze ji efektivně provést jedním, jelikož chceme 2 odlišné věci.

Číslo stránky budeme předávat pomocí $_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 $automobily s automobily na zobrazované stránce a $stran a celkovým počtem stran. Ten zjistíme tím, že celkový počet automobilů vydělíme $naStranu a zaokrouhlíme nahoru funkcí ceil (protože 1,5 strany jsou 2 strany :) ).

if (isset($_GET['strana']))
        $strana = $_GET['strana'];
else
        $strana = 1;
$naStranu = 15;
$automobily = vratAutomobily($strana, $naStranu);
$stran = ceil(vratPocetAutomobilu() / $naStranu);
?>

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

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 :)


 

Stáhnout

Staženo 132x (21.36 kB)
Aplikace je včetně zdrojových kódů v jazyce php

 

  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 (12 hlasů) :
4.833334.833334.833334.833334.83333


 


Miniatura
Předchozí článek
Paginace (stránkování) v PHP
Miniatura
Všechny články v sekci
Ostatní tutoriály v PHP
Miniatura
Následující článek
Stromové menu z databáze v PHP

 

 

Komentáře
Zobrazit starší komentáře (10)

Avatar
martin.alexandr:

ja to hledal po všech čertech,nikde nic,musel sem určitě něco přehlidnout

 
Odpovědět 7.5.2015 14:11
Avatar
Odpovídá na martin.alexandr
Martin Konečný (pavelco1998):

No místo toho {stranka} se dosadí číslo, aby se vytvořil správně odkaz. Je to nejspíš něco jako zástupný znak.

 
Odpovědět  +3 7.5.2015 16:39
Avatar
Odpovídá na martin.alexandr
Michal Šmahel (ceskyDJ):

Ano, funguje to jako zástupný znak (taková "proměnná"). Místo toho si systém dosadí požadovaná data.

Odpovědět 7.5.2015 20:02
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
martin.alexandr:

díky moc
vím jak to funguje,jen jsem nikde nemohl najít popis zmíněného zápisu

díky:)

 
Odpovědět 7.5.2015 20:47
Avatar
botsie
Člen
Avatar
botsie:

několik dní hledaní a konečne přesně to co potřebuju děkujiiiiii :O teď ten velký počet záznamů v db klekne na kolena

 
Odpovědět 14.6.2015 13:52
Avatar
botsie
Člen
Avatar
botsie:

prosim, když chci ?strana=6 změnit na ?str=6 ... kolik změn musím udělat aby fungovlo vše správně ?

 
Odpovědět 14.6.2015 21:26
Avatar
Inoue Yūki
Redaktor
Avatar
Odpovídá na botsie
Inoue Yūki:

Pokud jsem si ten článek dobře přečetl, mělo by stačit změnit tuto část

<?= paginace($strana, $stran, '?strana={strana}') ?>

na

<?= paginace($strana, $stran, '?str={strana}') ?>
Odpovědět 14.6.2015 21:30
Avatar
botsie
Člen
Avatar
botsie:

Děkuji za odpověď, ale bohužel toto jsem zkoušel jako první, a jediné co se mění je url, avšak výpis inzerátu včetně navigace stojí na prvních záznamech :) Chtěl bych toto rychlé stránkování použít pro starý web abych dodržel zaindexovaný obsah...

 
Odpovědět 15.6.2015 5:58
Avatar
Inoue Yūki
Redaktor
Avatar
Odpovídá na botsie
Inoue Yūki:

Tak to vypadá, že ještě tu:

if (isset($_GET['strana']))
        $strana = $_GET['strana'];
else
        $strana = 1;

na

if (isset($_GET['str']))
        $strana = $_GET['str'];
else
        $strana = 1;
Editováno 15.6.2015 6:24
Odpovědět  +1 15.6.2015 6:24
Avatar
botsie
Člen
Avatar
Odpovídá na Inoue Yūki
botsie:

Děkuju moc, tyhle dvě úpravy co jsi napsal a je to ok, url může být jiné :-)

 
Odpovědět 15.6.2015 6:51
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 10 zpráv z 20. Zobrazit vše