9. diel - Vylepšenia kontaktného formulára v PHP
V predchádzajúcom kvíze, Kvíz - Textové reťazce, polia a podmienky v PHP, sme si overili nadobudnuté skúsenosti z predchádzajúcich lekcií.
V minulej lekcii, Kvíz - Textové reťazce, polia a podmienky v PHP , sme naprogramovali jednoduchý emailový formulár. V dnešnom PHP tutoriálu ho vylepšíme.
Predvyplnenie polí
Keď niečo zle vyplníme, skript nám to oznámia, ale formulár je už prázdny. Je to samozrejme preto, že zobrazujeme už inú stránku, než do ktorej sme dáta zadávali.
Pretože spracovávame dáta tým samým skriptom, v ktorom je formulár,
môžeme do formulára jednoducho vložiť hodnoty z POST
v
prípade, že boli nejaké odoslané. Budete to vyzerať, ako by sa formulár
ani nevymazal.
V PHP bloku tesne pred formulárom si naplníme premennej
$jmeno
, $email
a $zprava
hodnotami z
$_POST
. To môžeme urobiť samozrejme len v prípade, keď v
POST
tieto hodnoty sú. Ak nie, dáme do premenných prázdnej
reťazca.
V tejto chvíli by sme kód napísali asi takto:
if (isset($_POST['jmeno'])) $jmeno = $_POST['jmeno']; else $jmeno = '';
Kód je pomerne dlhý a písať ho pre všetky 3 premenné by bolo
nepohodlné. Zvlášť, keď by formulár obsahoval ešte ďalšie pole. Preto
si uvedieme tzv. Ternárne výraz. Jedná sa o skrátenú
podobu if
... else
. Ternana výraz vždy vracia
nejakú hodnotu, nedá sa teda použiť len miesto podmienky. Skladá
sa z troch časti, čo by nás podľa jeho názvu nemalo prekvapiť V prvej časti uvedieme podmienku,
ďalej znak ?
a potom hodnotu, ktorú má výraz vrátiť, ak
podmienka platí. Za ňou uvedieme :
a hodnotu, ktorá sa má
vrátiť, keď podmienka neplatí.
Premennú by sme pomocou ternárního výrazu naplnili takto:
$jmeno = (isset($_POST['jmeno'])) ? $_POST['jmeno'] : '';
Ešte malá rekapitulácia. Ak v POST
existuje daný kľúč,
vložíme túto hodnotu do premennej $jmeno
. Ak nie, vložíme tam
prázdny textový reťazec, čo sú jednoducho úvodzovky, medzi ktorými nič
nie je.
Toto urobíme ešte s emailom a správou.
Formulár ďalej upravíme tak, aby sa do jeho polí vkladali hodnoty z týchto premenných. Ak nebol formulár odoslaný, vloží sa tam prázdne reťazca, inak sa tam vloží to, čo používateľ vyplnil.
Do formulárového poľa by sme mohli hodnotu vložiť nasledovne:
<input name="jmeno" type="text" value="<?php echo $jmeno ?>" />
Ak chceme v PHP sekvencii len vypísať obsah premennej, použijeme k tomu
skrátenú direktívu <?=
. Rovnakého výstupu teda môžeme
dosiahnuť aj kratšom zápisom:
<input name="jmeno" type="text" value="<?= $jmeno ?>" />
Stále to však nie je ono. Keďže text v premennej
$jmeno
pochádza od užívateľa, nemôžeme si byť
istí, že je bezpečný. Čo keby nám do textu užívateľ vložil nejaký
HTML kód? Vložil by sa potom normálne do našej stránky.
V našom prípade by to toľko nevadilo, ale sú prípady, kde áno. Predstavte si, že vypisujú na stránke správy od užívateľov, treba komentáre k nejakému článku. A jeden používateľ namiesto textu správy vložil HTML kód s formulárom, ktorý je nasmerovaný na jeho obslužný skript na inom webe a v ktorom požaduje od vašich používateľov heslo. Pri vypisovaní správy sa tento kód vypíše do stránky a zobrazí sa jeho formulár. Niektorí vaši používatelia tam naozaj zadajú svoje heslo, ktoré sa odošle niekam útočníkovi. A vy máte problém.
Tomuto typu útoku sa hovorí XSS (ako Cross Site Scripting). Obrana je
veľmi jednoduchá, pred vypísaním obsahu ktorejkoľvek premenné do
HTML kódu stránky použite funkciu htmlspecialchars()
.
Tá prevedie špicaté HTML zátvorky a pár ďalších znakov na tzv. HTML
entity. Prípadný škodlivý kód je potom braný len ako obyčajný text a
prehliadač ho nespracuje ako HTML kód.
Je potrebné pri výpise ošetrovať naozaj každú premennú, aj tie, ktoré užívateľ priamo nezadá. Nikdy totiž neviete, či sa obsah premennej neskladá z niečoho, čo užívateľ zadal a jednoducho sa to nedá ustrážiť. Preto sa ošetrí všetko a to priamo na tom mieste, kde premennú vypisujeme. Až budete pokročilejšie a budete poznať objektovú architektúru, dokážete tento proces zautomatizovať, aby ste funkciu nemuseli ručne písať.
Ukážme si konečne upravený HTML kód formulára is direktívou nad ním:
<?php if ($hlaska) echo('<p>' . htmlspecialchars($hlaska) . '</p>'); $jmeno = (isset($_POST['jmeno'])) ? $_POST['jmeno'] : ''; $email = (isset($_POST['email'])) ? $_POST['email'] : ''; $zprava = (isset($_POST['zprava'])) ? $_POST['zprava'] : ''; ?> <form method="POST"> <table> <tr> <td>Vaše meno</td> <td><input name="jmeno" type="text" value="<?= htmlspecialchars($jmeno) ?>"/></td> </tr> <tr> <td>Váš email</td> <td><input name="email" type="email" value="<?= htmlspecialchars($email) ?>"/></td> </tr> <tr> <td>Aktuálny rok</td> <td><input name="rok" type="number" /></td> </tr> </table> <textarea name="zprava"><?= htmlspecialchars($zprava) ?></textarea> <br /> <input type="submit" value="Odoslať" /> </form>
Formulár si vyskúšajme. Ponechajme nejaké pole prázdne a odošleme, ukáže sa chybová hláška a zároveň zostane aj to, čo používateľ vyplnil:
Presmerovanie
Formulár má teraz dve podstatné vady. Ak správu úspešne odošleme, rovnako zostane predvyplnený. A hlavne ak po odoslaní stlačíme F5, formulár sa odošle znova. Týmto neduhom trpí všetky formuláre, ak ho spracováva ten istý súbor, v ktorom je formulár vložený (čo je väčšinou nutné).
Ak je spracovanie formulára dokončené, mali by sme vykonať presmerovanie.
Presmerujeme na tú istú adresu, na ktorej je formulár. Vďaka presmerovanie
sa však stratí dáta v $_POST
. Následné obnovenie stránky tak
už nič neodošle.
Presmerovanie vykonáme pomocou funkcie header()
. Tá odošle
tzv. Hlavičku prehliadači. Práve hlavička môže obsahovať informáciu o
presmerovanie a to pomocou slova Location
.
Po uložení úspešnej hlášky teda formulár presmerujeme:
if ($uspech) { $hlaska = 'Email bol úspešne odoslaný, čoskoro vám odpovieme.'; header('Location: mailform.php'); exit; }
Funkciou exit()
ukončíme beh skriptu, pretože samotné
presmerovanie ho nezastaví, len pošle prehliadači návštevníka informáciu
o tom, že sa má presunúť na inú lokáciu.
Formulár už netrpí opätovným odoslaním pri obnovení stránky.
Nezobrazuje však ani hlášku o úspechu. Malo by vám byť jasné prečo, keď
presmerujeme na inú stránku, obsah premenných na stránke existujúce sa
stratí a tým aj ten v $hlaska
. Riešenie je niekoľko, tým
najjednoduchším je odovzdať pomocou GET
parametra stránke
nejakú premennú. Podľa toho stránka spozná, že na nej bolo presmerované
po úspešnom odoslaní a zobrazí o tom správu. Kód zmeníme na nasledujúce
podobu:
header('Location: mailform.php?uspech=ano'); exit;
Presunieme sa na začiatok skriptu, kde hlášku nastavujeme na prázdny
string
. Pozrieme sa, či nám neprišiel v adrese parameter
uspech
. Ak áno, nastavíme hlášku na text, ktorý sa má pri
úspechu užívateľovi vypísať. Už vieme, že parametre z URL adresy
prichádzajú na rozdiel od parametrov z formulára v poli
$_GET
:
$hlaska = ''; if (isset($_GET['uspech'])) $hlaska = 'Email bol úspešne odoslaný, čoskoro vám odpovieme.';
Môžete si vychutnať dobre fungujúce formulár.
POZOR! Presmerovať môžeme iba v prípade, že sme ešte nevyzvali na predloženie žiadne HTML. Akonáhle sa totiž začne niečo vypisovať, PHP prehliadači odošle hlavičku, kde mu hovorí, že mu posiela HTML súbor. Hlavičku možno samozrejme odoslať len raz, keď sa pokúsime veprostřed súboru presmerovať, dostaneme chybovú hlášku "Headers already sent" a k presmerovanie nedôjde. To by sa stalo napríklad v tomto prípade:
<html> <body> <?php // Tento kód je zle header('Location: index.php'); exit; ?> </body> </html>
Dávajte si pozor aj na tento prípad, v ktorom chyba nie je na prvý pohľad vidieť:
-- Tu je prázdna riadok -- <?php header('Location: index.php'); ?> <html> <body> </body> </html>
Na začiatku súboru je odriadkovanie. Aj to je znak, ktorý odštartuje výstup a PHP ho odosiela prehliadači spolu s hlavičkou. Podobný problém býva s medzerou. Ak ukladáte UTF-8 súbory s tzv. BOM, môže robiť práve tieto problémy. Ak však používate kvalitnú IDE, tak sa vám to nestane.
Pozn .: Niektorí začiatočníci presmerúvajú tak, že vyechují JavaScript, pomocou ktorého zmení adresu okna. Vyzerá asi takto:
// Tento kód je zle echo('<script type="text/javascript"> window.location = "index.php" </script>');
Tento spôsob je však nespoľahlivý a niekedy aj nebezpečný. Nepoužívajte ho.
Formulár si môžete nastylovať, aby vyzeral lepšie. Hlášku dať do nejakej bubliny a podobne. To ale už nie je predmetom tohto PHP kurzu, štýlovanie sa preberá v inom on-line kurzu Kompletný formulár je k stiahnutiu nižšie. V budúcej lekcii, Skladanie stránok v PHP , sa pozrieme na skladanie stránok pomocou PHP.
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é 4527x (3.13 kB)
Aplikácia je vrátane zdrojových kódov v jazyku php