ITnetwork summer 2020
80 % bodů zdarma na online výuku díky naší Letní akci!
Pouze tento týden sleva až 80 % na e-learning týkající se PHP

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í:

  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 . '")');
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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
localhost
Registrace uživatele
localhost

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:

Registrace uživatele
localhost

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

 

Předchozí článek
První databázová tabulka a MySQL ovladače v PHP
Všechny články v sekci
Databáze v PHP pro začátečníky
Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
50 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 sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity (6)

 

 

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

Avatar
Jiří Hruška:11.5.2019 11:44

Ahoj, potřeboval bych zjístit jak mohu vypsat do <select><option> // vypsat všechny registrované. Lze to udělat nějak jednoduše? Díky

 
Odpovědět
11.5.2019 11:44
Avatar
Jaroslav Smrž
Super redaktor
Avatar
Jaroslav Smrž:11.5.2019 11:52

Ahoj, pokud používáš místní DB wrapper, tak kód by mohl vypadat následovně:

<select name="kategorie" class="form-control">
        <?php
        $dropdown = DB::QueryAll('SELECT kat_nazev FROM kategorie');
                foreach ($dropdown as $drop){
                        echo('<option>');
                        echo(htmlspecialchars($drop['kat_nazev']));
                        echo('</option>');
                }
        ?>
</select>
Odpovědět
11.5.2019 11:52
/* Life runs on code */
Avatar
Stivko
Člen
Avatar
Stivko:14.6.2019 20:06

Super návod :) Zatím perfektně chápu.

Odpovědět
14.6.2019 20:06
Nikdy není pozdě začít s něčím novým
Avatar
phpnoob
Člen
Avatar
phpnoob:7.10.2019 11:30

výborné , ďakujem . pustím sa asi na ners. čo znamená $u ?a to foreach ($uzivatele as $u) , nevidím to nikde vysvetlené. BTW keď som aktualizoval formuluár tak sa mi tam nezobrazil nový input , chcel som pridať aby som mohol vkládať cez formulár aj počet článkov ktoré si zvolím , no neaktualizovala sa stránka .. neaktualizovala sa ani po tom čo som odstránil všetky vstupy , proste tie inputy zostali tam .. samozrejme ulozil som súbor a refreshol som stránku ale nepomohlo to

 
Odpovědět
7.10.2019 11:30
Avatar
Jaroslav Smrž
Super redaktor
Avatar
Odpovídá na phpnoob
Jaroslav Smrž:7.10.2019 12:38

Foreach je cyklus, znamená to, že vypíše všechny záznamy, ne jen první na který narazí.

($uzivatele as $uzivatel)

je podmínka pro foreach, aby se dalo pracovat s každým jednotlivým záznamem samostatně.
Pak třeba vybereš jen

$uzivatel['jmeno'];
Odpovědět
7.10.2019 12:38
/* Life runs on code */
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
phpnoob
Člen
Avatar
 
Odpovědět
8.10.2019 4:44
Avatar
Míra Balej
Člen
Avatar
Míra Balej:19.10.2019 17:33

Tuší někdo, zda lze tento wrpper použít pro dotaz na více tabulek? Něco jako SELECT FROM tab1 UNION SELECT FROM tab2? Jaká je pak syntaxe dotazu?

 
Odpovědět
19.10.2019 17:33
Avatar
Roman Zoufalý:12. února 22:37

Ahoj,
když zkouším ve 3.části manuálu ( díky moc za něj, dobrá práce ) výpis a dám na stránce refresh ( F5 ), tak se mi znovu přidají původně vkládané hodnoty do tabulky i když jsou pole v tu chvíli prázdná. Jak to?
Díky za reakci :-)

 
Odpovědět
12. února 22:37
Avatar
Miloshcz
Člen
Avatar
Miloshcz:25. dubna 23:29

Ahoj, mohl bych požádat o radu?
Mám kod

$tabulka = Db::queryall('SELECT MONTHNAME(Mesic), SUM(Pocet1), SUM(Pocet2), SUM(Pocet3), SUM(Pocet4), SUM(Pocet5), SUM(Celkem1), SUM(Celkem2), SUM(Celkem3), SUM(Celkem4), SUM(Celkem5) FROM `uctenka` GROUP BY (Mesic)');

echo(' <h2>Souhrn </h2><table class="table table-bordered"><tr><td><b style="text-align: center">měsíc vystavení</td><td><b> Z</td><td><b>M</td><td><b>D</td><td><b>T</td><td><b>Ostatní</td><td><b>celkem za měsíc</td></tr>');

foreach ($tabulka as $c);
echo var_dump($tabulka)."<br>";
echo ("as c"). "<br>";
echo var_dump($c)."<br>";

 {
    echo('<tr><td>' . htmlspecialchars($c ["MONTHNAME(Mesic)"]));
        echo('</td><td>' . htmlspecialchars($c ["SUM(Pocet1)"]));
        echo('</td><td>' . htmlspecialchars($c ["SUM(Pocet2)"]));
        echo('</td><td>' . htmlspecialchars($c ["SUM(Pocet3)"]));
        echo('</td><td>' . htmlspecialchars($c ["SUM(Pocet4)"]));
        echo('</td><td>' . htmlspecialchars($c ["SUM(Pocet5)"]));
        echo('</td><td>' . htmlspecialchars($c ["SUM(Celkem5)"] )); echo (",- Kč") ;


     echo('</td></tr>');
    }
echo('</table>');

Nemůžu však dostat do tabulky výpis všech řádků. SQL dotaz vrátí všechny řádky, echo var_dump pro $tabulka vrátí všechny hodnoty, ale pokud zadám echo var_dump pro $c tak mi vyjede poslední řádek jako se mi zobrazuje v tabulce. At hledám jak hledám, nemůžu zjistit kde může být chyba.

díky za radu

 
Odpovědět
25. dubna 23:29
Avatar
Odpovídá na Roman Zoufalý
Patrik Šimek:Včera 18:24

jak jsi to dal na tu doménu?

 
Odpovědět
Včera 18:24
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 93. Zobrazit vše