Kadar je v tabeli veliko zapisov, jih običajno ne prikažemo vseh hkrati. Namesto tega jih razdelimo na več strani. Tak postopek imenujemo delni izpis ali paginacija.
Delni izpis zapisov oziroma paginacija
Paginacija pomeni, da uporabniku prikažemo le določen del zapisov, na primer 5 ali 10 zapisov na posamezni strani. Tako je izpis preglednejši in hitrejši.
Pri paginaciji običajno potrebujemo:
- koliko zapisov želimo prikazati na eni strani,
- od katerega zapisa naprej želimo začeti izpis,
- skupno število vseh zapisov v tabeli.
Osnovna sintaksa za delni izpis je:
SELECT *
FROM imeTabele
ORDER BY idStolpec
LIMIT steviloZapisov OFFSET zacetek;
Za izračun paginacije pogosto potrebujemo še skupno število zapisov:
SELECT COUNT(*) AS total
FROM imeTabele;
Na podlagi števila vseh zapisov nato izračunamo, koliko strani potrebujemo, katera stran je trenutna in ali lahko uporabniku pokažemo povezavo na prejšnjo ali naslednjo stran.
Osnovni primer z mysqli
Spodnji zgled prikaže 5 zapisov na stran in uporablja parameter
start za določitev začetnega odmika.
<?php
define('DB_SERVER', 'localhost');
define('DB_USER', 'uporabnik');
define('DB_PASS', 'skritoGeslo');
define('DB_NAME', 'knjiznica');
$connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (!$connection) {
die(
'Povezava s podatkovno zbirko ni vzpostavljena: ' .
mysqli_connect_error() .
' (' . mysqli_connect_errno() . ')'
);
}
$limit = 5;
$start = $_GET['start'] ?? 0;
if (filter_var($start, FILTER_VALIDATE_INT) === false || (int)$start < 0) {
$start = 0;
}
$start = (int)$start;
// Skupno število zapisov
$countResult = mysqli_query($connection, "SELECT COUNT(*) AS total FROM knjige");
$countRow = mysqli_fetch_assoc($countResult);
$totalRecords = (int)$countRow['total'];
// Delni izpis zapisov
$stmt = mysqli_prepare(
$connection,
"SELECT ID_knjige, Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto
FROM knjige
ORDER BY ID_knjige
LIMIT ? OFFSET ?"
);
mysqli_stmt_bind_param($stmt, 'ii', $limit, $start);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($result)) {
echo htmlspecialchars($row['Naslov']) . '<br>';
}
mysqli_stmt_close($stmt);
mysqli_close($connection);
?>
Osnovni primer s PDO
Tudi z vmesnikom PDO lahko enostavno pripravimo
delni izpis in navigacijo med stranmi.
<?php
$streznik = 'localhost';
$baza = 'knjiznica';
$uporabnik = 'uporabnik';
$geslo = 'skritoGeslo';
try {
$pdo = new PDO("mysql:host=$streznik;dbname=$baza;charset=utf8mb4", $uporabnik, $geslo);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$limit = 5;
$start = $_GET['start'] ?? 0;
if (filter_var($start, FILTER_VALIDATE_INT) === false || (int)$start < 0) {
$start = 0;
}
$start = (int)$start;
$stmtCount = $pdo->query('SELECT COUNT(*) AS total FROM knjige');
$countRow = $stmtCount->fetch(PDO::FETCH_ASSOC);
$totalRecords = isset($countRow['total']) ? (int)$countRow['total'] : 0;
$stmt = $pdo->prepare(
"SELECT ID_knjige, Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto
FROM knjige
ORDER BY ID_knjige
LIMIT :limit OFFSET :start"
);
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':start', $start, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo htmlspecialchars($row['Naslov']) . '<br>';
}
}
catch (PDOException $e) {
echo 'Napaka pri delnem izpisu: ' . $e->getMessage();
}
?>
Izračun strani pri paginaciji
Pri paginaciji moramo poleg poizvedbe izračunati še nekaj dodatnih vrednosti, da lahko uporabniku pravilno prikažemo navigacijo.
- skupno število zapisov pridobimo z ukazom
COUNT(*), - število strani izračunamo iz skupnega števila zapisov in velikosti strani,
- trenutno stran izračunamo iz začetnega odmika,
- pripravimo povezave za prejšnjo in naslednjo stran.
Če uporabnik vnese previsok začetni odmik, ga lahko prilagodimo na zadnji smiselni blok zapisov.
Pomembnosti pri delnem izpisu
- delni izpis je uporaben pri tabelah z veliko zapisi,
- za pridobivanje dela rezultatov uporabimo LIMIT in OFFSET,
- za navigacijo med stranmi potrebujemo tudi COUNT(*),
- rezultate je priporočljivo pred paginacijo urediti z ORDER BY,
- uporabniku pogosto prikažemo še trenutno stran, število vseh strani in število zapisov.
📘Aplikacija Knjige
V priloženi aplikaciji Knjige je delni izpis
izveden v datoteki 14_delni-izpis.php. Na posamezni strani
se prikaže po 5 zapisov, začetni odmik pa se
prebere iz parametra start. Če je vrednost neveljavna
ali negativna, se nastavi na 0.
Aplikacija najprej z ukazom SELECT COUNT(*) AS total FROM knjige
prešteje vse zapise, nato pa z ukazom
LIMIT :limit OFFSET :start pridobi le trenutni del
rezultatov. Če je začetni odmik previsok, ga prilagodi na zadnji
možni blok zapisov.
Nato izračuna še trenutno stran, skupno število strani ter vrednosti za povezavi nazaj in naprej. Na strani se izpišejo tudi aktivne številke strani in preglednica zapisov. Če zapisov ni, se pokaže posebno obvestilo.
Navodila za izdelavo aplikacije Knjige
- Določimo, koliko zapisov želimo prikazati na eni strani.
- Iz URL parametra preberemo začetni odmik.
- Preverimo, ali je začetni odmik veljavno nenegativno celo število.
- Z ukazom COUNT(*) pridobimo skupno število zapisov.
- Z ukazoma LIMIT in OFFSET pridobimo trenutni del rezultatov.
- Izračunamo trenutno stran, skupno število strani ter povezavi za nazaj in naprej.
- Na strani izpišemo tabelo zapisov in navigacijo med stranmi.
Pri učenju je smiselno poznati oba pristopa:
- mysqli za klasičen delni izpis zapisov,
- PDO za sodobnejši pristop s pripravljenimi parametri,
- aplikacijski pristop, kjer uporabnik prehaja med stranmi rezultatov s klikom na navigacijo.