Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Pouze tento týden sleva až 80 % na e-learning týkající se Java. Zároveň využij akce až 80 % zdarma při nákupu e-learningu. Více informací:

Lekce 1 - Tvorba formulářového frameworku v PHP - Motivace

V dnešním tutoriálu začneme pracovat na minimalistické knihovně, která za nás vyřeší všechny starosti ohledně formulářů. Formuláře se ve webové aplikaci vyskytují velmi často a tvoří její značnou část. Uvidíte, že díky knihovně ve svých aplikacích ušetříte obrovské množství kódu a času. Protože nám její tvorba zabere hned několik dílů a bude se jednat o poměrně pokročilou věc, rozhodl jsem se celý dnešní díl věnovat motivaci, aby byla vidět její přidaná hodnota. Co se týče názvosloví, jedná se již spíše o menší framework než knihovnu, nicméně v seriálu budu tato označení zaměňovat.

Formuláře v čistém PHP

Ukažme si, co všechno musíme v čistém PHP napsat, abychom uložili několik políček z formuláře do databáze. Vše si budeme ukazovat na zjednodušeném formuláři pro objednání automobilu, který vypadá takto:

Tvorba formulářů v PHP

HTML kód

Jakmile tvoříme nějaký formulář, začínáme nejčastěji HTML kódem. Budeme chtít, aby formulář nějak vypadal a byl responzivní, proto musíme navíc použít nějaké divy a spany. Také budeme používat HTML 5 atributy pro klientské validace, které pro náš příklad maximálně zjednodušíme. Náš HTML kód bude vypadat takto:

<form method="POST" id="objednavka-auta" class="fancyform">
    <div class="form-component">
        <label for="jmeno">Jméno</label>
        <input name="jmeno" id="jmeno" required="required" type="text"/>
        <div class="clear"></div>
    </div>
    <div class="form-component">
        <label for="email">E-mail</label>
        <input name="email" id="email" type="email" />
        <div class="clear"></div>
    </div>
    <div class="form-component">
        <label for="znacka_vozu">Značka</label>
        <select name="znacka_vozu" id="znacka_vozu" required="required">
            <option value="skoda">Škoda</option>
            <option value="bmw">BMW</option>
            <option value="audi">Audi</option>
        </select>
        <div class="clear"></div>
    </div>
    <div class="form-component">
        <label for="nahon">Náhon</label>
        <select name="nahon" id="nahon" required="required">
            <option value="predni">Přední</option>
            <option value="zadni">Zadní</option>
            <option value="vse">Všechny</option>
        </select>
        <div class="clear"></div>
    </div>
    <div class="form-component">
        <label for="zpusob_platby">Způsob platby</label>
        <div name="zpusob_platby" id="zpusob_platby" class="radio-horizontal">
            <span>
                <input name="zpusob_platby" id="zpusob_platby1" value="prevodem" type="radio" checked="checked"/>
                <label for="zpusob-platby1">Převodem</label>
            </span>
            <span>
                <input name="zpusob_platby" id="zpusob_platby2" value="sekem" type="radio"/>
                <label for="zpusob_platby2">Šekem</label>
            </span>
            <span>
                <input name="zpusob_platby" id="zpusob_platby3" value="hotovost" type="radio"/>
                <label for="zpusob_platby3">V hotovosti</label>
            </span>
        </div>
        <div class="clear"></div>
    </div>
    <div class="form-component">
        <label for="poznamka">Poznámka</label>
        <textarea name="poznamka" id="poznamka"></textarea>
        <div class="clear"></div>
    </div>
    <div class="form-component">
        <label for="vybava">Výbava</label>
        <div name="vybava" id="vybava" class="radio-horizontal">
            <span>
                <input type="checkbox" name="abs" value="1" id="vybavaabs"/>
                <label for="vybavaabs">ABS</label>
            </span>
            <span>
                <input type="checkbox" name="sterace" value="1" id="vybavasterace"/>
                <label for="vybavasterace">Stěrače</label>
            </span>
            <span><input type="checkbox" name="asr" value="1" id="vybavaasr"/>
                <label for="vybavaasr">ASR</label>
            </span>
            <span>
                <input type="checkbox" name="eps" value="1" id="vybavaeps"/>
                <label for="vybavaeps">EPS</label>
            </span>
        </div>
        <div class="clear"></div>
    </div>
    <div class="form-buttons">
        <input name="objednat" id="objednat" value="Objednat" type="submit"/>
    </div>
</form>

Kód má zatím 74 řádek a zobrazuje 7 políček, to opravdu není efektivní. A bude hůř.

Validace

Data musíme zvalidovat znovu i na serveru, protože se na klientskou validaci nemůžeme spolehnout, ta slouží opravdu jen pro klienty, aby viděli, co mají špatně. Abychom se vyhnuli uložení nesmyslných hodnot do databáze, provedeme alespoň jednoduchou serverovou validaci:

