Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET. Zároveň využij akci až 30 % zdarma při nákupu e-learningu - Více informací.
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í.
discount 30 + hiring

Lekce 5 - Kontaktní formulář

V minulé lekci, Propojení kontroleru a pohledu, jsme propojili pohled s kontrolerem. Dokonce jsme také přidali již jednu součást webu, kterou je chybová stránka.

V dnešním dílu si do webu zkusíme naprogramovat od nuly novou funkčnost po vzoru MVC. Půjde o kontaktní formulář. V principu nás již nic nového nepotká, základ systému máme hotový.

Šablona

Ve složce pohledy/ si vytvořme kontakt.phtml, kam vložíme jednoduchý HTML kód s formulářem. Formulář bude obsahovat pole pro e-mailovou adresu návštěvníka (abychom mu mohli odpovědět), dále pole pro antispam (realizujeme jako zadání aktuálního roku), textové pole se zprávou a odesílací tlačítko.

<h1>Kontaktní formulář</h1>

<p>Kontaktujte nás odesláním formuláře níže.</p>

<form method="post" id="form-email">
    Vaše emailová adresa<br />
    <input type="email" name="email" required="required" value="<?php if (isset($_POST['email'])) echo(htmlspecialchars($_POST['email'])); ?>" /><br />
    Antispam - zadejte aktuální rok<br />
    <input type="text" name="rok" required="required" /><br />
    <textarea name="zprava"><?php if (isset($_POST['zprava'])) echo(htmlspecialchars($_POST['zprava'])); ?></textarea><br />
    <input type="submit" value="Odeslat" />
</form>

Kód je jen čisté HTML. Všimněte si využití HTML5 validátorů. Validovat bychom měli i na straně PHP, ale to nyní opomeneme. Formulář jsme vytvořili opravdu co nejjednodušeji, nepoužili jsme v něm labely a rozložení jsme docílili pouze pomocí <br />. Pokud uživatel již odeslal nějaká data a server je odmítl, měla by aplikace tato data znovu vložit do formuláře, k tomu ty funkce echo(). Pro složitější formuláře by se vyplatilo používat knihovnu, která ho sama vygeneruje a také po odeslání zvaliduje i na serveru, případně sama vyplní. To je ale v současné době nad rámec našich schopností, až budete pokročilejší, můžete se podívat do místní sekce PHP knihovny, kde se taková knihovna vyrábí.

Aby formulář nějak vypadal, přidáme nějaké minimum stylů do našeho style.css:

input[type="submit"] {
    background: #6FA4F8;
    color: white;
    padding: 5px 10px;
    border-radius: 10px;
    border: 0px;
}

input[type="submit"]:hover {
    background: #2976f8;
    color: #EEEEEE;
    cursor: pointer;
}

input[type="text"], input[type="email"], input[type="password"] {
    width: 250px;
    border-radius: 5px;
    border: 1px solid #aaaaaa;
    padding: 0.3em;
}

input[type="submit"] {
    padding: 10px 25px;
    display: block;
    margin: 0 auto;
    margin-top: 20px;
    font-weight: bold;
}

textarea {
    border-radius: 5px;
    border: 1px solid #aaaaaa;
    width: 483px;
    height: 90px;
}

Model

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

K odeslání e-mailu je zapotřebí nějaká logika. Veškerou logiku aplikace budeme psát do modelů. Kontrolery často svádí k jejich přetěžování a začátečníci se do nich snaží psát i logiku, ale nesmíme zapomínat na to, že slouží jen k propojení. Jediné, čím se zatěžují, je zpracování parametrů od uživatele a volání příslušné logiky, která už není jejich součástí.

Vytvoříme si tedy model pro odeslání emailu na určitou adresu. Do složky modely/ si přidejte soubor OdesilacEmailu.php. Bude v něm následující třída:

class OdesilacEmailu
{

    /**
     * Odešle email jako HTML, lze tedy používat základní HTML tagy a nové
     * řádky je třeba psát jako <br /> nebo používat odstavce. Kódování je
     * odladěno pro UTF-8.
     * @param string $komu E-mailová adresa příjemce
     * @param string $predmet Předmět e-mailu
     * @param string $zprava Obsah e-mailu jako HTML řetězec
     * @param string $od E-mailová adresa odesílatele
     * @return bool TRUE, pokud se odeslání e-mailu podařilo, FALSE, pokud ne
     */
    public function odesli(string $komu, string $predmet, string $zprava, string $od) : bool
    {
        $hlavicka = "From: " . $od;
        $hlavicka .= "\nMIME-Version: 1.0\n";
        $hlavicka .= "Content-Type: text/html; charset=\"utf-8\"\n";
        return mb_send_mail($komu, $predmet, $zprava, $hlavicka);
    }

}

