Validácia formulára

V tejto kapitole si ukážeme validáciu (kontrolu) formulára, ktorý sme použili v kapitole o odoslaní mailu (uni 4900). Kód tohto formulára si môžeme skopírovať do súboru page3.php, kód z minulej kapitoly (regulárne výrazy) si zatiaľ zakomentujeme. Validáciou formulára sa myslí kontrola jednotlivých prvkov, či spĺňajú nami očakávané predpisy – formáty hodnôt. Údaje zadané používateľom sa vo väčšine ďalej v kóde spracovávajú alebo niekam ukladajú (databáza, lokálne súbory...), preto je dôležité ich kontrolovať. V prípade nesprávne zadaných hodnôt môže následne funkcionalita s nimi zlyhať, takže týmto spôsobom tomuto zamedzíme. Pri výskyte zlých hodnôt sa to používateľovi zvyčajne dáva najavo a spomenutá funkcionalita sa ani nevykoná.

 

Na kontrolu jednotlivých hodnôt existujú aj nejaké zabudované funkcie v jazyku, ktoré vedia overiť niektoré používané reťazce znakov. My však už z predchádzajúcej kapitoly vieme, že nám na to slúžia regulárne výrazy. Náš formulár chceme použiť ako kontaktný formulár na stránke. To, kam sa mail odosiela, bude zadané natvrdo v kóde. Je to vo väčšine kontaktný mail majiteľa/prevádzkovateľa webstránky. Preto si našu prvú položku adresát zmeníme na email, ktorý bude značiť email používateľa, ktorý sa snaží skontaktovať mailom. Pred túto položku si ešte pridáme jeden prvok s názvom meno, do ktorého by mal používateľ napísať svoje meno. Súbor page3.php by mal vyzerať takto:

 

page3.php:

<form action="page3.php" method="post">
    <label for="email">Meno a priezvisko</label>
    <input type="text" name="name" id="name" value="<?php echo $_POST['name'];?>"><br><br>

    <label for="email">Email</label>
    <input type="text" name="email" id="email" value="<?php echo $_POST['email'];?>"><br><br>

    <label for="subject">Predmet</label>
    <input type="text" name="subject" id="subject" value="<?php echo $_POST['subject'];?>"><br><br>

    <label for="message">Správa</label>
<textarea name="message" id="message" value="<?php echo $message;?>" placeholder="Zadajte text spravy..."></textarea><br><br>

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

 

Formulár už máme pripravený, teraz nám ostáva vyriešiť validáciu. Čo to teda pre nás znamená? Našou úlohou je donútiť používateľa, aby zadal korektné informácie. Pokiaľ tak neurobí, funkcionalita sa nevykoná – v tomto prípade odoslanie emailu. V našom kóde si teda musíme skontrolovať, či bol vôbec formulár odoslaný. Následne by sme mali skontrolovať všetky hodnoty, ktoré chceme kontrolovať, či spĺňajú naše požiadavky.

 

V prípade, že spĺňajú, zobrazíme používateľovi správu o úspešnom odoslaní, v opačnom prípade mu zobrazíme hlášku o zle zadaných údajoch. Povedzme, že nateraz ideme iba kontrolovať správne zadaný email, pretože pri položke predmet a text správy môže v podstate používateľ zadať čokoľvek. Pri položke meno môže zadať tiež čokoľvek, vymyslime si ale situáciu, že to bude akýsi interný nickname (prezývka) stránky a musí to byť reťazec písmen a čísiel o minimálnej dĺžke 5 a maximálnej 10 znakov. Túto úlohu by ste teoreticky mohli zvládnuť, skúste si napísať, ako by ste to urobili. Mohlo by to vyzerať asi takto:

 

page3.php:

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['contact_form']){
    if(!preg_match('#^[a-zA-Z0-9]{5,10}$#', $_POST['name']) || !preg_match('#^.+@.+\..+$#', $_POST['email'])){
        echo '<p>Zadajte prosim korektne udaje</p>';

        //naplnenie formulara
        $name = $_POST['name'];
        $email = $_POST['email'];
        $subject = $_POST['subject'];
        $message = $_POST['message'];
    }else{
        //odoslanie emailu
        echo '<p>Vasa sprava bola uspesne odoslana.</p>';

        $name = '';
        $email = '';
        $subject = '';
        $message = '';
    }

}

?>

<form action="page3.php" method="post">
    <label for="email">Meno a priezvisko</label>
    <input type="text" name="name" id="name" value="<?php echo $name;?>"><br><br>

    <label for="email">Email</label>
    <input type="text" name="email" id="email" value="<?php echo $email;?>"><br><br>

    <label for="subject">Predmet</label>
    <input type="text" name="subject" id="subject" value="<?php echo $subject;?>"><br><br>

    <label for="message">Správa</label>
    <textarea name="message" id="message" placeholder="Zadajte text spravy..."><?php echo $message;?></textarea><br><br>

    <input type="submit" name="contact_form" value="Odoslat">