if (isset($_POST['jmeno']) && ($_POST['jmeno']) &&
    (!isset($_POST['email']) || (preg_match('/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/u', $_POST['email']))) &&
    isset($_POST['znacka_vozu']) && ($_POST['znacka_vozu']) &&
    isset($_POST['nahon']) && ($_POST['nahon']) &&
    isset($_POST['zpusob_platby']) &&
    isset($_POST['poznamka']) &&
    isset($_POST['vybava']))

Jsme na 81 řádcích.

Uložení hodnot do databáze

Objednávku uložíme do databáze následovně:

Db::dotaz('
    INSERT INTO `objednavka` (jmeno, email, znacka_vozu, nahon, zpusob_platby, poznamka, vybava)
    VALUES
    (?, ?, ?, ?, ?, ?, ?)
', $_POST['jmeno'], $_POST['email'], $_POST['znacka_vozu'], $_POST['nahon'], $_POST['zpusob_platby'], $_POST['poznamka'], $_POST['vybava']);

Celkem 86 řádků pro vložení sedmi políček do databáze.

Formulářová knihovna

Nyní si ukažme, jak by vypadalo zpracování identického formuláře pomocí naší knihovny.

Definice formuláře

Formulář vytvoříme jako instanci třídy Form a přidáme do něj jednotlivá pole:

$form = new Form('objednavka-auta');
$form->addTextBox('jmeno', 'Jméno', true);
$form->addEmailBox('email', 'E-mail', false);
$form->addComboBox('znacka_vozu', 'Značka', true)
    ->setValues(array(
        'Škoda' => 'skoda',
        'BMW' => 'bmw',
        'Audi' => 'audi',
    ));
$form->addComboBox('nahon', 'Náhon', true)
    ->setValues(array(
        'Přední' => 'predni',
        'Zadní' => 'zadni',
        'Všechny' => 'vse',
    ));
$form->addRadioGroup('zpusob_platby', 'Způsob platby', true)
    ->setValues(array(
        'Převodem' => 'prevodem',
        'Šekem' => 'sekem',
        'V hotovosti' => 'hotovost',
    ));
$form->addTextArea('poznamka', 'Poznámka', false);
$form->addCheckList('vybava', 'Výbava')
    ->setValues(array(
        'ABS' => 'abs',
        'Stěrače' => 'sterace',
        'ASR' => 'asr',
        'EPS' => 'eps',
    ));
$form->addButton('objednat', 'Objednat');

Zatím máme 29 řádek pro 7 polí, což je dobrý poměr. Řádky navíc jsou jen možnosti k výběru.

HTML kód

HTML kód se vygeneruje plně automaticky, stačí pouze zavolat metodu render() na instanci formuláře:

<?= $form->render() ?>

Validace

Serverové validace proběhnou plně automaticky při prvním pokusu o čtení hodnot z formuláře.

Uložení hodnot do databáze

Pokud formulářový framework použijeme spolu s místním databázovým frameworkem, bude uložení dat do databáze vypadat následovně:

Db::insert('objednavka', $form->getData());

Celková velikost kódu: 31 řádků oproti 86 řádkům bez použití frameworku. Přes 60% kódu jsme úplně vyhodili a nestalo se vůbec nic. Za zbylý čas bychom napsali ještě další 2 formuláře. Příklad byl opravdu velmi zjednodušený, v praxi by byly rozdíly na větších formulářích a složitějších validacích ještě markantnější.

Další funkce

Formulářový framework samozřejmě umí i spoustu dalších věcí, kterými jsem příklad nechtěl zatěžovat:

  • Další pole - Nabízí nám další formulářová pole, jako ListBox, FileBox, PasswordBox a podobně.
  • Částečný rendering - Formulář lze vyrenderovat i po částech, když chceme např. jiný layout, někde obrázek nebo nadpisy, rozdělit formulář na více stránek, nějaká speciální JavaScriptová tlačítka a tak dále.
  • Více formulářů - Knihovna se jednoduše vypořádá s několika formuláři na jedné stránce.
  • Načtení jen části dat - Metodou getData() můžeme získat i jen část dat. To využijeme v případě, když jsou ve formuláři pole, která do databáze ukládat nechceme (např. captcha).
  • Naplnění formuláře daty - Metodou setData() naplníme formulář výsledkem dotazu z databáze, což se využije např. při editaci záznamů.

A to hlavní: Knihovna je minimalistická a je navržena tak, aby ji šlo jednoduše rozšiřovat a upravovat. To vše by nás mělo dostatečně motivovat k jejímu využití.

Příště, v lekci Tvorba formulářového frameworku v PHP - HtmlBuilder, se pustíme do první pomocné třídy, kterou bude HtmlBuilder.


 

Všechny články v sekci
Pokročilá obsluha formulářů v PHP
Přeskočit článek
(nedoporučujeme)
Tvorba formulářového frameworku v PHP - HtmlBuilder
Článek pro vás napsal David Čápka
Avatar
Uživatelské hodnocení:
20 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 let. Má rád Nirvanu, nemovitosti 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