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í.
C# week + discount 30

8. diel - Kontaktný emailový formulár v PHP

V minulej lekcii, Podmienky v PHP druhýkrát - pretypovania, skladanie a switch , sme dokončili podmienky. Na dnešnej PHP tutoriál máme sľúbený kontaktný formulár, do ktorého návštevníci našich stránok napíšu odkaz a ten sa nám odošle emailom. Jedná sa o veľmi užitočný webový doplnok, vďaka ktorému nás môžu používatelia našich stránok lepšie kontaktovať.

Html časť

Ako vždy bude aplikácia rozdelená na 2 časti. V tomto prípade však budú obe v jednom súbore mailform.php. Je to z toho dôvodu, aby sme mali pri spracovaní dát z formulára prístupný aj formulár. Ak používateľ zadá niečo zle, vypíšeme nad formulár chybovú hlášku.

HTML časť bude teda obsahovať formulár, ktorý bude mať nasledujúce prvky:

  • Meno - Meno návštevníka (aby sme vedeli kto nám píše)
  • Emailová adresa - emailová adresa návštevníka (aby sme mu mohli odpovedať)
  • Správa - Správa od užívateľa
  • Antispam - Ochrana proti spamu

Okrem ochrany proti spamu asi nie je čo vysvetľovať. Povedzme si teda o spamu viac.

Spam

Akonáhle vložíte na internet nejakú stránku s formulárom, objaví sa časom roboti, ktorí do formulára začnú písať reklamu. Dôvod je prostý, formulár niekam niečo odosiela a keď do neho vloží odkaz na nejaké služby (často pôžičky alebo pornografiu), časť ľudí na tú reklamu klikne a služby si kúpi.

Proti spamu sa dá veľmi účinne brániť. K zabezpečeniu formulárov sa používa tzv. Turingov test, známy skôr pod pojmom Captcha. Účelom testu je položiť takúto otázku, na ktorú pozná odpoveď len človek. Prvý captcha často zobrazovali text na obrázku a predpokladalo sa, že obrázok vie prečítať len človek. Postupom času však spameri vyvinuli pomerne sofistikované OCR čítačky, ktoré vie obrázky čítať lepšie, než ľudia. Nie je však nič jednoduchšie, než položiť nejakú otázku (najlepšie slovensky), ktorú spambotmi nevedia. Bohato nám bude stačiť napr. Zadajte aktuálny rok.

Formulár

Založte si teda nový projekt a môžeme začať. HTML kód stránky s formulárom by mohol vyzerať napr. Nasledovne:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Kontaktný formulár</title>
    </head>
    <body>
        <p>Môžete ma kontaktovať pomocou formulára nižšie.</p>

        <form method="POST">
            <table>
                <tr>
                    <td>Vaše meno</td>
                    <td><input name="jmeno" type="text" /></td>
                </tr>
                <tr>
                    <td>Váš email</td>
                    <td><input name="email" type="email" /></td>
                </tr>
        <tr>
                    <td>Aktuálny rok</td>
                    <td><input name="rok" type="number" /></td>
                </tr>
            </table>
            <textarea name="zprava"></textarea><br />

            <input type="submit" value="Odoslať" />
        </form>

    </body>
</html>

A výsledok:

Kontaktný formulár
localhost/mail­form.php

Formulár sme vložili do tabuľky, aby boli prvky pekne zarovnané. Robí sa to tak často, ak chceme formulár rýchlo nastylovať. Všimnite si, že vo formulári nie je vyplnený parameter action. Dáta sa teda odošlú na ten istý súbor, v ktorom je formulár.

Php časť

Na úplný začiatok súboru vložíme PHP direktívu a pustíme sa do programovania:

<?php

?>

Validácia

Každý formulár by sme mali zvalidovat. Validácia je overenie, či je správne vyplnený. Síce ešte nevieme overiť, či sú v poliach správne hodnoty, ale vieme zistiť, či nie sú prázdna.

