Pouze tento týden sleva až 80 % na e-learning týkající se Javy. A zároveň využij akce až 30 % zdarma při nákupu e-learningu - Více informací.
Hledáme koordinátorku kurzů a programátora, 100% home office, 100% flexibilní. Prozkoumej aktuální pozice
discount week 30 - hiring

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.


 

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 3546x (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
Přeskočit článek
(nedoporučujeme)
Programujeme neobjektový redakční systém v PHP (NERS)
Článek pro vás napsal David Čápka
Avatar
Uživatelské hodnocení:
60 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 let. Má rád Nirvanu, sushi a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity

 

 

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

Avatar
phpnoob
Člen
Avatar
phpnoob:8.10.2019 4:44

dakujem

 
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.2.2020 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.2.2020 22:37
Avatar
Miloshcz
Člen
Avatar
Miloshcz:25.4.2020 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.4.2020 23:29
Avatar
Odpovídá na Roman Zoufalý
Patrik Šimek:2.7.2020 18:24

jak jsi to dal na tu doménu?

 
Odpovědět
2.7.2020 18:24
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Pavel Kubalík:8.2.2021 14:44

Dobrý den
Když jsem ukončil kurz základů PHP, měl jsem dle doporučení v textu jít na tento kurz. Začal jsem to číst, a narazil jsem na slovo "wrapper". Toho jsem se lekl (protože jsem tomu nerozuměl) a tak jsem šel na kurz OOP. Když jsem se dostal ke "statice", zjistil jsem, že "wrapper" není žádné sprosté slovo, a že je vše v naprostém pořádku. Řekl jsem si, že nyní je nejvyšší čas dodělat si, čeho jsem se před tím lekl. Později bych se sem již nedokázal vrátit. Jsem tedy spokojen.
V této první půlce (lekce 1 - 3) jsem měl drobné problémy. Program jsem "naťukával ručně", ale v řádcích, kde bylo $_POST mi editor dával vykřičníky. Tak jsem to tam raději zkopíroval, ale vykřičníku jsem se nezbavil. Tak jsem to spustil, a ejhle, ono to chodilo. Tak nevím.
Už se těším na to, co je to ten NERS. Je dobré se těšit.
Děkuji PK

 
Odpovědět
8.2.2021 14:44
Avatar
Josef Šlejtr:29.3.2021 14:28

Ahoj, kurz je výborný a postupně se sám učím. Měl bych prosbu u radu. Chtěl bych vytvořit formulář kam chci vkládat vážení jednotlivých zvířat. Ćísla jednotlivých zvířat mám v databázi a seznam těchto zvířat se v čase mění. Do formuláře bych rád 2 sloupce. V jednom sloupci by bylo číslo zvířete (které by se natahovalo z databáze) a v druhém sloupci by se zapisovaly hmotnosti jednotlivých zvířat zjištěné při jednom vážení. Celé by s najednou odeslalo do databáze. Skript mám špatně, protož se do databáze vkládá vždy jen hmotnost posledního zvířete v seznamu. Poradí prosím někdo?

 echo "<table class='potomci'>";


 echo  "<form  method='post'>" ;


 $dat_vaz="2021-03-21";



 $datum_od = $rok."-01-01"; // časový interval výběru podle data narození zvířat do sestavy
 $datum_do = $rok."-12-31";


 $rph10_2019 = Db::queryAll


("SELECT * FROM $farmar


WHERE  datnar_farma between '$datum_od' AND '$datum_do'

ORDER BY zvire ASC");



echo

"<tr>
          <th> Číslo </th>

          <th> Hmotnost</th>


</tr>";

foreach ($rph10_2019 as $u)
                {


  echo "<tr>";


  $zvire=($u['zvire']);
  echo " <td class='stred'> ";
  echo " <input name='cislo_vaha' type='text' size='8' value='$zvire  '  /> </td>";

  echo " <td class='stred'> ";


  echo " <input name='vaha' type='text' size='4' value='$vaha'   /> </td>";
  $vaha=$_POST['vaha'];

  echo "</tr>";

  IF ($_POST)
  {
                        Db::query('
                                INSERT INTO vazeni_slejtr (cislo_vaha, dat_vaz, vaha  )
                                VALUES (?,?,?)

                        ',$zvire,
                           $dat_vaz, $_POST['vaha'] );
  }


           }

  echo "</table>";

echo  "<input type='submit' value='Vlož hlášení o vážení' /> ";

echo "</form>";
 
Odpovědět
29.3.2021 14:28
Avatar
Josef Šlejtr:29.3.2021 14:31

Jenom doplním , formulář mi správně vkládá sloupec s vygeerovanými čísly zvířat, ale nedaří se mi duehý sloupec s těmi hmotnostmi. Ty se zadávají do vlastního formuláře ručně.

 
Odpovědět
29.3.2021 14:31
Avatar
Dušan Kovářík:11.7.2021 2:36

Během této lekce jsem cítil, jak se mi vše konečně trochu dostává do krve. phpMyAdmin, wrapper, připojení k databázi, jednoduché SQL dotazy v PHP, bezpečnost... Díky za článek.

 
Odpovědět
11.7.2021 2:36
Avatar
Michal Gros
Redaktor
Avatar
Michal Gros :7. ledna 23:08

chybí mi doresení kontroly neprazdných input poli a kontrola datumu

Odpovědět
7. ledna 23:08
Jestli jste dobří nahrnou na Vás spoustu práce. Jestli jste sakra dobří, tak se jí dokážete zbavit.
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 98. Zobrazit vše