Třída obsahuje pouze jednu metodu odesli(), která bere v parametrech adresu příjemce, předmět, zprávu a adresu odesílatele. Uvnitř sestavíme hlavičku a email odešleme pomocí funkce mb_send_mail(). Ta obaluje obyčejnou PHP funkci mail() a dodává jí podporu UTF-8 kódování.

Ti bystřejší si všimli, že email se posílá jako HTML. Všechny emaily v našem redakčním systému budeme posílat jako HTML, máme tak možnost psát klasický text i text nějak ozdobený. Pouze nesmíme zapomínat, že místo \n píšeme <br />;.

Kontroler

Nakonec vytvoříme onoho prostředníka, kterým bude KontaktKontroler. Uveďme si rovnou celý jeho kód, který si záhy popíšeme:

<?php

class KontaktKontroler extends Kontroler
{
    public function zpracuj(array $parametry) : void
    {
        $this->hlavicka = array(
            'titulek' => 'Kontaktní formulář',
            'klicova_slova' => 'kontakt, email, formulář',
            'popis' => 'Kontaktní formulář našeho webu.'
        );

        if (isset($_POST["email"]))
        {
            if ($_POST['rok'] == date("Y"))
            {
                $odesilacEmailu = new OdesilacEmailu();
                $odesilacEmailu->odesli("[email protected]", "Email z webu", $_POST['zprava'], $_POST['email']);
            }
        }

        $this->pohled = 'kontakt';
    }
}

KontaktKontroler dědí z Kontroler a implementuje metodu zpracuj(). Pokud jsme u metody v rozšiřované třídě specifikovali datový typ parametrů, nebo návratový datový typ, musíme přesně ty samé datové typy specifikovat i ve třídě, která rodičovskou třídu rozšiřuje. V metodě nastavíme nějakou hlavičku a podíváme se, zda přišel formulář. Pokud ano, zkontrolujeme rok. Při úspěchu vytvoříme model OdesilacEmailu a předáme mu parametry od uživatele. Samotnou logiku již provede model, kontroler ho pouze volá. Nakonec nastavíme pohled na "kontakt". "[email protected]" si samozřejmě nahraďte svým emailem.

Můžeme novou stránku vyzkoušet, přejděme na URL /kontakt a měli bychom vidět něco takového:

Kontaktní formulář
localhost/kontakt

Princip jak náš redakční systém ke stránce došel je snad jasný, ale opakování je matka moudrosti. Směrovač podle prvního parametru v URL ("kontakt") zjistí, voláme KontaktKontroler a předá mu řízení aplikace. Pokud jsme formulář již odeslali, KontaktKontroler vytvoří model OdesilacEmailu a předá mu data od uživatele. Model e-mail s daty odešle. Kontroler nakonec vypíše svou šablonu.

Pokud nemáte na localu zprovozněný SMTP server, email vám nedorazí a budete si aplikaci muset vyzkoušet na produkci nebo mi věřit, že je to takhle správně :)

Zprávy

Bylo by opravdu skvělé, kdybychom po odeslání emailu zobrazili uživateli zprávu, že byl odeslán. Nebo naopak, že se to z nějakého důvodu nepovedlo. Pokazit se mohlo samotné odesílání nebo uživatel špatně zadal antispamovou kontrolu. Jistě bychom mohli do šablony vložit nějakou proměnnou s textem zprávy a v EmailKontroler ji nastavovat. Takovou funkčnost ale jistě nebudeme potřebovat jen zde, ale v mnoha dalších kontrolerech a modelech. Proto zobrazování zpráv integrujeme do našeho redakčního systému.

V další lekci, Založení databáze a přístupy k ní v PHP, si připravíme databázi a pobavíme se o možných přístupech k ní.


 

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

 

Předchozí článek
Propojení kontroleru a pohledu
Všechny články v sekci
MVC - Jednoduchý redakční systém v PHP objektově
Přeskočit článek
(nedoporučujeme)
Založení databáze a přístupy k ní v PHP
Článek pro vás napsal David Čápka
Avatar
Uživatelské hodnocení:
48 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 (33)

Avatar
David Čápka
Tým ITnetwork
Avatar
David Čápka:13.5.2019 9:37