Okrem toho, že pole prišlo prázdne, je ešte jedna možnosť - formulár sa nemusel vôbec odoslať. S touto možnosťou musíme počítať, pretože máme spracovanie aj zobrazenie v rovnakom skripte - užívateľ mohol zatiaľ len zobraziť formulár a nič neodoslať. Z minulej lekcie vieme, že ak napíšeme:

if ($_POST)

Vykoná sa podmienka v prípade, keď pole nie je prázdne.

Ďalej by sme mali počítať aj s tým, že sa formulár neodoslal celý, ale len jeho časť. Potrebujeme teda zistiť, či v $_POST existujú jednotlivé ukazovatele. K tomu v PHP slúži funkcia isset().

POZOR! Veľa začiatočníkov používa na overenie toho, či sa niečo odoslalo, nasledujúci kód:

if ($_POST['jmeno'])
{
    // ...
}

To je však zle a ak sa formulár neodoslal, PHP vypíše škaredú chybu, pretože čítame z neexistujúce premennej. Títo začiatočníci si miesto toho, aby kód opravili, vypnú výpis chýb v PHP. Neskôr sem chodia a čuduje sa, že im niečo nefunguje a nemôžu chyby nájsť.

Keď už sme pri nastavení chýb, tak musí byť vždy také, že sú na lokálnom serveri (na vašom počítači pri testovaní) zapnuté a na produkciu (na internete) vždy vypnuté. Len tak odhalíte pri testovaní väčšinu problémov a na produkciu vám nikto vďaka viditeľnej chybové hláške nebude napádať aplikáciu. Chyby je možné zapínať a vypínať v php.ini, niekedy však na produkciu nemusíme mať k tomuto nastaveniu prístup a existuje k tomu nejaký prepínač v administrátorskom rozhraní daného webhostingu.

Validácie formulára by mohla vyzerať asi takto:

$hlaska = '';
if ($_POST) // V poli _POST niečo je, odoslal sa formulár
{
    if (isset($_POST['jmeno']) && $_POST['jmeno'] &&
        isset($_POST['email']) && $_POST['email'] &&
        isset($_POST['zprava']) && $_POST['zprava'] &&
        isset($_POST['rok']) && $_POST['rok'] == date('Y'))
    {
        // Sem príde odoslania emailu
    }
    else
        $hlaska = 'Formulár nie je správne vyplnený!';
}

Celý kód je v podmienke, ktorá kontroluje, či je niečo v poli $_POST. Ak sa nič neodoslal, nie je čo spracovávať. Ďalšie zložená podmienka kontroluje, či bola odoslaná jednotlivé polia a či v nich je nejaký text. U roka samozrejme kontrolujeme, či je aktuálna. V skripte používame premennú $hlaska, kam vložíme hlášku pre používateľa v prípade, že sa validácia nepodarila. Tú neskôr vypíšeme v HTML časti skriptu.

Spracovanie

Samotné odoslania emailu nie je zložité. Slúži na to funkcia mb_send_mail(), ktorá narozdiel od staršej funkcie mail() podporuje UTF-8 kódovanie. K funkciám s prefixom mb_ sa ešte dostaneme, teraz nám musí stačiť, že ak ich chceme používať, často musíme na úplnom začiatku súboru nastaviť kódovanie:

<?php
mb_internal_encoding("UTF-8");

Prejdime dovnútra našej podmienky s validáciou a umiestnime tam odoslania emailu a nastavenia správy pre užívateľov:

$hlavicka = 'From:' . $_POST['email'];
$hlavicka .= "\nMIME-Version: 1.0\n";
$hlavicka .= "Content-Type: text/html; charset=\"utf-8\"\n";
$adresa = '[email protected]';
$predmet = 'Nová správa z mailformu';
$uspech = mb_send_mail($adresa, $predmet, $_POST['zprava'], $hlavicka);
if ($uspech)
{
    $hlaska = 'Email bol úspešne odoslaný, čoskoro vám odpovieme.';
}
else
    $hlaska = 'Email sa nepodarilo odoslať. Skontrolujte adresu.';