</form>

 

Pozrite sa najprv na kód formulára. Nastali tam iba tieto zmeny - metóda odosielania by mala byť post, defaultný text správy sme dali ako palceholder, nie ako value a tlačítku submit sme pridali atribút name. Pred formulárom sa nachádza kód jazyka PHP, ktorý rieši odosielanie formulára. Na začiatku máme v podmienke funkciu $_SERVER['REQUEST_METHOD'], ktorá slúži na otestovanie, či bol formulár odoslaný metódou post. Je dobré si zvyknúť používať túto podmienku na akúkoľvek prácu so zachytávaním poslaných dát. Za ňou nasleduje ešte jedna podmienka a to je, či nám prišla hodnota s názvom contact_form, ktorú sme pridali do atribútu name tlačítku v našom formulári. Prečo sme to tak urobili? Predstavte si, že máte na stránke dva rôzne formuláre, ktoré oba odosielate metódou post. Ako by ste rozlíšili, kedy sa poslali dáta z jedného a kedy z druhého? Presne takto sa to dá šikovne zistiť, tlačítko submit má nastavený atribút value stále (je to jeho zobrazovaný text), takže ak sa naň kliklo, táto hodnota nám musí prísť.

 

Po overovaní, či bol formulár odoslaný metódou, ktorú očakávame a či bol odoslaný ten správny formulár, máme v tele tejto podmienky ďalšiu podmienku, ktorá rozlišuje, či boli údaje vo formulári zadané správne. Ako sme si povedali, predmet a text správy nemáme prečo kontrolovať, ale pre email a meno máme predom určené pravidlá, ktoré musia byť splnené. Preto v tejto podmienke kontrolujeme, že či náhodou nespĺňa nejaká z týchto dvoch zadaných hodnôt náš predpis (regulárny výraz). Ak nespĺňa, hodnota funkcie je 0, máme pred nimi ale výkričník (negácia), takže sa z toho stane 1, resp. pravda a tým pádom, ak aspoň jedna z týchto dvoch nie je splnená (čiže bude jedna z nich pravda), podmienka je splnená a spúšťa sa jej prvá vetva (nie else).

 

Táto vetva teda rieši prípad, kedy boli údaje zadané zle. Všimnite si, čo v nej vykonávame. Používateľovi zobrazíme hlášku, že údaje boli nesprávne zadané. Okrem toho si do premenných, ktorých názvy predstavujú jednotlivé položky formulára nastavíme hodnoty, ktoré nám prišli. Všimnite si, že tieto premenné máme potom nastavené v atribúte value pri každom prvku formulára. To je preto, aby ak boli zle zadané údaje, boli tieto hodnotu znova zobrazené v inputoch, aby tie správne zadané nemusel používateľ znova zadávať, aby sa nevymazali. Vo vetve else, ktorý rieši správne zadané údaje, tieto hodnoty vynulujeme (priradíme prázdny string) a po zobrazení hlášky používateľovi, že správa bola úspešne odoslaná bude mať formulár vyresetovaný – hodnoty budú vynulované. Samotné odoslanie mailu neriešime, to nateraz nie je podstatné. Môžme si ale predstaviť, že odoslanie mailu by bolo práve na tomto mieste.

 

Takto nejako by mohla vyzerať jednoduchá validácia nášho formulára, ktorý si v nasledujúcej kapitole naštýlujeme. Vráťme sa ešte k overovaniu správne zadanej emailovej adresy. Ako sme si povedali, náš regulárny výraz nie je úplne správny a ten správny je oveľa zložitejší, existuje však vstavané funkcia v jazyku PHP, ktorá overuje niektoré hodnoty a typy hodnôt. Názov tejto funkcie je filter_var (filter variable – filtruj premennú), kde ako prvý parameter posielame testovanú hodnotu a ako druhý parameter typ preddefinovaných typov hodnôt, ktoré chceme otestovať. Týchto hodnôt je viac, pre overovanie emailovej adresy je to hodnota FILTER_VALIDATE_EMAIL. Táto funkcia v prípade správnosti údajov vráti danú hodnotu, v opačnom prípade hodí false. Takže namiesto testovania regulárneho výrazy môžeme v našej podmienke použiť výraz filter_var($_POST['email'], FILTER_VALIDATE_EMAIL).

 