Tvoje řešení je hezký. Dále v navazujícím kurzu se to pak i podobně dělá (formuláře se wrappují do třídy a s POST se již nepracuje). Tady mi to přišlo ještě OK.

Odpovědět
13.5.2019 9:37
One of the most common causes of failure is the habit of quitting when one is overtaken by temporary defeat.
Avatar
Otvorený Zdroj
Supertvůrce
Avatar
Otvorený Zdroj:17.5.2019 4:11

Citujem z Lekcie 1

Pohled přijme data od kontroleru a vloží je do připravené šablony. Hotová stránka je zobrazena uživateli, který často o celé této kráse ani netuší :)

A kde je konkrétne napísané ako pohled prijme data od kontroleru?? Kontroler ukladá data do premenných to mi je jasné....

// Nastavení proměnných pro šablonu.... SmerovacKontroler si ukladá data z vnoreného kontroleru
                $this->data['titulek'] = $this->kontroler->hlavicka['titulek'];
                $this->data['popis'] = $this->kontroler->hlavicka['popis'];
                $this->data['klicova_slova'] = $this->kontroler->hlavicka['klicova_slova'];

Skôr vychádza že kontroler prijíma data a metodou vypisPohled() na premenné iba odkazuje ($this->data) a ($this->pohled). Pohled (Šablona) si premenne len dosadí...

Otazkou vlastne je, či je vôbec vhodne písat, že pohled prijíma data od kontrolera.Ked jedine kontroler prijíma data a ukladá ich do premennych a potom na ne odkazuje. Tým, že kontroler zobrazí vystúp, pohled o kontrolerovi nevie, čiže pohled nevie co ma prijat.... len vie co ma dosadiť. Preto sa mi zdá..ze medzi pohľadom a kontrolerom je to trochu abstraktné :-), alebo Davidove texty:-)?

Odpovědět
17.5.2019 4:11
Ak existuje voľná energia, tak autorské právo sú dve smiešne slová..
Avatar
Michal Šmahel:18.5.2019 14:17

Ahoj, bylo by lepší hned v původním příspěvku zmínit danou citaci, aby bylo jasné, co hodláš rozebírat. Navíc se jedná o 5. lekci, komentář patří tedy trochu jinam.

Pro úplné pochopení této problematiky je třeba znát princip funkčnosti include a require, tedy skládání souborů se zdrojovým kódem v PHP. Načtení pohledu a předání dat funguje právě na tomto principu. Zakládá to na tom, že když připojíš HTML soubor nebo soubor generující HTML kód, tento kód se přidá k tomu, co se odešle klientovi. Předání dat funguje tak, že se v kontroleru rozbalí pole s získanými daty od dílčích kontrolerů. Jelikož je PHP kód ve výsledku všechen v jednom souboru (include a require vlastně jen připojují obsah daného souboru k prvnímu souboru, který byl načten), jsou proměnné rozbalené v kontroleru dostupné i v šabloně.

Ještě tě zajímalo, jak řídící kontroler data získá. Je to poměrně jednoduché. Dílčí kontrolery (ty, které tento řídící vytvoří a zavolá na nich zpracování) získaná data ukládají do třídní vlastnosti $data (pole). Tato vlastnost je veřejná, je k ní tedy možnost přistupovat zvenčí - například z řídícího kontroleru. Dále je tu vlastnost $head, do níž dílčí kontrolery ukládají údaje do HTML hlavičky. Za funguje stejně. Řídící kontroler si jen data přečte z těchto vlastností a uloží si je do své vlastnosti data (samozřejmě dojde k jejich spojení). Z této vlastnosti jsou poté rozbaleny na jednotlivé proměnné (název klíče = název proměnné) a použity v šabloně.

David to v článku popisuje správně. Pro lepší pochopení architektury (MVC) využívá určité abstrakce, kdy nenazývá věci podle implementace, ale filozofie architektury. Implementaci však také podrobně popisuje, problém bych v tom neviděl.

Odpovědět
18.5.2019 14:17
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
Odpovídá na Otvorený Zdroj
Michal Šmahel:18.5.2019 14:20

Zapomněl jsem tě označit.

Odpovědět
18.5.2019 14:20
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
Otvorený Zdroj
Supertvůrce
Avatar
Otvorený Zdroj:13.6.2019 4:06