Do niekoľkých premenných si pripravíme hlavičku, adresu, kam sa má email odoslať (tú si samozrejme nastavte na svoju) a predmet. Ako vyzerá hlavička je dané a nemusíte nad tým premýšľať, podstatná je len premenná v prvom riadku, ktorá určuje odosielateľa emailu. Email potom vyzerá ako že prišiel z tejto adresy, aj keď ho odoslalo PHP z vašich stránok. Funkcia mb_send_mail() vracia true ak sa odoslanie podarilo a false ak zlyhalo. Túto hodnotu si uložíme do premennej $uspech a nastavíme podľa nej hlášku.

Úprava formulára

Vráťme sa k nášmu formulári a vložme tesne nad tag <form> ďalšie PHP sekvenciu, v ktorej vypíšeme premennú $hlaska, pokiaľ v nej niečo je:

<?php
    if ($hlaska)
        echo('<p>' . $hlaska . '</p>');
?>

Hotovo. Váš formulár by mal teraz odosielať emaily a zobrazovať chybové hlášky. Musíte to ale vyskúšať skôr tak, že si ho nahráte niekam na webhosting. V XAMPP v predvolenom nastavení nie je odosielanie emailov funkčný, aj keď ide nastaviť v konfiguračnom súbore. Ak máte s nastavením problémy, nevadí, proste si formulár niekam nahrajte (trebárs na webhosting OneBit) a vyskúšajte ho online.

Kontaktný formulár
localhost/mail­form.php

V budúcej lekcii, Vylepšenia kontaktného formulára v PHP , formulár dokončíme. Ak ste mali s nejakou časťou problém, nižšie sú zdrojové kódy k stiahnutiu.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 5982x (1.28 kB)
Aplikácia je vrátane zdrojových kódov v jazyku php

 

Predchádzajúci článok
Podmienky v PHP druhýkrát - pretypovania, skladanie a switch
Všetky články v sekcii
Základné konštrukcie jazyka PHP
Preskočiť článok
(neodporúčame)
Vylepšenia kontaktného formulára v PHP
Článok pre vás napísal David Čápka
Avatar
Užívateľské hodnotenie:
1 hlasov
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 sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity

 

 

Komentáre

Avatar
Josef Rajmon
Brigádník
Avatar
Josef Rajmon:11.6.2021 17:44

Dekuji vecer zkusim. Snad to bude fungovat :)

Odpovedať
11.6.2021 17:44
Existuje lepší moznost, najdi ji!
Avatar
Josef Rajmon
Brigádník
Avatar
Josef Rajmon:11.6.2021 22:57

Super uz to jde! Dekuji moc

Odpovedať
11.6.2021 22:57
Existuje lepší moznost, najdi ji!
Avatar
Dušan Kovářík:27.6.2021 14:04

Wow, funguje mi to :) Musel jsem si celý článek dnes přečíst podruhé, abych pochopil některé věci, které mi napoprvé přišly složité, a už se mi to zdá mnohem jednodušší. Díky za článek!

 
Odpovedať
27.6.2021 14:04
Avatar
Martin Libich:10.9.2021 15:53

Ahoj, vše dobře vysvětleno, jen by mě zajímal první "příkaz":

$hlaska = '';

Tím je myšleno co přesně? Deklaruje se nějaká zatím prázdná proměnná? A je to nutné? Díky.

Odpovedať
10.9.2021 15:53
Pokud se ráno probudím, je vše v pořádku
Avatar
Václav Franz
Supertvůrce
Avatar
Václav Franz:19.12.2021 22:15

Po odeslání formuláře na "localhost" mi to vyhodilo hlášku "Uncaught Error: Call to undefined function mb_send_mail()". Pomohlo změnit mb_send_email() na mail(). Stejně tak u mb_internal_en­coding. Ale po nahrání na server vše fungovalo. (Kdyby měl někdo čas a chuť, může vysvětlit, proč tomu tak je.)

 
Odpovedať
19.12.2021 22:15
Avatar
Haloun Jiří:6. januára 15:13

