Kadar ne želimo prikazati vseh zapisov naenkrat, lahko izpis omejimo. V MySQL oziroma MariaDB za to uporabimo ukaza LIMIT in OFFSET.
Omejen izpis je uporaben pri daljših seznamih, pri preglednejšem prikazu podatkov in pri pripravi paginacije. Namesto da uporabniku prikažemo vse zapise hkrati, mu lahko prikažemo samo določen del rezultatov.
Pomni: LIMIT določa, koliko zapisov naj se prikaže, OFFSET pa določa, koliko začetnih zapisov naj se preskoči.
Pri omejenem izpisu rezultate skoraj vedno tudi uredimo z ukazom ORDER BY. Tako je vrstni red prikaza predvidljiv.
Vsebina strani
Osnovna pravila
Pri omejenem izpisu določimo, koliko zapisov želimo prikazati in od katerega mesta v rezultatu naj se prikaz začne.
- Za določanje števila prikazanih zapisov uporabimo
LIMIT. - Za določanje začetnega odmika uporabimo
OFFSET. - Vrednost pri
LIMITmora biti pozitivno celo število. - Vrednost pri
OFFSETmora biti celo število, ki je večje ali enako nič. - Rezultate pred omejitvijo uredimo z ukazom
ORDER BY. - Če uporabnik vnese neveljavne vrednosti, uporabimo privzeti izpis ali prikažemo opozorilo.
- Pri izpisu podatkov uporabimo
htmlspecialchars().
Pozor: Vrednosti za LIMIT in OFFSET pogosto pridejo iz obrazca. Zato jih je treba pred uporabo preveriti kot cela števila.
Omejen izpis zapisov
Omejen izpis pomeni, da iz tabele prikažemo le določen del zapisov. To je uporabno pri daljših seznamih, pri prikazu po straneh in pri pripravi preglednejšega izpisa.
Osnovna sintaksa za omejen izpis je:
SELECT *
FROM imeTabele
LIMIT steviloZapisov;
Če želimo določiti še začetni odmik, uporabimo:
SELECT *
FROM imeTabele
LIMIT steviloZapisov OFFSET zacetek;
Če želimo iz tabele knjige prikazati 5 zapisov od tretjega zapisa naprej, uporabimo:
SELECT *
FROM knjige
ORDER BY ID_knjige
LIMIT 5 OFFSET 2;
Vrednost OFFSET 2 pomeni, da se prva dva zapisa preskočita, nato pa se prikaže največ 5 zapisov.
Pomni: Vrednost pri OFFSET se začne z nič. OFFSET 0 pomeni, da se ne preskoči noben zapis.
Osnovni primer z mysqli
Spodnji zgled prikaže omejeno število zapisov iz tabele knjige. Če uporabnik vnese napačne podatke, se izpišejo vsi zapisi.
<?php
define('DB_SERVER', 'localhost');
define('DB_USER', 'uporabnik');
define('DB_PASS', 'skritoGeslo');
define('DB_NAME', 'knjiznica');
// Povezava do podatkovne zbirke
$connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
// Preverjanje povezave
if (!$connection) {
die(
'Povezava s podatkovno zbirko ni vzpostavljena: ' .
mysqli_connect_error() .
' (' . mysqli_connect_errno() . ')'
);
}
$stevilo = trim($_POST['stevilo'] ?? '');
$start = trim($_POST['start'] ?? '');
$steviloValid = filter_var($stevilo, FILTER_VALIDATE_INT);
$startValid = filter_var($start, FILTER_VALIDATE_INT);
if ($steviloValid !== false && $startValid !== false && (int)$stevilo > 0 && (int)$start >= 0) {
$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', $steviloValid, $startValid);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
} else {
$result = mysqli_query(
$connection,
"SELECT ID_knjige, Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto
FROM knjige
ORDER BY ID_knjige"
);
}
while ($row = mysqli_fetch_assoc($result)) {
echo htmlspecialchars($row['Naslov']) . '<br>';
}
if (isset($stmt)) {
mysqli_stmt_close($stmt);
}
mysqli_close($connection);
?>
Pri mysqli vrednosti za LIMIT in OFFSET preverimo kot cela števila, nato ju vežemo kot parametra s funkcijo mysqli_stmt_bind_param().
Osnovni primer s PDO
Tudi z vmesnikom PDO lahko omejen izpis izvedemo s pripravljenim stavkom in parametroma za LIMIT ter OFFSET.
<?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);
$stevilo = trim($_POST['stevilo'] ?? '');
$start = trim($_POST['start'] ?? '');
$steviloValid = filter_var($stevilo, FILTER_VALIDATE_INT);
$startValid = filter_var($start, FILTER_VALIDATE_INT);
if ($steviloValid !== false && $startValid !== false && (int)$stevilo > 0 && (int)$start >= 0) {
$stmt = $pdo->prepare(
"SELECT ID_knjige, Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto
FROM knjige
ORDER BY ID_knjige
LIMIT :stevilo OFFSET :start"
);
$stmt->bindValue(':stevilo', (int)$stevilo, PDO::PARAM_INT);
$stmt->bindValue(':start', (int)$start, PDO::PARAM_INT);
$stmt->execute();
} else {
$stmt = $pdo->prepare(
"SELECT ID_knjige, Priimek_avtorja, Ime_avtorja, Naslov, Strani, Cena, Leto
FROM knjige
ORDER BY ID_knjige"
);
$stmt->execute();
}
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo htmlspecialchars($row['Naslov']) . '<br>';
}
}
catch (PDOException $e) {
echo 'Napaka pri omejenem izpisu: ' . $e->getMessage();
}
?>
Pri PDO vrednosti za LIMIT in OFFSET vežemo kot cela števila z PDO::PARAM_INT. Tako preprečimo, da bi se v poizvedbo vključile neustrezne vrednosti.
Preverjanje vrednosti za omejen izpis
Pred uporabo ukazov LIMIT in OFFSET moramo preveriti, ali je uporabnik vnesel veljavni celi števili.
- število zapisov mora biti pozitivno celo število,
- začetni odmik mora biti nič ali več,
- če podatka nista pravilna, uporabniku pokažemo opozorilo ali izpišemo vse zapise,
- omejen izpis je najbolj smiseln skupaj z urejenim prikazom zapisov.
$steviloValid = filter_var($stevilo, FILTER_VALIDATE_INT);
$startValid = filter_var($start, FILTER_VALIDATE_INT);
if ($steviloValid === false || $startValid === false) {
echo 'Vneseni vrednosti nista veljavni celi števili.';
}
Pozor: Vrednost LIMIT 0 ne pomeni prikaza vseh zapisov, ampak pomeni, da se ne prikaže noben zapis. Zato mora biti število prikazanih zapisov večje od nič.
Povezava z paginacijo rezultatov
Ukaza LIMIT in OFFSET se pogosto uporabljata pri paginaciji rezultatov. Pri tem se velik seznam razdeli na več strani.
Če želimo na vsaki strani prikazati 10 zapisov, lahko odmik izračunamo iz številke strani:
$naStran = 10;
$stran = 3;
$offset = ($stran - 1) * $naStran;
Za tretjo stran je odmik 20, saj se prvih 20 zapisov preskoči, nato pa se prikaže naslednjih 10 zapisov.
SELECT *
FROM knjige
ORDER BY ID_knjige
LIMIT 10 OFFSET 20;
Pomni: Pri paginaciji mora biti vrstni red rezultatov določen. Zato je ORDER BY pri uporabi LIMIT in OFFSET zelo pomemben.
Primerjava pristopov mysqli in PDO
Oba pristopa omogočata omejen izpis s preverjenimi številskimi parametri. Razlikujeta se predvsem v načinu vezave parametrov in branju rezultatov.
| Korak | mysqli |
PDO |
|---|---|---|
| Preverjanje števil | filter_var() |
filter_var() |
| Priprava stavka | mysqli_prepare() |
$pdo->prepare() |
| Parametra | ?, ? |
:stevilo, :start |
| Vezava vrednosti | mysqli_stmt_bind_param() |
$stmt->bindValue() |
| Branje rezultatov | mysqli_fetch_assoc() |
$stmt->fetchAll() |
Aplikacija Knjige
📘Aplikacija Knjige
V priloženi aplikaciji Knjige je omejen izpis izveden v datoteki 11_omejen-izpis.php. Uporabnik v obrazec vnese število zapisov in začetni odmik, nato pa aplikacija glede na vneseni vrednosti pripravi ustrezno poizvedbo.
Stran najprej pridobi največji ID_knjige in ga uporabi pri dodatni kontroli, ali je začetni odmik smiseln. Če podatka manjkata, nista veljavna ali je začetni odmik previsok, aplikacija prikaže vse zapise. Če sta oba podatka pravilna, uporabi LIMIT :stevilo OFFSET :start.
Pod obrazcem aplikacija izpiše tudi opis trenutnega izpisa, število prikazanih zapisov in preglednico rezultatov. Vrednosti so pri izpisu zaščitene s funkcijo htmlspecialchars().
11_omejen-izpis.phpNavodila za izdelavo aplikacije Knjige
- Najprej pripravimo obrazec za vnos števila zapisov in začetnega odmika.
- Ob oddaji obrazca preberemo obe vrednosti.
- Preverimo, ali sta vneseni vrednosti veljavni celi števili.
- Preverimo, da je število zapisov večje od
0. - Preverimo, da je začetni odmik večji ali enak
0. - Če sta podatka pravilna, pripravimo poizvedbo z ukazoma LIMIT in OFFSET.
- Če podatka nista pravilna, uporabniku izpišemo vse zapise ali opozorilo.
- Rezultate uredimo, izvedemo poizvedbo in jih izpišemo v tabeli.
- Na koncu prikažemo še opis trenutnega izpisa in število prikazanih zapisov.
Pozor: Pri omejenem izpisu je pomembno, da uporabnik ne more poslati negativnega odmika ali neustrezne vrednosti za število zapisov. Takšne vrednosti je treba zavrniti ali nadomestiti s privzetim izpisom.
Priporočila
- Za omejen izpis uporabi
LIMIT. - Za začetni odmik uporabi
OFFSET. - Vrednosti za
LIMITinOFFSETvedno preveri kot cela števila. - Število zapisov naj bo večje od
0. - Začetni odmik naj bo večji ali enak
0. - Rezultate vedno uredi z
ORDER BY. - Pri večjih seznamih razmisli o paginaciji rezultatov.
- Uporabniku prikaži opis izpisa in število prikazanih zapisov.
Pogoste napake
- Vrednosti za
LIMITinOFFSETniso preverjene. - Za število zapisov je dovoljena vrednost
0, zato se ne prikaže noben zapis. - Začetni odmik je negativen.
- Ukaz
LIMITje uporabljen brezORDER BY, zato je izpis manj predvidljiv. - Uporabniku ni jasno prikazano, kateri del rezultatov gleda.
- Ni predvidenega odziva za neveljavne vrednosti obrazca.
- Pri izpisu podatkov manjka
htmlspecialchars(). - Pri paginaciji je napačno izračunan začetni odmik.
Omejen izpis je pogosto povezan z uporabniškim vnosom. Zato je treba vrednosti za število zapisov in začetni odmik obravnavati kot nezaupan podatek, dokler ju strežniška koda ne preveri.