Cely systém funguje napr. z podzlozky cms na localhost v XAMPP v3.22 , na adrese (http://localhost/cms) pri tychto zmenach:

1. V subore Kontroler.php iba pridame nazov zlozky do url:

public function presmeruj($url)
        {
                         // tu pridame nazov zlozky cms do url
                header("Location: /cms/$url");
                header("Connection: close");
        exit;
        }

2.V súbore SmerovacKontro­ler.php, doplnime:

private function parsujURL($url)
        { ...
// tu doplnime funkciu, ktora odstrani prvu hodnotu z pola,  v nasom pripade cms..
array_shift($rozdelenaCesta);
return $rozdelenaCesta;
}

3. V subore rozlozeni.phtml nastavime cestu ku korenovej zlozke:

<base href= "/cms/" />

... vsetko...plati aj pre webhosting

Poznamka: Zmeny v suboroch je lepsie vykonat cez NetBeans, pretoze klasicky Notepad pri zmenach v suboroch pridava biele znaky, alebo ine neviditelne znaky, ktore napr. pri ostrom webhosting budú vypisovat chybu 500. Treba sa ujistit.ci sa nepridavaju neviditelne znaky pri zmenach v suboroch.Pokial sa pridavaju system nebude fungovat...
Subor htacces nie je potrebne menit.Vynimocne mozete skusit odkomentovat # RewriteBase / ak by vam system na webhostingu nefungoval, osobne som to vsak nepotreboval. System funguje aj pod PHP 5.6, PHP 7.1 PHP 7.2, PHP 7.3

Odpovědět
13.6.2019 4:06
Ak existuje voľná energia, tak autorské právo sú dve smiešne slová..
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Otvorený Zdroj
Supertvůrce
Avatar
Otvorený Zdroj:13.6.2019 4:23

Ked chceme aby redakcny system fungoval na subdomene webhostingu napr. na adrese

http://cms.nazov_domeny.sk alebo https://cms.nazov_domeny.sk

1.V administracii webhostingu vytvorime korenovu zlozku pre subdomenu:cms­.nazov_domeny­.sk

2.V subore rozlozeni.phtml zmenime korenovu zlozku :

<base href="http://cms.nazov_domeny.sk/" />
// alebo
<base href="https://cms.nazov_domeny.sk/" />

......vsetko...

Editováno 13.6.2019 4:26
Odpovědět
13.6.2019 4:23
Ak existuje voľná energia, tak autorské právo sú dve smiešne slová..
Avatar
FiftypiSoftware
Supertvůrce
Avatar
Odpovídá na Otvorený Zdroj
FiftypiSoftware:25.8.2019 12:50

Ahoj, díky, toto jsem hledal. Zkoušel jsem x možností, ale array_shift($roz­delCesta); mě nenapadlo. Vždycky přesmerování skončilo chybou too_many_redirects.

 
Odpovědět
25.8.2019 12:50
Avatar
Libor Melich
Člen
Avatar
Libor Melich:31.7.2020 18:46

Ahoj, po pridaní dodatočného kódu do style.css sa mi tá novo pridaná časť kódu neprejavuje na stránke. Nevie niekto prosím kde robím chybu? Je to blbosť ale aj tak ma to trápi :D

Odpovědět
31.7.2020 18:46
Live long and prosper, my friend.
Avatar
jozef.stropko:28.10.2021 10:56

Nie je náhodou pri volaní funkcie: odesli("[email protected]­dresa.cz", "Email z webu", $_POST['zprava'], $_POST['email']); v KontaktKontroler prehodená prvá a posledná hodnota parametru?

Nemalo by byť namiesto "[email protected]" byť $_POST['email'] a nameisto $_POST['email']
nemalo byť "[email protected]"?

Pretože vo funkcii: public function odesli($komu, $predmet, $zprava, $od) v modeli OdosielacEmailu sa do premennej $od posiela $_POST['email'], čo je adresa príjemcu a v hlavičke sa má vypísať $hlavicka = "From: " . $od; a v hlavičke sa tým pádom vypisuje From adresa príjemcu namiesto From adresa odosielateľa.

 
Odpovědět
28.10.2021 10:56
Avatar
jozef.stropko:10.11.2021 15:54

Asi ma niečo splietlo a v tutoriáli je to dobre. V $_POST['email'] je adresa od koho sa posiela email a parametre vo funkcii majú byť tak ako je to v skriptoch v modeli OdosielacEmailu a v kontroleri KontaktKontroler.

 
Odpovědět
10.11.2021 15:54
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 43. Zobrazit vše