Interaktívna učebnica: Bootstrap, tabuľky a výpis dát z databázy v PHP. Čítaj, skúšaj a hneď vidíš výsledok.
Hotová kostra kódu s pravidlami, do ktorej vkladáme vlastný obsah.
@media pravidielMy voláme jej kód vtedy, keď ho práve potrebujeme. Program riadime my.
= náradie v dielni
Dáva kostru a pravidlá, do ktorých vkladáme obsah. Framework riadi nás.
= stavebnica s návodom
Najčastejšia chyba: kód nájdený na internete patrí k inej verzii.
| Kritérium | Bootstrap 3 2013 | Bootstrap 4 2018 | Bootstrap 5 2021 |
|---|
data-toggle (v4) → data-bs-toggle (v5)ml-3 / mr-3 (v4) → ms-3 / me-3 (v5, kvôli podpore RTL)img-responsive (v3) → img-fluid (v4 a v5)form-group (v4) → zrušené, použi mb-3 alebo g-3Tri spôsoby. Na hodine používame CDN.
Súbory sa načítajú priamo z internetu. Nič nesťahujeme. Bez pripojenia stránka stratí štýl.
<!-- 1. do <head> -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- 2. tesne pred </body> -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
bundle znamená, že súbor obsahuje aj knižnicu Popper, ktorú potrebujú dropdown, tooltip a popover. Ak používaš len mriežku a farby, JavaScript pripájať nemusíš.
Na getbootstrap.com → Download → Compiled CSS and JS stiahneme ZIP, rozbalíme a priečinky css/ a js/ skopírujeme do projektu.
<link rel="stylesheet" href="css/bootstrap.min.css">
<script src="js/bootstrap.bundle.min.js"></script>
Pre väčšie projekty s nástrojmi Vite alebo Webpack, keď si chceme upraviť zdrojové SCSS premenné (napr. hlavnú farbu $primary).
npm install bootstrap@5.3.8
// potom v kóde projektu
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap';
Minimálna funkčná stránka. Bez značky <meta name="viewport"> sa na mobile mriežka vôbec nezalomí — je to najčastejšia príčina otázky „prečo mi to na telefóne nefunguje“.
<!DOCTYPE html>
<html lang="sk">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Moja prvá Bootstrap stránka</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="p-4">
<h1 class="text-primary">Ahoj, Bootstrap!</h1>
<button class="btn btn-success">Funguje to</button>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Posúvaj jazdce a sleduj, ako sa mriežka mení. Kód sa generuje sám.
Zmenši okno prehliadača (alebo stlač F12 a zapni Toggle device toolbar) a sleduj, kedy sa stĺpce zalomia pod seba.
.container → .row → .col-*.
Stĺpec musí byť priamym potomkom riadku. Súčet stĺpcov v riadku má byť 12;
ak je viac, prebytok sa zalomí do ďalšieho riadku (nie je to chyba, ale musí to byť zámer).
Bootstrap pomenúva farby podľa významu, nie podľa odtieňa. Klikni na dlaždicu.
text-success — zelený text
bg-warning — žlté pozadie
text-bg-danger — pozadie + kontrastný text
border-info — farebný rámček
alert alert-info — informačná hláškaŠírka sa skokovo mení na breakpointoch, po bokoch ostávajú okraje. Vhodné pre články, blogy a bežný obsah.
Vhodné pre hlavičky, hero sekcie, administračné panely a galérie na celú obrazovku.
Zapínaj triedy a sleduj, ako sa obrázok mení.
Namiesto skutočnej fotografie je tu farebný blok, aby stránka fungovala aj bez internetu. Na skutočnom obrázku sa triedy správajú rovnako.
alt je povinný vždy. Číta ho čítačka obrazovky pre nevidiacich
a zobrazí sa, keď sa obrázok nenačíta. Bootstrap ho nenahrádza.
Skús formulár odoslať prázdny a pozri, ako funguje validácia.
form-label | popisok, prepojený cez for |
form-control | text, e-mail, heslo, textarea |
form-select | rozbaľovací zoznam |
form-check | checkbox a radio |
form-switch | prepínač (novinka v 5) |
form-range | posuvník |
form-floating | plávajúci popisok (novinka v 5) |
is-invalid | chybný stav + invalid-feedback |
form-group, form-row.
Medzery rieš triedami mb-3 alebo g-3 na riadku.
Základom je vždy trieda .table. Ostatné triedy pridávaš k nej — skús to.
table)
tr = riadok, th = bunka hlavičky (tučná), td = bunka s dátami.
Triedy table-striped a table-hover pôsobia len na riadky v <tbody> —
preto thead a tbody píš vždy. Práve do <tbody> budeme neskôr
vypisovať riadky z databázy.
table | základ — bez nej ostatné triedy nefungujú |
table-striped | pruhované riadky |
table-hover | zvýraznenie riadka pod myšou |
table-bordered / table-borderless | rámček okolo všetkých buniek / bez čiar |
table-sm | kompaktná tabuľka s menším odsadením |
table-dark, table-primary… | farba celej tabuľky, riadka tr alebo bunky td |
align-middle | zvislé centrovanie obsahu buniek |
table-responsive | obal (div) — na mobile pridá vodorovný posuvník |
table-responsive nepatrí na <table>,
ale na obalový <div> okolo nej. Na <table> nemá žiadny účinok.
Procedurálne mysqli — kód rozdelený do súborov, s kódovaním UTF-8 a s HTML oddeleným od PHP.
hostia/
├── connect.php ← pripojenie + kódovanie (raz pre celý web)
├── index.php ← dotaz a výpis do tabuľky
├── hladanie.php ← výpis s filtrom z formulára
└── databaza.sql ← tabuľka + testovacie dáta
hostia skopíruj do C:\xampp\htdocs\.http://localhost/phpmyadmin → Import → vyber databaza.sql.http://localhost/hostia/ — nie dvojklikom na súbor.<meta charset="utf-8">.utf8mb4 a hlavne spojenie:
mysqli_set_charset($conn, "utf8mb4");
Prečo utf8mb4 a nie utf8? V MySQL je starší „utf8“ len trojbajtový a neuloží napr. emoji.
utf8mb4 je plnohodnotné UTF-8. Porovnávanie utf8mb4_slovak_ci navyše zoradí
priezviská po slovensky — Čech za Baláž, nie až na koniec.
Vytvorí databázu myDB, tabuľku MyGuests (rovnakú ako na W3Schools) a vloží šesť testovacích záznamov s diakritikou — hneď uvidíš, či kódovanie funguje.
Pripojenie napíšeme raz do samostatného súboru. Každá stránka, ktorá potrebuje databázu, si ho pripojí jedným riadkom
require_once "connect.php";. Keď sa zmení heslo alebo server, opravuješ jediný súbor.
mysqli_set_charset hneď po pripojení. Určuje, v akom kódovaní si PHP a databáza posielajú text.
Bez neho sa diakritika pokazí, aj keď sú tabuľka aj HTML správne.mysqli rovno vyhodí chybu
Fatal error: Uncaught mysqli_sql_exception s popisom. Podmienka if (!$conn) sa vtedy
ani nevykoná — nechávame ju pre staršie PHP a pre pochopenie postupu.Súbor má tri časti: hore PHP (pripojenie a dotaz, nič nevypisuje), v strede HTML s Bootstrap tabuľkou, do ktorej PHP len vsúva hodnoty, a dole upratovanie.
htmlspecialchars() zmení znaky < > " & na neškodný text. Keby niekto uložil do databázy
meno <script>…, prehliadač ho len vypíše a nespustí. Číslo id ošetrovať netreba.
Keď do dotazu vstupuje text od používateľa (z formulára, z adresy), nikdy ho nelepíme do SQL reťazca.
Na jeho miesto dáme otáznik ? a hodnotu databáze odovzdáme zvlášť — tzv. prepared statement.
$sql = "SELECT … WHERE lastname = '" . $_GET["priezvisko"] . "'";
— ak niekto do poľa napíše ' OR '1'='1, dotaz vráti celú tabuľku. Tento útok sa volá SQL injection.
Pôvodný príklad z W3Schools vypisuje HTML cez echo. Pre tabuľku je prehľadnejšie opačné poradie: píšeme HTML a PHP vkladáme len tam, kde treba.
echo
</td>.
<?php while (…) { ?>
Hneď za otváracou zátvorkou { zatvor PHP značkou ?>. Odteraz píšeš čisté HTML — ono sa bude opakovať pre každý riadok z databázy.
<?php echo $row["lastname"]; ?>
echo vypíše hodnotu presne na to miesto v HTML, kde stojí. Na konci príkazu nezabudni na bodkočiarku ;.
<?php } ?>
Do PHP sa vrátiš už len na zatvorenie cyklu zátvorkou }. Za ňou pokračuje obyčajné HTML — </tbody></table> a zvyšok stránky.
if / elseBlok otvoríš zátvorkou {, ukončíš PHP značkou ?>,
napíšeš HTML a blok zatvoríš <?php } ?>. Každá { musí mať svoju } —
odsadzuj kód, aby bolo vidno, ktoré patria k sebe. Celý príklad nájdeš v index.php.
while skončíKlikaj na Ďalší krok a sleduj, čo sa deje s premennou $row.
Dotaz: SELECT id, firstname, lastname FROM MyGuests
$row
$result (ukazovateľ ▸ na ďalší riadok)| ID | Meno | Priezvisko |
|---|
✘ SELECT * FROM MyGuests
✔ SELECT id, firstname, lastname FROM MyGuests
Z databázy do PHP putuje menej dát a z dotazu je jasné, s čím stránka pracuje.
WHERE, ORDER BY lastname, LIMIT 20
Databáza to urobí rýchlejšie ako if v PHP cykle a do PHP pošle len to, čo naozaj vypíšeš.
require_once "connect.php"; — na začiatku, raz.
Pripojenie je najpomalší krok. require_once zaručí, že súbor sa nepripojí dvakrát.
mysqli_query v while = 100 riadkov → 100 dotazov.
Ak potrebuješ dáta z dvoch tabuliek, spoj ich v jednom dotaze cez JOIN.
mysqli_num_rows✘ if (mysqli_fetch_assoc($result)) pred cyklom
Každé volanie mysqli_fetch_assoc posunie ukazovateľ — prvý riadok by sa „minul“ a v tabuľke by chýbal.
?, výstup cez htmlspecialcharsmysqli_prepare + mysqli_stmt_bind_param
Prepared statement chráni databázu (SQL injection), htmlspecialchars chráni návštevníkov stránky (XSS).
| Čo vidíš | Prečo | Riešenie |
|---|---|---|
Namiesto č, š, ž sú otázniky alebo znaky ako Å¡ |
Chýba mysqli_set_charset, alebo tabuľka nie je v utf8mb4. |
Doplň riadok do connect.php; tabuľku vytvor podľa databaza.sql. |
| V tabuľke chýba prvý záznam | Pred cyklom je ďalšie volanie mysqli_fetch_assoc. |
Na kontrolu použi mysqli_num_rows($result) > 0. |
Parse error: syntax error, unexpected end of file |
Chýba zatváracia zátvorka <?php } ?> za cyklom alebo podmienkou. |
Každý otvorený blok zatvor. Odsadzuj kód, aby bolo vidno páry. |
Fatal error: Uncaught mysqli_sql_exception: Unknown column … |
Preklep v názve stĺpca alebo tabuľky v SQL. | Dotaz si najprv vyskúšaj v phpMyAdmin → záložka SQL. |
… mysqli_sql_exception: Access denied / Connection refused |
Zlé meno či heslo, alebo nebeží MySQL. | V XAMPP spusti MySQL; skontroluj údaje v connect.php. |
| Prehliadač ukáže PHP kód ako text alebo ponúkne súbor na stiahnutie | Súbor má príponu .html alebo je otvorený cez file://. |
Prípona .php a otvárať cez http://localhost/… |
| Na stránke sa zobrazí kus komentára z PHP | V komentári // je napísané ?> — PHP sa tam ukončí aj uprostred komentára. |
V jednoriadkových komentároch nepíš ?>. |
Cannot modify header information – headers already sent |
Za ?> v connect.php je prázdny riadok alebo medzera. |
Súbor, ktorý obsahuje iba PHP, nekonči značkou ?>. |
htmlspecialchars
a prepared statement. Popis všetkých funkcií:
php.net — MySQLi.
16 otázok zo všetkých tém. Odpoveď sa vyhodnotí hneď, poradie možností sa pri každom pokuse zamieša.