Ať dělám co dělám, stejně mi chodí do mejlu hloupost, takto Nová zpráva z mailformu
aGdmZHNkZmc=

 
Odpovedať
6. januára 15:13
Avatar
Radek Drlík
Člen
Avatar
Radek Drlík:30. júna 8:38

sendmail se mi nepovedlo rozchodit, místo toho jsem použil PHPMailer, je ale nutno pres composer nainstalovat

<?php
mb_internal_encoding("UTF-8");
//Load Composer's autoloader
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

if ($_POST){

  $mail = new PHPMailer(true);
  if (isset($_POST['jmeno']) && $_POST['jmeno'] &&
      isset($_POST['email']) && $_POST['email'] &&
      isset($_POST['zprava']) && $_POST['zprava'] &&
      isset($_POST['rok']) && $_POST['rok'] == date('Y'))
      {
        try{
          $mail->isSMTP();
          $mail->Host       = 'smtp.seznam.cz';
          $mail->SMTPAuth   = true;
          $mail->Username   = '[email protected]';
          $mail->Password   = 'password';
          $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
          $mail->Port       = 465;
          $mail->isHTML(true);                                  //Set email format to HTML
          $mail->Subject = 'Here is the subject';
          $mail->Body    = $_POST['zprava'];
          $mail->setFrom('[email protected]', 'Rada');
          $mail->addAddress($_POST['email'], $_POST['jmeno']);
          $mail->send();
          $hlaska = 'Email byl úspěšně odeslán, brzy vám odpovíme.';
        } catch (Exception $e) {
            echo "Email se nepodařilo odeslat. Mailer Error: {$mail->ErrorInfo}";
        }
      } else {
        $hlaska = 'Formulář není správně vyplněný!';
      }
}
?>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Kontaktní formulář</title>
    </head>
    <body>
        <p>Můžete mě kontaktovat pomocí formuláře níže.</p>
        <?php
            if ($hlaska)
                echo('<p>' . $hlaska . '</p>');
        ?>
        <form method="POST">
            <table>
                <tr>
                    <td>Vaše jméno</td>
                    <td><input name="jmeno" type="text" /></td>
                </tr>
                <tr>
                    <td>Váš email</td>
                    <td><input name="email" type="email" /></td>
                </tr>
        <tr>
                    <td>Aktuální rok</td>
                    <td><input name="rok" type="number" /></td>
                </tr>
            </table>
            <textarea name="zprava"></textarea><br />

            <input type="submit" value="Odeslat" />
        </form>

    </body>
</html>
 
Odpovedať
30. júna 8:38
Avatar
Radek Drlík
Člen
Avatar
Odpovedá na Radek Drlík
Radek Drlík:30. júna 8:44

nejspis kvuli tomu ze mam v heslu mezeru a sendmail nepodporuje mezery

 
Odpovedať
30. júna 8:44
Avatar
Lukáš Hrabovský:22. septembra 19:55

Pokud nemám žádný on-line webhosting, tak si to neotestuju. Možná bych uvítal základní informace pro nastavení v XAMPPu.

 
Odpovedať
22. septembra 19:55
Avatar
x.listo
Tvůrce
Avatar
Odpovedá na Lukáš Hrabovský
x.listo:24. septembra 5:32

Na konci lekce máš odkaz na lekci 18. Kde se nastavení XAMPP pro odesílání emailu rozebírá.

Nebo si můžeš založit free hosting na webzdarma.cz.

Odeslání emailu funguje, byť s několika minutovým zpožděním, než přijde do schránky.
Navíc umí databáze. Sice bez https a s reklamním bannerem, ale pro ukázky z kurzu plně dostačující.

 
Odpovedať
24. septembra 5:32
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!