Okrem toho môžeme náš formulár vylepšiť ešte o jednu vec. Pri posielaní dát a všeobecne formulárov, kedy sa posielajú dáta, sa môže vyskytnúť nejaký útok od používateľa. Nejdeme si to teraz podrobne vysvetľovať, to sa bude podrobnejšie preberať neskôr, je dobré ale vedieť, že práve pri odosielaní formulára sa to môže stať. Zraniteľné miesto je práve atribút action v tagu form, kde zadávame, kam sa má formulár odosielťa. V prípade, že odosielame formulár na seba samého, čiže na ten istý súbor – tak, ako sme to robili my, je možné špecifikovať tento cieľ inak. Slúži na to prvok premennej $_SERVER s názvom PHP_SELF, čiže výraz $_SERVER["PHP_SELF"] nám hodí názov nášho súboru – seba samého. Práve tento výraz sa dá kadejako zneužiť, aby sa tomu predišlo, obalíme tento výraz funkciou htmlspecialchars(), ktorá konvertuje špeciálne znaky do znakov zrozumiteľných pre jazyk HTML. Práve toto konvertovanie môže v istých prípadoch zamedziť útoku pri odoslaní formulára (pri jeho presmerovaní niekam inam). Náš kód by mohol teda vyzerať takto:

 

page3.php (iba zmenený kód):


f(!preg_match('#^[a-zA-Z0-9]{5,10}$#', $_POST['name']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">

Máte nejakú otázku alebo Vám niečo nie je jasné? Napíšte nám na info@zacni-programovat.sk a poradíme!

Obsah súborov projektu po tejto prednáške

1 - footer.php

<div class="footer">
</div>

2 - fotogaleria.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "fotogaleria";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Fotogaléria</h1>

<?php

$pictures = array();

for($i = 0; $i < 7; $i++){
$pictures[] = 'images/placeholder.jpg';
}

echo '<ul id="gallery">';
for($i = 0; $i < 7; $i++){
echo '<li>';

echo '<a class="left';
if(($i+1)%3){
echo ' photo-margin';
}
echo '" target="_blank" href="'.$pictures[$i].'">';

echo '<img src="'.$pictures[$i].'">';
echo '</a>';
echo '</li>';
}
echo '</ul>';

?>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

3 - global.css

BODY{
margin: 0;
background-color: #dee8e7;
}

.main{
background-color: #f6f7f1;
width: 900px;
margin: auto;
margin-top: 20px;
margin-bottom: 20px;
}

.header{
border-bottom: 1px solid #7d8079;
height: 150px;
}

.header-inner1{
}

.header-inner2{
}

.content{
}

.footer{
border-top: 1px solid #7d8079;
height: 200px;
}

.half-width{
width: 50%;
}

.full-height{
height: 100%;
}

.left{
float: left;
}

.right{
float: right;
}

.clear{
clear: both;
}

/**********MENU***********/
.sidebar{
width: 200px;
height: 400px;
}

.sidebar UL{
list-style-type: none;
padding: 0;
margin: 0;
}

.sidebar UL LI{
}

.sidebar UL LI A{
display: block;
padding: 15px 0px 15px 35px;
border-bottom: 1px solid #7d8079;
color: #7d8079;
font-family: Arial;
text-decoration: none;
text-transform: uppercase;
}

.sidebar UL LI A.active{
color: #f5f7f4;
background-color: #f96b81;
}

.sidebar UL LI:HOVER A{
background-color: #5b6b78;
color: #d6e3e9;
}

.main-content{
width: calc(100% - 241px);
min-height: 700px;
border-left: 1px solid #7d8079;
padding-left: 20px;
padding-right: 20px;
}

/**********GALERIA***********/
#gallery{
list-style-type: none;
margin: 0;
padding: 0;
}

#gallery A{
display: block;
height: 133px;
margin-bottom: 10px;
}

#gallery IMG, #gallery A{
width: 213px;
}

.photo-margin{
margin-right: 10px;
}

/**********PERSONS***********/
.persons{
width: 100%;
table-layout: fixed;
font-family: Arial;
}

.persons, .persons TH, .persons TD{
border: 1px solid #D9E4E6;
}

.persons TH, .persons TD{
padding: 15px;
}

.persons TH{
background-color: #167F92;
color: #FFFFFF;
font-weight: normal;
text-transform: uppercase;
}

.persons TR:nth-child(odd){
background-color: #D9E4E6;
}

.persons TR{
color: #024457;
background-color: #FFFFFF;
}

.persons TD{
font-size: 14px;
}

.persons TR:HOVER{
color: #f5f7f4;
background-color: #f96b81;
cursor: pointer;
}

4 - header.php

<div class="header">
<div class="header-inner1 full-height half-width left"></div>
<div class="header-inner2 full-height half-width left"></div>
</div>

