Lekce 3 - Formulář a výpis dat z databáze do tabulky v PHP
V minulé lekci, První databázová tabulka a MySQL ovladače v PHP, jsme se připojili k databázi a vložili do ní několik uživatelů.
V reálných aplikacích se uživatelé vkládají pomocí formuláře. Přesně to se dnes naučíme a také se naučíme vypsat uživatele z databáze do HTML tabulky. Budeme pokračovat ve stylu co nejjednoduššího kódu.
Formulář
Pro vkládání uživatelů do databáze si vytvoříme jednoduchou HTML stránku s jedním formulářem. Náš vkládací dotaz upravíme tak, aby vkládal hodnoty z formuláře. Uveďme si kompletní kód registrační aplikace:
<!DOCTYPE html> <html lang="cs-cz"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>Registrace uživatele</title> </head> <body> <h1>Registrace uživatele</h1> <?php require_once('Db.php'); Db::connect('127.0.0.1', 'databaze_pro_web', 'root', ''); if ($_POST) { $datum = date("Y-m-d H:i:s", strtotime($_POST['datum_narozeni'])); Db::query(' INSERT INTO uzivatele (jmeno, prijmeni, datum_narozeni) VALUES (?, ?, ?) ', $_POST['jmeno'], $_POST['prijmeni'], $datum); echo('<p>Byl jste úspěšně zaregistrován.</p>'); } ?> <form method="post"> <label> Jméno:<br /> <input type="text" name="jmeno" /> </label><br /> <label> Příjmení:<br /> <input type="text" name="prijmeni" /> </label><br /> <label> Datum narození:<br /> <input type="text" name="datum_narozeni" /> </label><br /> <input type="submit" value="Registrovat" /> </form> </body> </html>
Kód je stále velmi krátký. Vysvětleme si ho. Co se týče HTML, tak tam by mělo být vše jasné. Formulář je jednoduchý a obsahuje 3 pole (jméno, příjmení, datum narození) a odesílací tlačítko. Protože form postrádá atribut action, odešle se na tu samou stránku.
Ve stránce je rovněž PHP skript, který se připojí k databázi. Podmínkou otestuje, zda se odeslala nějaká data formulářem. Pokud ano, vykoná SQL dotaz, který data do databáze vloží. Všimněme si třech věcí:
- Datum musíme převést z českého formátu (tak, jak ho zadal do políčka
uživatel, např. 15.1.1989) do formátu MySQL (např. 1989-15-1). To za nás
udělá dvojice funkcí
str_to_time()
adate()
. - SQL dotaz je velmi podobný tomu z minulého dílu. Již nevkládáme do
všech sloupců, ale jen do třech. Do sloupce
pocet_clanku
se vloží výchozí hodnota, tedy0
. - Do dotazu zde již potřebujeme vložit proměnné z PHP (konkrétně od
uživatele z pole
$_POST
).
Proměnné nikdy nevkládáme přímo do
dotazu! Kdyby uživatel zadal místo jména nějaký SQL příkaz, tak by se
totiž do dotazu vložil a provedl na naší databázi! Místo parametrů v
dotazu vždy píšeme otazníky a potom parametry předáme ve stejném pořadí
jako další parametry funkce Db::query()
! Tuto chybu zde neustále
opakují začátečníci stále a stále dokola, hazardujete se svými daty a
daty vašich uživatelů!
Ukažme si ještě raději, jak se to nemá dělat:
// TENTO KÓD JE VELMI NEBEZPEČNÝ! Db::query(' INSERT INTO uzivatele (jmeno, prijmeni, datum_narozeni) VALUES ("'. $_POST['jmeno'] . '", "' . $_POST['prijmeni'] . '", "' . $datum . '")');
Proměnné jsou vložené přímo v SQL dotazu. Když uživatel napíše do políčka pro jméno tento řetězec:
", "", ""); DELETE FROM uzivatele; --
Smaže nám všechny uživatele v databázi, protože co napsal se vloží přímo do dotazu a příkaz se vykoná. Tomuto útoku se říká SQL injection. Zrovna proti tomuto případu je náš wrapper imunní, jelikož jsou v něm určitá nastavení, která zrovna tento typ injekce nepovolí. Nejedná se však o výchozí nastavení a v žádném případě nezastaví další typy injekcí.
Kdykoli chceme do dotazu vložit nějaký parametr, použijeme otazník a napíšeme ho mimo dotaz! Databáze si tam potom parametr sama a bezpečně dosadí, nikdy to nedělejte za ni. Nikdy nepřerušujte řetězec s SQL dotazem.
Pro jistotu ještě jednou ta samá část kódu, tentokrát ale správně:
Db::query(' INSERT INTO uzivatele (jmeno, prijmeni, datum_narozeni) VALUES (?, ?, ?) ', $_POST['jmeno'], $_POST['prijmeni'], $datum);
Kód vyzkoušejme. Vložme nějakého uživatele:
Po odeslání formuláře:
A podívejme se do databáze, že v ní opravdu je:
Výpis dat
Do našeho jednoduchého skriptu přidejme ještě výpis dat z databáze do HTML tabulky. Tento PHP kód umístíme na konec dosavadního PHP bloku:
$uzivatele = Db::queryAll(' SELECT * FROM uzivatele '); echo('<h2>Uživatelé</h2><table border="1">'); foreach ($uzivatele as $uzivatel) { echo('<tr><td>' . htmlspecialchars($uzivatel['jmeno'])); echo('</td><td>' . htmlspecialchars($uzivatel['prijmeni'])); $datum = date("d.m.Y", strtotime($uzivatel['datum_narozeni'])); echo('</td><td>' . htmlspecialchars($datum)); echo('</td><td>' . htmlspecialchars($uzivatel['pocet_clanku'])); echo('</td></tr>'); } echo('</table>');
Nejdůležitější je volání funkce Db::queryAll()
. To
vykoná databázový dotaz, stejně jako funkce Db::query()
a
zároveň vrátí všechny řádky, které dotaz vybral. Budeme ji používat
při čtení a funkci Db::query()
budeme používat při zápisu
(přidání, editace, mazání).
Samotný SQL dotaz obsahuje jen 4 slova. Dal by se přeložit jako "Vyber
všechny sloupce z uživatelů". Právě hvězdička *
označuje
všechny sloupce. Jelikož neupřesňujeme kteří uživatelé nás zajímají,
vybere dotaz všechny řádky z tabulky.
Výsledkem dotazu je pole řádků, které si uložíme do proměnné
$uzivatele
. Následně pole proiterujeme pomocí cyklu
foreach
řádek po řádku a pro každý vyechujeme sloupeček do
HTML tabulky. Nezapomeneme používat funkci htmlspecialchars()
,
jinak by si někdo mohl do jména vložit JavaScript a ten by se poté při
výpisu jména spustil. Tomuto útoku se říká XSS (Cross-site
scripting).
Podívejme se na výsledek aplikace:
Můžete si zkusit přidávat uživatele, budou se objevovat v tabulce. To by bylo pro dnešní lekci vše. Doufám, že se mi podařilo prolomit ledy a že jste úspěšně vytvořili svou první databázovou aplikaci. Zdrojové kódy dnešní aplikace jsou jako vždy ke stažení v příloze.
V lekci příští, Programujeme neobjektový redakční systém v PHP (NERS), začneme pracovat na slíbeném redakčním systému.
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 3876x (3.48 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP