3. díl - Formulář a výpis dat z databáze do tabulky v PHP

PHP Databáze pro začátečníky Formulář a výpis dat z databáze do tabulky v PHP American English version English version

V minulém dílu seriálu tutoriálů o databázích v PHP pro úplné začátečníky 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í:

  1. 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().
  2. 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.
  3. 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:

Registrace uživatele v PHP
Registrace uživatele v PHP

A podívejme se do databáze, že v ní opravdu je:

Uživatelé v MySQL databázi

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:

Správa uživatelů v PHP

Můžete si zkusit přidávat uživatele, budou se objevovat v tabulce. To by bylo pro dnešní díl vše. Doufám, že se mi podařilo prolomit ledy a že jste úspěšně vytvořili svou první databázovou aplikaci. Příště začneme pracovat na slíbeném redakčním systému. Zdrojové kódy dnešní aplikace jsou jako vždy ke stažení v příloze.


 

Stáhnout

Staženo 1685x (3.24 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (24 hlasů) :
4.958334.958334.958334.958334.95833


 



 

 

Komentáře
Zobrazit starší komentáře (42)

Avatar
petr.jouza
Člen
Avatar
petr.jouza:

Ještě se předem omlouvám za to neodkomentování komentáře z první ukázky... :)

 
Odpovědět 14. července 17:50
Avatar
jirka.skop
Člen
Avatar
Odpovídá na petr.jouza
jirka.skop:

Díky,něco takového jsem potřeboval,těť to pořádně prostuduju a můžu pokračovat.

 
Odpovědět 14. července 21:19
Avatar
Bartoloměj Eliáš:

Mockrát děkuji, pochopitelně vysvětleno.

 
Odpovědět 11. září 22:36
Avatar
Zdenek
Člen
Avatar
Zdenek:

Ahojte, prosím o pomoc. Snažím se rozchodit formulář, ale někde asi dělám chybu. Mám stažené odtud soubory, ale nefunguje mi přidávání jmen do databáze. Výsledek je:

Editováno 17. září 21:23
 
Odpovědět 17. září 21:22
Avatar
Zdenek
Člen
Avatar
Odpovídá na Zdenek
Zdenek:

Tady je stažený zdroják:

<!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($_POS­T['datum_naro­zeni']));
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:

<input type="text" name="jmeno" />

Příjmení:

<input type="text" name="prijmeni" />

Datum narození:

<input type="text" name="datum_na­rozeni" />

<input type="submit" value="Registrovat" />
</form>

</body>
</html>

Editováno 18. září 7:41
 
Odpovědět 18. září 7:39
Avatar
Vít Vohralík:

Mám to úplně přesně napsaný jako tady ale nefunguje mi to. Píše to tuto chybu:

 
Odpovědět 11. října 17:07
Avatar
IT Man
Redaktor
Avatar
Odpovídá na Vít Vohralík
IT Man:

Nemáš vytvořenou databázi 'databaze_pro_web'.

Odpovědět 11. října 17:22
Když nevíš jak dál, podá ti ruku někdo, od koho by jsi to nečekal. A tu šanci musíš přijmout!
Avatar
Stanislav Čaja:

Zdravím, rád bych poprosil o radu. Při spuštění i staženého souboru tady odsud se setkávám s tímto errorem. Neví někdo co s tím?

 
Odpovědět 18. listopadu 14:11
Avatar
Stanislav Čaja:

Předchozí problém jsem opravil. Narazil jsem na další při stisknutí tlačítka "registrovat" se absolutně nic nestane, ano stránka problikne, ale již se údaje nezapíší do databáze ani se nevypíše "Byl jste úspěšně zaregistrován." Opět celé to testuji na stažené souboru. Takže chybu jsem nemohl udělat, nevíte čím by to mohlo být?
Předem děkuji. :)

 
Odpovědět 18. listopadu 17:02
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

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