Lekce 8 - Kontaktní emailový formulář v PHP
V minulé lekci, Podmínky v PHP podruhé - přetypování, skládání a switch, jsme probírali přetypování a switch.
Na dnešní PHP tutoriál máme slíbený kontaktní formulář, do kterého návštěvníci našich stránek napíší vzkaz a ten se nám odešle emailem. Jedná se o velmi užitečný webový doplněk, díky kterému nás mohou uživatelé našich stránek lépe kontaktovat.
HTML část
Jako vždy bude aplikace rozdělena na 2 části. V tomto případě ovšem
budou obě v jednom souboru mailform.php
. Je to z toho důvodu,
abychom měli při zpracování dat z formuláře přístupný i formulář.
Pokud uživatel zadá něco špatně, vypíšeme nad formulář chybovou
hlášku.
HTML část bude tedy obsahovat formulář, který bude mít následující prvky:
- Jméno - Jméno návštěvníka (abychom věděli kdo nám píše)
- Emailová adresa - Emailová adresa návštěvníka (abychom mu mohli odpovědět)
- Zpráva - Zpráva od uživatele
- Antispam - Ochrana proti spamu
Kromě ochrany proti spamu asi není co vysvětlovat. Řekněme si tedy o spamu více.
Spam
Jakmile vložíte na internet nějakou stránku s formulářem, objeví se časem roboti, kteří do formuláře začnou psát reklamu. Důvod je prostý, formulář někam něco odesílá a když do něj vloží odkaz na nějaké služby (často půjčky nebo pornografii), část lidí na tu reklamu klikne a služby si koupí.
Proti spamu se dá velmi účinně bránit. K zabezpečení formulářů se
používá tzv. Turingův test, známý spíše pod pojmem Captcha. Účelem
testu je položit takovou otázku, na kterou zná odpověď jen člověk. První
captchy často zobrazovaly text na obrázku a předpokládalo se, že obrázek
umí přečíst jen člověk. Postupem času však spammeři vyvinuli poměrně
sofistikované OCR čtečky, které umí obrázky číst lépe, než lidé.
Není ovšem nic jednoduššího, než položit nějakou otázku (nejlépe
česky), kterou spamboti neumějí. Bohatě nám bude stačit např.
Zadejte aktuální rok
.
Formulář
Založte si tedy nový projekt a můžeme začít. HTML kód stránky s formulářem by mohl vypadat např. takto:
<!DOCTYPE html> <html lang="cs"> <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> <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>
A výsledek:
Formulář jsme vložili do tabulky, aby byly prvky hezky zarovnané. Dělá se to tak často, pokud chceme formulář rychle nastylovat. Všimněte si, že ve formuláři není vyplněný parametr action. Data se tedy odešlou na ten samý soubor, ve kterém je formulář.
PHP část
Na úplný začátek souboru vložíme PHP direktivu a pustíme se do programování:
<?php ?>
Validace
Každý formulář bychom měli zvalidovat. Validace je ověření, zda je správně vyplněný. Sice ještě neumíme ověřit, zda jsou v polích správné hodnoty, ale umíme zjistit, zda nejsou prázdná.
Kromě toho, že pole přišlo prázdné, je ještě jedna možnost - formulář se nemusel vůbec odeslat. S touto možností musíme počítat, jelikož máme zpracování i zobrazení ve stejném skriptu - uživatel mohl zatím jen zobrazit formulář a nic neodeslat. Z minulé lekce víme, že pokud napíšeme:
if ($_POST)
Provede se podmínka v případě, když pole není prázdné.
Dále bychom měli počítat i s tím, že se formulář neodeslal celý, ale
jen jeho část. Potřebujeme tedy zjistit, zda v $_POST
existují
jednotlivé proměnné. K tomu v PHP slouží funkce isset()
.
POZOR! Mnoho začátečníků používá k ověření toho, zda se něco odeslalo, následující kód:
if ($_POST['jmeno']) { // ... }
To je ovšem špatně a pokud se formulář neodeslal, PHP vypíše ošklivou chybu, jelikož čteme z neexistující proměnné. Tito začátečníci si místo toho, aby kód opravili, vypnou výpis chyb v PHP. Později sem chodí a diví se, že jim něco nefunguje a nemohou chyby najít.
Když už jsme u nastavení chyb, tak musí být vždy
takové, že jsou na lokálním serveru (na vašem počítači při testování)
zapnuté a na produkci (na internetu) vždy vypnuté. Jen tak odhalíte při
testování většinu problémů a na produkci vám nikdo díky viditelné
chybové hlášce nebude napadat aplikaci. Chyby lze zapínat a vypínat v
php.ini
, někdy ovšem na produkci nemusíme mít k tomuto
nastavení přístup a existuje k tomu nějaký přepínač v
administrátorském rozhraní daného webhostingu.
Validace formuláře by mohla vypadat asi takto:
$hlaska = ''; if ($_POST) { // V poli _POST něco je, odeslal se formulář if (isset($_POST['jmeno']) && $_POST['jmeno'] && isset($_POST['email']) && $_POST['email'] && isset($_POST['zprava']) && $_POST['zprava'] && isset($_POST['rok']) && $_POST['rok'] == date('Y') ) { // Sem přijde odeslání emailu } else $hlaska = 'Formulář není správně vyplněný!'; }
Celý kód je v podmínce, která kontroluje, zda je něco v poli
$_POST
. Pokud se nic neodeslalo, není co zpracovávat. Další
složená podmínka kontroluje, zda byla odeslána jednotlivá pole a zda v nich
je nějaký text. U roku samozřejmě kontrolujeme, zda je aktuální. Ve
skriptu používáme proměnnou $hlaska
, kam vložíme hlášku pro
uživatele v případě, že se validace nepovedla. Tu později vypíšeme v
HTML části skriptu.
Zpracování
Samotné odeslání emailu není složité. Slouží k tomu funkce
mb_send_mail()
, která narozdíl od starší funkce
mail()
podporuje UTF-8 kódování. K funkcím s prefixem
mb_
se ještě dostaneme, nyní nám musí stačit, že pokud je
chceme používat, často musíme na úplném začátku souboru nastavit
kódování:
<?php mb_internal_encoding("UTF-8");
V následující ukázce využíváme zavináč
@
. Zavináč na české klávesnici můžeme napsat pomocí
klávesy pravý ALT a písmene V:
![Zavináč - Základní konstrukce jazyka PHP](/images/5/klavesnice/zavinac.jpg)
Přejděme dovnitř naší podmínky s validací a umístěme tam odeslání emailu a nastavení zprávy pro uživatele:
$hlavicka = 'From:' . $_POST['email']; $hlavicka .= "\nMIME-Version: 1.0\n"; $hlavicka .= "Content-Type: text/html; charset=\"utf-8\"\n"; $adresa = '[email protected]'; $predmet = 'Nová zpráva z mailformu'; $uspech = mb_send_mail($adresa, $predmet, $_POST['zprava'], $hlavicka); if ($uspech) { $hlaska = 'Email byl úspěšně odeslán, brzy vám odpovíme.'; } else $hlaska = 'Email se nepodařilo odeslat. Zkontrolujte adresu.';
Do několika proměnných si připravíme hlavičku, adresu, kam se má email
odeslat (tu si samozřejmě nastavte na svou) a předmět. Jak vypadá hlavička
je dané a nemusíte nad tím přemýšlet, podstatná je jen proměnná v
prvním řádku, která určuje odesílatele emailu. Email potom vypadá jako
že přišel z této adresy, i když ho odeslalo PHP z vašich stránek. Funkce
mb_send_mail()
vrací true
pokud se odeslání
podařilo a false
pokud selhalo. Tuto hodnotu si uložíme do
proměnné $uspech
a nastavíme podle ní hlášku.
Úprava formuláře
Vraťme se k našemu formuláři a vložme těsně nad tag
<form>
další PHP sekvenci, ve které vypíšeme proměnnou
$hlaska
, pokud v ní něco je:
<?php if ($hlaska) echo('<p>' . $hlaska . '</p>'); ?>
Hotovo. Váš formulář by měl nyní odesílat emaily a zobrazovat chybové hlášky. Musíte to ale vyzkoušet spíše tak, že si ho nahrajete někam na webhosting. V XAMPPu ve výchozím nastavení není odesílání emailů funkční, i když jde nastavit v konfiguračním souboru. Pokud máte s nastavením problémy, nevadí, prostě si formulář někam nahrajte (třeba na webhosting OneBit) a vyzkoušejte ho online.
V příští lekci, Vylepšení kontaktního formuláře v PHP, si vylepšíme kontaktní formulář.
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 6400x (2.35 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP