PHP Tutorijal: Kontakt forma

1

PHP Tutorijal: Kontakt forma

offline
  • PHP developer
  • Pridružio: 22 Mar 2006
  • Poruke: 3760
  • Gde živiš: 127.0.0.1

Ovo pitanje je bilo postavljano na MyCity forumu bar 10 puta, odgovarano je na njega, ali i pored toga se otvaraju teme sa istim naslovom. Potrudicu se da detaljno objasnim kako napraviti univerzalnu kontakt formu, tako da i pocetnicima bude jasno.

1. Neophodne stvari
2. HTML kod forme
3. "Skupljanje" unetih podataka
4. Provera unetih podataka (obavezna polja)
4a. Provera unete e-mail adrese
4b. Flood zastita
4c. CAPTCHA zastita
5. Slanje maila i prikazivanje rezultata

idemo redom:

1. Neophodne stvari

Da bi ste napisali PHP kod, potrebam vam je neki tekstualni editor - npr Notepad. Posluzice i Code View kod DreamWeaver-a, mada ja preporucujem Notepad++.

Da bi ste pokrenuli PHP kod, neophodan je web server (Apache) i PHP, koji mozete instalirati jedan po jedan, ili u okviru nekog All-in-one paketa (EasyPHP, XAMPP, Apache2Triad...).

Da bi ste poslali mail, neophodan je ili podesen mail server na localhostu (ili serveru na kome pokrecete formu), ili, kao laksa varijanta PHPmailer. Na velikoj vecini free hostova je php funkcija mail() iskljucena, sto je jos jedan razlog za koriscenje PHPmailera. Neki mail serveri cak mailove poslate preko mail() funkcije prepoznaju kao spam. PHP mailer mozete besplatno preuzeti sa http://sourceforge.net/projects/phpmailer

2. HTML kod forme

Postoji nekoliko nacina za pisanje html koda forme, i svako ima svoj. Ja koristim gotovo uvek isti html kod, jer je dobar html kod pola posla. Zasto ovo kazem, videcete kasnije. Stranica na kojoj se kod nalazi se zove "kontakt.php" (mada samo ime nije toliko bitno), a kasnije ce ta ista stranica posluziti i da posalje mail.

<html> <head> <title>PHP Tutorijal: Kontakt forma</title> </head> <body> <form action="kontakt.php" method="post"> Ime i prezime: <input type="text" name="value0" value=""><br> E - mail adresa: <input type="text" name="value1" value=""><br> Naslov poruke: <input type="text" name="value2" value=""><br> Tekst poruke: <textarea name="value3" cols="10" rows="3"></textarea><br><br> <input type="submit" value="Posalji" name="posalji"> </form> </body> </html>

I to je kompletan html kod kontakt forme. Mozete dodavati jos polja po svojoj zelji, samo pazite da se imena polja (atribut name) nalaze u formatu "value#" (gde # oznacava redni broj).

3. "Skupljanje" unetih podataka

Sada je potrebno je prihvatiti podatke koji su poslati preko POST metode. I dalje se nalazimo na kontakt.php stranici, samo sad vec pisemo u PHP-u.
Tekst iza // je komentar, i on se ne izvrsava. Sluzi samo da vam objasni sta se radi kojom linijom koda, i mozete ga izbrisati kad god zelite. Od sad pa nadalje samo cu dodavati delove koda onom kodu koji vec imamo, kako ne bi bilo nedoumica oko toga gde sta treba dodati.

<?php if (isset($_POST['posalji'])) { //provera da li je forma popunjena    for ($i=0;$i<=3;$i++) { //broj 3 oznacava koliko polja imamo       $label = "value" . $i; //pripremamo "ime" polja       if (isset($_POST[$label]) and !empty($_POST[$label])) { //provera da li je polje popunjeno          $value[$i] = $_POST[$label]; //ako jeste, prihvatamo podatke       }       else {          $value[$i] = ""; //ako nije, dodeljujemo "praznu" vrednost promenljivoj       }    } } ?> <html> <head> <title>PHP Tutorijal: Kontakt forma</title> </head> <body> <form action="kontakt.php" method="post"> Ime i prezime: <input type="text" name="value0" value=""><br> E - mail adresa: <input type="text" name="value1" value=""><br> Naslov poruke: <input type="text" name="value2" value=""><br> Tekst poruke: <textarea name="value3" cols="10" rows="3"></textarea><br><br> <input type="submit" value="Posalji" name="posalji"> </form> </body> </html>

Time su svi uneti podaci prikupljeni u niz $value[], a sledeci korak je provera da li su neophodni podaci uneti.

4. Provera unetih podataka (obavezna polja)

I za ovo postoji nekoliko nacina. Ukoliko je broj polja relativno mali (<5) mozete svako polje proveriti rucno, a ako nije, automatizovanje koda puno znaci. Najbolje je da se u startu naviknete da pisete sto manje koda koji radi isti posao kao i dugacki kod, kako bi kasnije, kada okolnosti to budu zahtevale, uz male izmene postojeceg koda dobili ono sto vam treba.

Takodje, u samoj formi sam dodao da, ukoliko postoji greska prilikom popunjavanja, u poljima ostanu unete vrednosti, kako posetioci ne bi morali da vise puta popunjavaju formu.

<?php $value = array("","","",""); $allset = false; //forma nije spremna za slanje $error = ""; //nema gresaka u popunjavanju forme if (isset($_POST['posalji'])) { //provera da li je forma popunjena    $allset = true; //pretpostavljamo da su svi uneti podaci tacni    for ($i=0;$i<=3;$i++) { //broj 3 oznacava koliko polja imamo       $label = "value" . $i; //pripremamo "ime" polja       if (isset($_POST[$label]) and !empty($_POST[$label])) { //provera da li je polje popunjeno          $value[$i] = $_POST[$label]; //ako jeste, prihvatamo podatke       }       else {          $value[$i] = ""; //ako nije, dodeljujemo "praznu" vrednost promenljivoj       }    }    $obavezna = array("0","1","3"); //brojevi obaveznih polja    $o = count($obavezna) - 1; //brojanje obaveznih polja    for ($i=0;$i<=$o;$i++) {       $op = $obavezna[$i]; //uzimamo broj obaveznog polja       if ($value[$op] == "") { //provera da li je polje prazno          $allset = false; //forma nije spremna za slanje          $error = "Niste popunili sva obavezna polja."; //objasnjenje greske       }    } } ?> <html> <head> <title>PHP Tutorijal: Kontakt forma</title> </head> <body> <form action="kontakt.php" method="post"> Ime i prezime: <input type="text" name="value0" value="<?php echo $value[0]; ?>"><br> E - mail adresa: <input type="text" name="value1" value="<?php echo $value[1]; ?>"><br> Naslov poruke: <input type="text" name="value2" value="<?php echo $value[2]; ?>"><br> Tekst poruke: <textarea name="value3" cols="10" rows="3"><?php echo $value[3]; ?></textarea><br><br> <input type="submit" value="Posalji" name="posalji"> </form> </body> </html>

I time je provera da li su popunjena sva obavezna polja zavrsena. Sada bi trebalo proveriti da li je uneti e-mail u validnom formatu.

4a. Provera unete e-mail adrese

Za proveru validnosti e-mail adrese napisao sam jednu funkciju koju uvek primenjujem. Znam da nije savrsena (uostalom, uvek mozete napisati da je vas e-mail npr. ja.sam@svjetskimega.car) ali malo dodatne paznje nije na odmet.

<?php function IsValid($mail) {    $et = strpos($mail,"@"); //provera na kojoj se poziciji nalazi znak @    if ($et >= 1) { //ako ima neceg ispred @       $rest = substr($mail,$et + 1,strlen($mail) - $et); //uzimamo ostatak adrese, iza @       $dot = strpos($rest,"."); // trazimo prvo pojavljivanje tacke iza @       if ($dot >= 2) { //ako ima bar 2 slova ispred tacke          $dotrest = strlen(substr($rest,$dot + 1,strlen($rest) - $dot)); //koliko slova ima iza tacke          if ($dotrest >= 2) { //ako ima vise od ili jednako 2             return true; //mail je validan          }          else {             return false; //ima manje od 2, nije validan          }       }       else {          return false; //manje od 2 slova ispred tacke, nije validan       }    }    else {       return false; //nema niceg ispred @, nije validan    } } $value = array("","","",""); $allset = false; //forma nije spremna za slanje $error = ""; //nema gresaka u popunjavanju forme if (isset($_POST['posalji'])) { //provera da li je forma popunjena    $allset = true; //pretpostavljamo da su svi uneti podaci tacni    for ($i=0;$i<=3;$i++) { //broj 3 oznacava koliko polja imamo       $label = "value" . $i; //pripremamo "ime" polja       if (isset($_POST[$label]) and !empty($_POST[$label])) { //provera da li je polje popunjeno          $value[$i] = $_POST[$label]; //ako jeste, prihvatamo podatke       }       else {          $value[$i] = ""; //ako nije, dodeljujemo "praznu" vrednost promenljivoj       }    }    if (!IsValid($value[1])) { //provera da li je adresa validna       $allset = false; //forma nije spremne za slanje       $error = "Uneta e-mail adresa nije validna."; // objasnjenje greske    }    $obavezna = array("0","1","3"); //brojevi obaveznih polja    $o = count($obavezna) - 1; //brojanje obaveznih polja    for ($i=0;$i<=$o;$i++) {       $op = $obavezna[$i]; //uzimamo broj obaveznog polja       if ($value[$op] == "") { //provera da li je polje prazno          $allset = false; //forma nije spremna za slanje          $error = "Niste popunili sva obavezna polja."; //objasnjenje greske       }    } } ?> <html> <head> <title>PHP Tutorijal: Kontakt forma</title> </head> <body> <form action="kontakt.php" method="post"> Ime i prezime: <input type="text" name="value0" value="<?php echo $value[0]; ?>"><br> E - mail adresa: <input type="text" name="value1" value="<?php echo $value[1]; ?>"><br> Naslov poruke: <input type="text" name="value2" value="<?php echo $value[2]; ?>"><br> Tekst poruke: <textarea name="value3" cols="10" rows="3"><?php echo $value[3]; ?></textarea><br><br> <input type="submit" value="Posalji" name="posalji"> </form> </body> </html>

Zavrsena provera obaveznih podataka, kao i validnosti e-mail adrese. Idemo dalje.

4b. Flood zastita

Ono sto bi trebalo spreciti je da kontakt bude poslat vise puta slucajno, ili namerno - u vidu spama. Zato cemo posetiocima uvesti ogranicenje u vidu slanja jedne poruke u 5 minuta. Medjutim, ovaj deo je nemoguce odvojiti od objasnjenja slanja poruke, jer zabrana tece od onog trenutka kad je poruka poslata. Zato cemo se kasnije vratiti na taj deo.

4c. CAPTCHA zastita

Zloupotreba kontakt forme od strane spamera je ne samo moguca, vec i vrlo realna ukoliko se ne zastitite. Jedan od nacina zastite (ne potpuno pouzdan, ali sasvim dovoljno) je CAPTCHA zastita (CAPTCHA je skracenica za Completely Automated Public Turing test to tell Computers And Humans Apart) i sluzi za razlikovanje ljudi od "botova". Na kom principu radi? Sigurno ste videli, prilikom popunjavanja neke forme slicicu sa brojevima i slovima, gde se od vas trazi da taj kod upisete u odgovarajuce polje. To je za coveka lak zadatak, ali ne i za bota, i vecina padne na tom testu. Zastita je bolja ukoliko koristite nestandardne fontove i izoblicavate slova. Kako se za kreiranje slika "u letu" (ne preporucuje se koriscenje gotovih slika zbog konacnog broja kombinacija) koristi GD biblioteka, a to spada u malo naprednije koriscenje PHPa, o tome ce biti reci u nekom narednom tutorialu. Za sada je dovoljno da znate da i to treba uraditi.

5. Slanje maila i prikazivanje rezultata

Forma je popunjena, podaci prosledjeni, prosli kroz proveru, i sada dolazimo do dela u kome treba poslati mail. Sada su vam potrebna 2 fajla koje ste (nadam se) skinuli jos na pocetku: class.phpmailer.php i class.smtp.php. Neophodan vam je i mail nalog kome mozete pristupiti preko smtp servera. Takodje, sada cemo se vratiti i na flood zastitu, videcete u kodu gde se to nalazi. Evo koda:

<?php session_start(); //startujemo sesiju function IsValid($mail) {    $et = strpos($mail,"@"); //provera na kojoj se poziciji nalazi znak @    if ($et >= 1) { //ako ima neceg ispred @       $rest = substr($mail,$et + 1,strlen($mail) - $et); //uzimamo ostatak adrese, iza @       $dot = strpos($rest,"."); // trazimo prvo pojavljivanje tacke iza @       if ($dot >= 2) { //ako ima bar 2 slova ispred tacke          $dotrest = strlen(substr($rest,$dot + 1,strlen($rest) - $dot)); //koliko slova ima iza tacke          if ($dotrest >= 2) { //ako ima vise od ili jednako 2             return true; //mail je validan          }          else {             return false; //ima manje od 2, nije validan          }       }       else {          return false; //manje od 2 slova ispred tacke, nije validan       }    }    else {       return false; //nema niceg ispred @, nije validan    } } $value = array("","","",""); $allset = false; //forma nije spremna za slanje $error = ""; //nema gresaka u popunjavanju forme $poslato = false;// forma nije poslata (jos uvek) if (isset($_POST['posalji'])) { //provera da li je forma popunjena    $allset = true; //pretpostavljamo da su svi uneti podaci tacni    for ($i=0;$i<=3;$i++) { //broj 3 oznacava koliko polja imamo       $label = "value" . $i; //pripremamo "ime" polja       if (isset($_POST[$label]) and !empty($_POST[$label])) { //provera da li je polje popunjeno          $value[$i] = $_POST[$label]; //ako jeste, prihvatamo podatke       }       else {          $value[$i] = ""; //ako nije, dodeljujemo "praznu" vrednost promenljivoj       }    }    if (!IsValid($value[1])) { //provera da li je adresa validna       $allset = false; //forma nije spremne za slanje       $error = "Uneta e-mail adresa nije validna."; // objasnjenje greske    }    $obavezna = array("0","1","3"); //brojevi obaveznih polja    $o = count($obavezna) - 1; //brojanje obaveznih polja    for ($i=0;$i<=$o;$i++) {       $op = $obavezna[$i]; //uzimamo broj obaveznog polja       if ($value[$op] == "") { //provera da li je polje prazno          $allset = false; //forma nije spremna za slanje          $error = "Niste popunili sva obavezna polja."; //objasnjenje greske       }    }    if ($allset) { //ako je forma spremna za slanje       if (isset($_SESSION['floodstop'])) { //provera da li je poruka poslata u toku sesije          $slanje = $_SESSION['floodstop']; //"uzimamo" vreme kad je poslata          $sada = time(); //"uzimamo" trenutno vreme          $vreme = $sada - $slanje; //razlika u vremenu       }       else {          $vreme = 300; //ako nije, neka razlika bude 5 minuta       }       if ($vreme >= 300) { //ako poruka nije poslata u zadnjih 5 minuta          require("class.phpmailer.php");          $mail = new PHPMailer();          $mail->IsSMTP();          $mail->Host = "mail.server.com"; //podesavanje servera          $mail->SMTPAuth = true; //server zahteva password          $mail->Username = "username@server.com"; //korisnicko ime          $mail->Password = "123456"; //password                          $mail->From = $value[1]; //mail posiljaoca          $mail->FromName = $value[0]; //ime posiljaoca          $mail->AddAddress("kontakt@server.com"); //adresa na koju se salje          $mail->Subject = $value[2]; //subject maila          $mail->Body = stripslashes($value[3]); //tekst poruke          $mail->CharSet = "utf-8"; //"ukljucuje" cirlicna slova, kao i latinicna sa kvacicama                    $mail->WordWrap = 50;          $mail->IsHTML(true);          $mail->AltBody="Ova poruka koristi HTML enkoding, da bi ste je videli morate da ukljucite HTML podrsku u Vasem mail klijentu!";                    if ($mail->Send()) {             $poslato = true; //poruka je poslata             $_SESSION['floodstop'] = time(); //belezimo vreme slanja          }          else {             $error = "Mail nije poslat. Pokusajte ponovo."; //objasnjenje greske          }       }       else { //ako jeste poslata u zadnjih 5 minuta          $error = "Nije moguce poslati poruku u razmaku manjem od 5 minuta."; //objasnjenje greske       }    } } ?> <html> <head> <title>PHP Tutorijal: Kontakt forma</title> </head> <body> <?php if ($poslato) { //ako je poruka poslata ?> Vasa poruka je uspesno poslata. <?php } else { //ako nije poslata, prikazacemo formu if (!empty($error)) { //ako postoji greska    echo "<div>$error</div>"; //prikazacemo je } ?> <form action="kontakt.php" method="post"> Ime i prezime: <input type="text" name="value0" value="<?php echo $value[0]; ?>"><br> E - mail adresa: <input type="text" name="value1" value="<?php echo $value[1]; ?>"><br> Naslov poruke: <input type="text" name="value2" value="<?php echo $value[2]; ?>"><br> Tekst poruke: <textarea name="value3" cols="10" rows="3"><?php echo $value[3]; ?></textarea><br><br> <input type="submit" value="Posalji" name="posalji"> </form> <?php } //kraj prikazivanja forme ?> </body> </html>

i time ste zavrsili kontakt formu. Ostaje samo da dizajn forme dovedete u red, ali to je cist html (i malo css-a), te se u objasnjavanje toga necu upustati.



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Pridružio: 11 Maj 2005
  • Poruke: 871
  • Gde živiš: Aleksinac - Niš

Ovakav tutorial je bas trebao... u zadnje vreme je bilo bas mnogo ovakvih tema.
Dodao bih samo da je za proveru validnosti polja bolje koristiti regularne izraze. Ima vec puno gotovih regex-a pa ih nije tesko korititi. Na primer, za email, mozete naci puno primera ovde:
http://regexlib.com/DisplayPatterns.aspx?cattabindex=0&categoryId=1



offline
  • Pridružio: 13 Jan 2008
  • Poruke: 3657
  • Gde živiš: Stara Pazova

Lepo si se ti pomučio, svaka čast, ali za nas koji ne znamo php i nisi baš uradio veliku stvar! Sad
Recimo u kodu E - mail adresa: <input type="text" name="value1" value=""><br>
zašto je name="value1" a value=""? Meni to nije jasno zašto ne staviti odma name=adresa?
Zar ne bi trebao php kod da se odvoji od html-a ili se sve piše kompletno?

offline
  • igor86  Male
  • Stručni saradnik
    Web programiranje
  • Pridružio: 24 Maj 2006
  • Poruke: 1633

zašto je name="value1" a value=""?

Ne zna se ni HTML

Meni to nije jasno zašto ne staviti odma name=adresa?

Da bi mu lakse poslije bilo baratati sa promjeljivim kroz PHP.

Zar ne bi trebao php kod da se odvoji od html-a ili se sve piše kompletno?

Za sitne stvari moze i ovako.

Mogla bi se tema izdvojiti.

offline
  • Pridružio: 13 Jan 2008
  • Poruke: 3657
  • Gde živiš: Stara Pazova

Jbg, uči se! Ako je lakše, znači da može i onako! Wink

offline
  • PHP developer
  • Pridružio: 22 Mar 2006
  • Poruke: 3760
  • Gde živiš: 127.0.0.1

@Crazy Wiking: Zasto je name="value0", name="value1", name="value2"...?

Odgovorio ti je igor86, da si malo detaljnije procitao, shvatio bi i sam Smile

izdvojicu samo deo koda koji je skracen:

for ($i=0;$i<=3;$i++) { //broj 3 oznacava koliko polja imamo       $label = "value" . $i; //pripremamo "ime" polja       if (isset($_POST[$label]) and !empty($_POST[$label])) { //provera da li je polje popunjeno          $value[$i] = $_POST[$label]; //ako jeste, prihvatamo podatke       }       else {          $value[$i] = ""; //ako nije, dodeljujemo "praznu" vrednost promenljivoj       }    }

da se polja zovu ime, mail, adresa, poruka imao bi 4x ovoliko koda za proveru, jer bi svako polje morao da proveravas Smile zamisli da imas 24 polja (kao ja u jednoj formi koju sam preksinoc pisao) Mr. Green Ovako imas brojac koji sam generise imena polja i proverava.

Name je ime polja, a value njegova vrednost. E sad, mozda moze da te zbuni sto je u atributu name "value#", ali ne daj se Smile Spojio sam PHP i HTML kako bi u slucaju da postoji neka greska prilikom popunjavanja forme u poljima zadrzao vrednosti.

@stankovic: nisam toliko dobar sa RegExpom, tek sam poceo da ga ucim, pa jos uvek ne mogu da napisem dobar primer.

offline
  • igor86  Male
  • Stručni saradnik
    Web programiranje
  • Pridružio: 24 Maj 2006
  • Poruke: 1633

@Rastafarii
Nesto kontam da ti je to gore bilo lakse dobiti da si koristio za name u formi

npr. value[1]

odnosno

E - mail adresa: <input type="text" name="value[1]" value=""><br>

onda samo uradis

$value = $_POST['value'];

i eto ga

offline
  • Blood  Male
  • Ugledni građanin
  • Pridružio: 26 Jul 2003
  • Poruke: 384
  • Gde živiš: Beograd

..ili mozda ako zelis i malo sigurnosti:
$expected = array('email','fname','lname'); // ili sta god ti vec treba foreach($expected as $key) {   ${$key} = $_POST[$Key]; }

Wink

offline
  • Pridružio: 11 Maj 2005
  • Poruke: 871
  • Gde živiš: Aleksinac - Niš

Rastafarii ::
@stankovic: nisam toliko dobar sa RegExpom, tek sam poceo da ga ucim, pa jos uvek ne mogu da napisem dobar primer.

Nije toliko tesko. Blood je dao primer u jednoj drugoj temi:
Blood ::
$valid = preg_match("/^[a-zA-Z0-9]$/",$uname); // ovo ti je samo za slova i projeve, u sledeci primer cu da ubacim i jedan znak(_), pa ti posle mozes da dodajes i druge, ovo je cisto da vidis kako funkcionise.. $valid = preg_match("/^[a-zA-Z0-9_]$/",$uname); // e sada kad bi hteo da ogranicis ime na minim 3 a maximum 15 karaktera, uradio bi ovako nesto $valid = preg_match("/^[a-zA-Z0-9_]{3,15}$/",$uname); if(!$valid) {    echo "Korisnicko ime nije validno"; } else {    ... }

Umesto ovih, mozes koristiti neki drugi pattern a gotovih primera ima koliko hoces.

offline
  • Pridružio: 13 Jan 2008
  • Poruke: 3657
  • Gde živiš: Stara Pazova

Mislim da sam i ja uspeo da rešim svoj problem. Videćemo kad postavim sajt. Do tada.....
U svakom slučaju hvala vam! Smile

Ko je trenutno na forumu
 

Ukupno su 881 korisnika na forumu :: 19 registrovanih, 5 sakrivenih i 857 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 3466 - dana 01 Jun 2021 17:07

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: A.R.Chafee.Jr., Džordžino, Faki-Valjevo, FileFinder, hyla, ikan, ladro, laki_bb, marsovac 2, Mercury, milutin134, panzerwaffe, procesor, S-lash, Silvertooth, stagezin, vlad the impaler, zlatkoa987, zziko