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"> Jméno:<br /> <input type="text" name="jmeno" /><br /> Příjmení:<br /> <input type="text" name="prijmeni" /><br /> Datum narození:<br /> <input type="text" name="datum_narozeni" /><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() a date().
- 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, tedy 0.
- Do dotazu zde již potřebujeme vložit proměnné z PHP (konkrétně od uživatele z $_POST). A nyní pozor: 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 tak, jak se 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:
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 $u) { echo('<tr><td>' . htmlspecialchars($u['jmeno'])); echo('</td><td>' . htmlspecialchars($u['prijmeni'])); $datum = date("d.m.Y", strtotime($u['datum_narozeni'])); echo('</td><td>' . htmlspecialchars($datum)); echo('</td><td>' . htmlspecialchars($u['pocet_clanku'])); echo('</td></tr>'); } echo('</table>');
Nejdůležitější je volání funkce Db::queryAll(). To vykoná databázový dotaz, stejně jako Db::query() a zároveň vrátí všechny řádky, které dotaz vybral. Budeme ji používat při čtení a 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í foreach cyklu řá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.
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.
Stáhnout
Staženo 3387x (3.24 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP
Komentáře


Zobrazeno 10 zpráv z 94. Zobrazit vše