5 - index.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "index";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Domov</h1>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

6 - menu.php

<div class="sidebar left">
<ul>
<li><a class="<?php if($actual_page == "index"){echo 'active';}?>" href="index.php">Domov</a></li>
<li><a class="<?php if($actual_page == "o-nas"){echo 'active';}?>" href="o-nas.php">O nás</a></li>
<li><a class="<?php if($actual_page == "fotogaleria"){echo 'active';}?>" href="fotogaleria.php">Fotogaléria</a></li>
<li><a class="<?php if($actual_page == "page3"){echo 'active';}?>" href="page3.php">page3</a></li>
</ul>
</div>

7 - o-nas.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "o-nas";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>O nás</h1>

<?php
$person_1 = array('Raťafák', 'Plachta', 'plachtos@mail.sk','0903 123 123');
$person_2 = array('Od kuka', 'do kuka', 'kuko@mail.sk','0903 123 123');
$person_3 = array('Joey', 'Tribbiani', 'ako.sa.mas@mail.sk','0903 123 123');
$person_4 = array('Charlie', 'Harper', 'hooker@mail.sk','0903 123 123');
$person_5 = array('Chruno', 'Moysey', 'abstinent@mail.sk','0903 123 123');

$pole = array($person_1, $person_2, $person_3, $person_4, $person_5);

$pole[5] = array('Jardo', 'Jágr', 'legenda@mail.sk','0903 123 123');

echo '<table class="persons">';
echo '<tr>';
echo '<th>Meno</th>';
echo '<th>Priezvisko</th>';
echo '<th>Email</th>';
echo '<th>Telefónne číslo</th>';
echo '</tr>';

for($i=0; $i<count($pole); $i++){
echo '<tr>';

for($j=0; $j<count($pole[$i]); $j++){
echo '<td>'.$pole[$i][$j].'</td>';
}

echo '</tr>';
}

echo '</table>';

?>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

8 - page3.php

<!DOCTYPE html>

<html lang="sk">
<head>
<title>Vitajte na našej prvej skutočnej webstránke!</title>

<meta charset=“UTF-8“>
<meta name="description" content="Ponúkame vám lekcie jazykov HTML, CSS, PHP a mnoho ďalších užitočných rád pri programovaní">
<meta name="keywords" content="programovanie, html, css, php, webstranka, web, tvorba webu, web developer, ucenie programovania, ako programovat">

<link rel="stylesheet" type="text/css" href="global.css">
</head>

<body>
<?php $actual_page = "page3";?>
<div class="main">

<?php include "header.php";?>

<div class="content">

<?php include "menu.php";?>

<div class="main-content right">
<h1>Page3</h1>

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['contact_form']){
if(!preg_match('#^[a-zA-Z0-9]{5,10}$#', $_POST['name']) || !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
echo '<p>Zadajte prosim korektne udaje</p>';

//naplnenie formulara
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
}else{
//odoslanie emailu
echo '<p>Vasa sprava bola uspesne odoslana.</p>';

$name = '';
$email = '';
$subject = '';
$message = '';
}

}

?>

<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<label for="email">Meno a priezvisko</label>
<input type="text" name="name" id="name" value="<?php echo $name;?>"><br><br>

<label for="email">Email</label>
<input type="text" name="email" id="email" value="<?php echo $email;?>"><br><br>

<label for="subject">Predmet</label>
<input type="text" name="subject" id="subject" value="<?php echo $subject;?>"><br><br>

<label for="message">Správa</label>
<textarea name="message" id="message" placeholder="Zadajte text spravy..."><?php echo $message;?></textarea><br><br>

<input type="submit" name="contact_form" value="Odoslat">
</form>
</div>

<div class="clear"></div>
</div>

<?php include "footer.php";?>
</div>
</body>
</html>

Ťažko sa vám učí samému?

Máte problémy s niektorými časťami alebo sa neviete učiť sám? Využite našu možnosť individuálnej asistencie:

  • samostatný prístup
  • vysvetlenie nejasností prebraného učiva
  • úlohy a cvičenia navyše
  • všetko z pohodlia domova cez mail a skype

Pre viac info kliknite tu

Kľúčové slová prednášky

regularne vyrazyphp regularne vyrazyvalidacia formularakontrola formularavalidacia udajovvalidacia regularne vyrazyvalidacia v php

IT ftip

Zomrie programátor a dostane sa do pekla. Po týždni Lucifer volá Bohovi: - Čo za blázna si mi sem poslal? Zničil mi všetky kotly, poškrtil všetkých čertov a už tri dni bezhlavo behá po všetkých chodbách pekla a reve "Kde je prechod do druhého levelu?"