Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

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

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

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 2151x (3.24 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
32 hlasů
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.
Aktivity (1)

 

 

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

Avatar
IT Man
Redaktor
Avatar
IT Man:15. února 6:25

Na Google toho najdeš dost. :)
Když už ale odpovídám, chyba je v tom, že sloupec mob_jmeno nemůže mít nullovou hodnotu. Nejdřív ji musíš povolit v databázi u toho sloupce. ;)

Odpovědět 15. února 6:25
Cokoliv a kdokoliv může jednou uspět.
Avatar
Pavel Šrytr
Člen
Avatar
Pavel Šrytr:18. března 18:12

Chybí ti heslo,mělo by to vypadat takto:

Db::connect('127­.0.0.1','data­baze_pro_web',­'root','');

 
Odpovědět 18. března 18:12
Avatar
Petr Vocel
Redaktor
Avatar
Petr Vocel:17. dubna 16:41

Ahoj,
napřed bych poděkoval za práci, kterou děláš, protože jako starý vlk dovedu ocenit její náročnost a hodnotu.
Ale k příkladu. Mě to pokud jsem nepřidal definici časové zöny

date_default_ti­mezone_set("E­urope/Prague");

házelo tuhle hlášku:
Warning: strtotime(): It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_ti­mezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in C:\xampp\htdoc­s\databaze1\in­dex.php on line 23

A protože se dřív a možná i teď dává občas datum ve tvaru s lomítky, tak v praxi by to chtělo přidat překlad parametrů (lomítka na tečky)
$datumtext= str_replace('/', '.',$_POST['da­tum_narozeni']);
a výsledek použít jako vstup do "strtotime"
Osobně jako starý vlk moc vkládání příkazů do sebe (když to není nutné) nepodporuji. Hůř se pak hledají chyby.

 
Odpovědět 17. dubna 16:41
Avatar
Libor Sitek
Člen
Avatar
Libor Sitek:26. června 17:20

Ahoj, nějak nerozumím proč se do proměnné $datum ukládá i časový údaj, má to nějaký význam? Nebo by stačilo napsat řádek i takto:

$datum = date("Y-m-d", strtotime($_POST['datum_narozeni']));
 
Odpovědět 26. června 17:20
Avatar
gorri
Člen
Avatar
Odpovídá na Libor Sitek
gorri:26. června 17:30

To by asi stačilo. David jen počítal asi i s tím, že by někdo chtěl používat i čas ;-)

Odpovědět 26. června 17:30
Když vím, tak poradím. Nikdo neví všechno :-)
Avatar
drabek
Člen
Avatar
drabek:9. července 11:02

Prosím o radu, když vložím kód do html souboru v NETBEANS, vypíše se následující stránka, po vyplnění formuláže a kliknutím na tlačítko Registrovat stránka jen problikne a do databáze se nic nepřidá.

Registrace uživatele
Byl jste úspěšně zaregistrován.

'); } ?>
Jméno:

Příjmení:

Datum narození:

 
Odpovědět 9. července 11:02
Avatar
Jiří Zeman
Člen
Avatar
Odpovídá na drabek
Jiří Zeman:6. srpna 18:03

Nemůžeš vkládat kód do .html souboru, ale do .php souboru. Stáhni si příklad a uvidíš to :). Kde se pracuje s PHP tak se vytvářejí .php soubory. Nebo teda myslím... Už jsem dlouho s .html soubory nepracoval. Jestli se pletu omlouvám se.

 
Odpovědět 6. srpna 18:03
Avatar
michal.cepelak:1. září 8:36

Zdravím,
jak u tohoto příkladu zjistím vložené hodnoty.
u mysql_query jsem to dělal

$sql=('select ...');
echo $sql;
die;

U PDO to provedu jak?
Děkuji za radu

 
Odpovědět 1. září 8:36
Avatar
Odpovídá na michal.cepelak
Michal Šmahel:1. září 20:21

Ahoj, je to jednoduché (a David to krásně popisuje v článku. Pokud používáš zdejší PDO wrapper (obal), asi takto:

// Načtení wrapperu
require_once('Db.php');
// Vytvoření spojení
Db::connect('127.0.0.1', 'databaze_pro_web', 'root', '');

// Dotaz na více výsledků
$poleVysledku = Db::queryAll("
    SELECT ...
");

Pokud ho nepoužíváš (a svůj zřejmě nemáš), asi takto:

// Vytvoření spojení
$db = new PDO(...);

// Dotaz na více výsledků
$dotaz = $db->prepare("
    SELECT ...
");
$dotaz->execute([$data1, $data2, ...]);
$poleVysledku = $dotaz->fetchAll();
Odpovědět 1. září 20:21
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
teofil
Člen
Avatar
teofil:12. října 8:45

Řešil někdo u tohoto příkladu ošetření proti zapsání "prázdných" dat? Mně to prázdné záznamy zapisuje s datem 01.01.1970.

Editováno 12. října 8:46
 
Odpovědět 12. října 8:45
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 64. Zobrazit vše