nav_dugme codeBlog codeBlog
  • početna Početna stranica
  • Sačuvani članci Sačuvani članci
  • Članci
     (spisak)
  • Kontakt
Povratak na vrh stranice

Info & povezani članci Info o članku - dugme

Info

trejler_sat Datum objave: 02.03.2021.

trejler_olovka Poslednja izmena: 05.05.2022.

trejler_dokument Jezici: PHP,
MySql

trejler_teg_narandzasti Težina: 7/10

PHP
MySql
SQL
autentifikacija
internet
web dizajn
baze podataka
baze
upit
formular
get
post
session
cookie
login
prijava
tutorijali
url

Tema: PHP

Uvod u PHP i back-end programiranjePovezivanje skripti sa MySql bazama podataka$_GET - Prosleđivanje podataka preko URL-a ($_GET)$_POST - Prosleđivanje podataka preko HTML forme$_SESSION - Direktno prosleđivanje podataka između stranicaTutorijal - Ažuriranje praznih kolona u bazi podataka

Povezani članci

Uvod u web dizajn - 1. deo - Početni koraciPokretanje lokalnog web serveraUvod u relacione baze podataka i SQLUvod u Node.jsUvod u PythonStruktura web adresa i pristup internet stranicamaŠablonske niske u programskim jezicimaHTTP statusni kodoviLokalno skladištenje podataka browsera (sessionStorage, localStorage, cookies)Asinhrono programiranje u JavaScriptuASCII, Unicode i UTF - Predstavljanje znakova na računarimaGNU/Linux - 1. deo - Uvod
Svi članci
If you're good at the debugger it means you spent a lot of time debugging. I don't want you to be good at the debugger.
Robert C. Martin

Tutorijal - PHP - Kreiranje forme za prijavu korisnika

Facebook LinkedIn Twitter Viber WhatsApp E-mail
zoom_plus zoom_minus bookmark
početna > Članci > Saveti

Uvod

Da bismo na što bolji način zaokružili uvodnu diskusiju o 'osnovnim tehnikalijama u programskom jeziku PHP' i da bismo isprobali kako sve funkcioniše u praksi (što je u svemu najvažnije), kreiraćemo formular za prijavu korisnika:

Slika 1. - Formular za prijavu korisnika (tema članka).

Ukoliko želite, kliknite na sliku da se prebacite na stranicu na kojoj možete direktno isprobati formular.

Podaci za prijavu:

  • korisničko ime: "petar_011"
  • lozinka: "ApstraKcij4~#"

Sistem za prijavu tipično funkcioniše kroz interakciju tri PHP skripte:

  • prijava.php - stranica preko koje se unose podaci za prijavu
  • obrada.php - skripta preko koje se uneti podaci proveravaju u odnosu na podatke iz baze
  • povezivanje.php - pomoćna skripta za povezivanje sa bazom

Nazivi datoteka koje smo naveli su proizvoljni (tj. nisu 'obavezni'), ali, izabrani su "logični"/uobičajeni nazivi koji odgovaraju nameni datoteka.

Shodno tome da li je korisnik uneo korektne podatke (ili nije), sistem, u nastavku:

  • dozvoljava prijavu korisnika - ukoliko su podaci u redu (ili)
  • onemogućava dalji pristup - ukoliko nisu uneti odgovarajući podaci

Krenimo redom ....

Šta projekat obuhvata?

Sa jedne strane, kreiranje sistema za prijavu korisnika je prilično jednostavan zadatak, ali - sa druge strane - postoje stvari o kojima se uvek mora voditi računa (a pogotovo u fazi upoznavanja sa back-end programiranjem).

U pitanju je pre svega sigurnost sajta, koja može biti ugrožena na nekoliko načina:

  • korisnici (namerno ili slučajno), mogu uneti podatke koji su u stanju da ugroze sajt (i stoga moramo biti pažljivi pri obradi podataka koje su korisnici uneli)
  • sa naše strane (kao back-end programeri), moramo biti korektni prema korisnicima, odnosno, moramo se potruditi da zaštitimo podatke koje korisnici predaju na obradu, što se posebno odnosi na korisničke lozinke (koje nikako ne treba čuvati u izvornom obliku!)

Navedenim temama posvetićemo posebnu pažnju (usput ćemo se naravno osvrtati i na druge tehnike koje smo ranije pominjali), a sam projekat biće podeljen na sledeće celine:

  • kreiranje forme za prijavu
  • objašnjenje postupka za pravilno skladištenje lozinki
  • kreiranje i popunjavanje baze podataka sa korisničkim podacima (uz vođenje računa o pravilnom skladištenju lozinki)
  • obrada korisničkih podataka (tokom prijave korisnika)
  • sprečavanje unošenja nedozvoljenog SQL koda (SQL injection), preko polja za upis
  • prosleđivanje informacije o neuspešnom pokušaju prijave (u smeru: od stranice za obradu - prema stranici za prijavu), preko superglobalne promenljive $_SESSION

Projekat je "zvanično" vezan za izradu stranice za prijavu korisnika, ali, osvrnućemo se i na dodatne tehnike koje se koriste pri "prečišćavanju" primljenih podataka na formama za registraciju, što će čitaocima dati sasvim dovoljno informacija da samostalno izrade formular za registraciju (posle izrade formulara koji opisujemo u članku).

Malo je reći da takav poduhvat predstavlja dobru vežbu i nešto čime svaki back-end programer treba da se pozabavi na početku svog usavršavanja (ukratko - domaći zadatak). 🙂

Za sam početak, obavićemo najjednostavniji zadatak - kreiraćemo formu za prijavu.

Forma za prijavu

U prigodno imenovanom folderu koji će sadržati sve skripte koje su vezane za projekat kojim se bavimo, kreirajte prvo datoteku sa nazivom prijava.php (u pitanju je glavna stranica sa formularom za prijavu), i unesite u datoteku sledeći kod:

		
<?php
	session_start();
?>

<!DOCTYPE html>

<html>
	<head>
		<meta charset='UTF-8'/>
		<title>PHP - login</title>
		<link rel='stylesheet' type='text/css' href='stil.css'/>
	</head>

	<body>
		<main id='wrapper'>
			<form id='forma_prijava' method='post' action='obrada.php'>
				<input
					type        = 'text'
					placeholder = 'Korisnicko ime'
					name        = 'korisnicko_ime'
				/>
				
				<input
					type        = 'password'
					placeholder = 'Lozinka'
					name='lozinka'
				/>
				
				<input
					type  = 'submit'
					value = 'PRIJAVA'
				/>
			</form>
		</main>
	</body>
</html>
		
	
Slika 2. - Sadržaj datoteke index.php, preko koje je definisan formular za prijavu (deluje da smo previše "ulepšali" zapis input polja, time što smo atribute pisali jedne ispod drugih, ali .... polako .... uvidećemo na kraju zašto smo 'pisali tako kako smo pisali').

Datoteka prijava.php povezana je sa CSS datotekom stil.css, koja će imati sledeći sadržaj (vezu smo prethodno uspostavili preko taga <link>):

		
* {
	margin:  0;
	padding: 0;
	font:    inherit;
}

::placeholder {
	color: #777;
}

#wrapper {
	width:           100vw;
	height:          100vh;
	display:         flex;
	flex-direction:  column;
	justify-content: center;
	align-items:     center;
}

#forma_prijava {
	display:        flex;
	flex-direction: column;
	font-family:    OpenSans-Regular, Arial, sans-serif;
	font-size:      14pt;
}

#forma_prijava input {
	margin:  0 0 5px 0;
	padding: 2px 5px;
	//border:  solid 1px #bbb;
}

#forma_prijava input[type='submit'] {
	margin:     0;
	padding:    8px;
	background: #2e7fff;
	color:      white;
	border:     none;
}

.okvir_crni {
	border:  solid 1px #bbb;
}

.okvir_crveni {
	border:  solid 2px #e33;
}

#ispis_gresaka {
	display:         flex;
	flex-direction:  column;
	justify-content: flex-start;
	align-items:     stretch;
	font-family:     OpenSans-Regular, Arial, sans-serif;
	font-size:       14pt;

	margin:          12px 0 0 0;
}
		
	
Slika 3. - Sadržaj datoteke stil.css, sa kojom se povezuje datoteka index.php (koja sadrži formular za prijavu).

Pošto smo uspostavili mehanizam za prosleđivanje podataka, spremni smo da se pozabavimo i obradom podataka koje je korisnik prosledio pri pokušaju prijave, međutim, pre nego što uopšte pokušamo da korisniku odobrimo pristup, moramo primetiti sledeće:

  • sistem za prijavu podrazumeva pristup bazi podataka sa korisničkim podacima (ali - baza još uvek ne postoji)
  • unos lozinki u izvornom obliku, predstavlja veliki sigurnosni rizik

Prvo ćemo se pozabaviti tematikom pravilnog skladištenja lozinki u izmenjenom obliku (a "usput" ćemo diskutovati i o obradi drugih podataka koji se unose u sistem preko formulara).

Obrada podataka iz formulara i skladištenje lozinki u bazama podataka

Zapisivanje lozinki u bazama podataka, doslovno u obliku u kome ih korisnici unose, predstavlja veliki sigurnosni rizik!

Znamo da smo to već napisali nekoliko redova iznad (ali - nije naodmet da ponovimo). :)

Ukoliko se desi da neko neovlašćeno pristupi bazi podataka sa korisničkim podacima, u kojoj se lozinke skladište u izvornom obliku (prosto rečeno, ako neko "hakuje" bazu i preuzme sadržaj tabela), imaće direktan uvid u podatke za prijavu većeg broja korisnika i biće u stanju da se prijavi na bilo koji od naloga, bez imalo dodatnog truda - čime se potencijalno može izazvati velika šteta.

Postoje dokumentovani slučajevi ovakvih "upada" na veće, poznatije sajtove (tj. servere), na kojima su lozinke čuvane u izvornom obliku, a možemo samo pretpostaviti da je drugih, manje poznatih slučajeva, bilo - mnogo, mnogo više.

Slika 4. - Tabela sa korisničkim podacima - u kojoj su lozinke zapisane u izvornom obliku. Ovakav način zapisa je neadekvatan jer, u slučaju neovlašćenog pristupa podacima, postoji mogućnost direktnog čitanja svih lozinki (odnosno, praktičnije - postoji mogućnost pristupa svim nalozima).

Da bismo sprečili neovlašćeni pristup podacima (ili makar da bismo otežali neovlašćeni pristup podacima, koliko god je moguće), lozinke se ne skladište neposredno, već, u kriptovanom ("haširanom") obliku, koji nastaje upotrebom posebnih funkcija (koje će biti tema narednih poglavlja).

Slika 5. - Tabela sa korisničkim podacima - u kojoj su zapisane haširane lozinke. Ovakav način zapisa je adekvatan jer, u slučaju neovlašćenog pristupa podacima, nije moguće koristiti hash kodove za pristup (drugim rečima: iako je "obijanje" lozinki i dalje moguće - znatno je otežano).

U pitanju je sigurnosni mehanizam koji, za bilo koju unetu nisku znakova, kreira nisku od 60 naizgled nasumičnih znakova (koja odgovara unetoj lozinki), čime se postiže - "ako ništa drugo" - da lica koja su neovlašćeno pristupila podacima iz baze ne mogu neposredno koristiti podatke za prijavu.

Način kreiranja kriptovanog oblika koji ćemo prikazati, nije ni izdaleka komplikovan, * ali, to (nažalost) nije jedino o čemu se mora voditi računa.

* Da budemo precizni, mislimo na korake koje PHP programeri preduzimaju direktno, kao što ćemo prikazati kasnije u toku članka (međutim, sama procedura za kreiranje hash potpisa, zapravo je prilično kompleksna). :)

Pre nego što se lozinka kriptuje, moramo biti sigurni da sam podatak ne sadrži specijalne znakove koji se mogu umetnuti preko HTML formulara, promeniti tok izvršavanja skripte i dovesti do gubitka podataka (ili našteti sistemu i korisnicima na drugi način).

Naime, budući da se lozinke (i razni drugi podaci) unose preko HTML formulara (formulara za registraciju / prijavu / pretragu / online kupovinu / objavu komentara i sl), pri čemu su formulari tipično dostupni javno, nije teško uvideti da, u većini situacija, "bilo ko" može uneti "bilo šta" u neki od pomenutih formulara.

Prethodno navedeni pristup otvara mogućnosti zloupotrebe, i stoga je zadatak back-end programera da preduprede pokušaje unošenja neovlašćenog SQL ili HTML koda u sistem za obradu podataka.

"Sanitacija" korisničkih podataka - sprečavanje ugrađivanja nedozvoljenog SQL i HTML koda (SQL i HTML injection)

Postoji pravilo koje navodi da "ne treba verovati" podacima koje korisnici unose preko formulara, i to je pravilo koje - pokazalo se tako u praksi - treba uvek poštovati!

Po potrebi, zadržite se još koji minut na ideji koja je izneta u gornjem pasusu (pre nego što nastavite sa čitanjem i pre nego što počnete da kreirate javno dostupne web stranice). :)

Bez preduzimanja posebnih koraka, sistem za obradu korisničkih zahteva (kome se prosleđuju podaci uneti preko korisničkih formulara), ne prepoznaje znake kao što su ' i " (apostrofi i navodnici), kao opšte podatke iz upita, već prepoznaje navedene znake kao deo sopstvenog SQL koda, što (kao što smo prethodno nagovestili), predstavlja poveći problem i otvara mogućnost zloupotrebe.

Primera radi, uzmimo da se podaci uneti preko <input> polja (iz HTML forme), prosleđuju sledećem upitu:

		
<?php
	// Podaci prosleđeni sa forme:

	$korisnicko_ime = $_POST['korisnicko_ime'];
	$lozinka        = $_POST['lozinka'];

	// Upit za pristup podacima

	$upit = "SELECT * FROM korisnici WHERE korisnicko_ime='$korisnicko_ime' AND lozinka='$lozinka'";

	// U nastavku, proverava se da li je upit
	// vratio (tačno) jedan red - što predstavlja
	// signal da su uneti podaci korektni

?>
		
	
Slika 6. - Primer upita preko koga se selektuje red tabele (shodno prosleđenim podacima).

Kod sa gornje slike ne prikazuje optimalan postupak za prihvat i obradu korisničkih lozinki, ali, jednostavan je za razumevanje i dovoljno dobro "potcrtava poentu".

U normalnim okolnostima, prikazani upit izvršava se na sledeći način:

		
<?php
	// Ako su prosleđeni sledeći podaci:

	// $korisnicko_ime = "pera94";
	// $lozinka        = "ParadaYz14";

	// .... upit za pristup podacima praktično postaje:

	$upit = "SELECT * FROM korisnici WHERE korisnicko_ime='pera94'
	         AND lozinka='ParadaYz14'";

    // .... i to je (prosto rečeno) -
    // "ono što treba da se desi" ....
?>
		
	
Slika 7. - Primer izvršavanja upita sa prethodne slike - ukoliko se proslede standardni podaci.

Pod uslovom da su uneti podaci u redu (smatraćemo da jesu), sistem u nastavku dozvoljava prijavu.

Međutim, ukoliko neko prosledi sledeće podatke:

		
<?php
	$korisnicko_ime = "pera94' OR 1=1;--";
	$lozinka        = "bilo šta";
?>
		
	
Slika 8. - Primer podataka preko kojih se pokušava umetanje SQL koda u upit sa slike #6.

.... upit više nije ni najmanje (!) bezopasan:

		
SELECT * FROM korisnici WHERE korisnicko_ime='pera94' OR 1=1; --' AND lozinka='ParadaYz14'";
		
	
Slika 9. - Primer izvršavanja upita sa slike #6 - Oblik koji upit dobija ukoliko se unesu podaci koji sadrže specijalne znakove (apostrofe i znake navoda). Da bismo sprečili umetanje SQL koda, potrebno je koristiti ugrađene funkcije mysqli_real_escape_string i htmlentities.

Budući da je sistem "nekritički" prihvatio znak ' (apostrof), navedeni znak je zatvorio nisku 'pera94' i omogućio da se između korisničkog imena i "pravog" apostrofa koji je unet kao deo upita u PHP skripti, umetne proizvoljan SQL kod:

  • umetnuti kod je prepravio smisao upita ("dozvolio je prijavu" preko bilo kog postojećeg korisničkog imena (u gornjem primeru, pera94))
  • takođe je poništen ostatak upita (AND lozinka='$lozinka'), prostim stavljanjem ostatka niske pod komentar (u različitim implementacijama SQL-a, komentar tipično započinje niskom sa dve crtice --)

Srećom, ovakvi pokušaji 'obijanja' mogu se preduprediti prilično lako, * uz upotrebu dve specijalizovane funkcije za "sanitaciju":

  • mysqli_real_escape_string je funkcija koja ukida funkcionalnost znakova koji su deo SQL koda
  • htmlentities je funkcija koja ukida funkcionalnost znakova koji su deo HTML koda

* Naravno, ne kažemo da je lako obezbediti sigurnost web aplikacije u širem kontekstu, ali, svakako je red da makar ne ostavljamo "otključana vrata". :)

Preko sledećeg koda, postiže se da uneti podatak bude tretiran kao obična niska.

		
<?php
	// Na formi za registraciju,
	// korisnik je uneo lozinku
	// "ApstraKcij4~#"
	
	// Podaci sa forme za registraciju,
	// prihvataju se preko superglobalne
	// promenljive $_POST ....

	$lozinka = $_POST['registracija_lozinka'];

	// .... ali, pre preduzimanja daljih koraka
	// preuzete podatke je potrebno "provući"
	// kroz funkcije za "sanitaciju" podataka
	// (popularan naziv za procedure preko kojih
	// se u unetim niskama ukida funkcionalnost
	// specijalnih znakova, čime se sprečava
	// prosleđivanje nedozvoljenih delova koda)

	$lozinka = mysqli_real_escape_string($lozinka);
	$lozinka = htmlentities($lozinka);

	// (Tek) sada se može koristiti uneti podatak!
?>
		
	
Slika 10. - Programski kod koji, preko funkcija mysqli_real_escape_string i htmlentities, "prečišćava" podatke i ukida funkcionalnost specijalnih znakova.

Zarad preglednosti, gornja skripta sadrži samo obradu vezanu za lozinku, ali, svakako je potrebno da se prikazani proces sanitacije obavi i za sve ostale unete podatke.

Najprostije rečeno, od niski ....

		
pera94' OR 1=1;--
<a href='#'>ubačeni link</a>
		
	
Slika 11. - Niske preko kojih se pokušava umetanje SQL koda ("SQL injection").

.... obradom preko funkcije mysqli_real_escape_string (za prvu nisku) i htmlentities (za drugu), nastaju niske:

		
pera94\' OR 1=1\;--
&lt;a href='#'&gt;ubačeni link&lt;/a&gt;
		
	
Slika 12. - Niske sa slike #11 - posle 'prečišćavanja' (to jest, posle ukidanja funkcionalnosti specijalnih znakova).

Budući da prva niska sada sadrži odgovarajuće escape sekvence (koje sugerišu SQL-u da znakove, koji inače imaju specijalno značenje, treba tretirati kao obične znakove), i budući da su u drugoj niski pojave HTML znakova zamenjene odgovarajućim HTML entitetima (što neće pokrenuti kreiranje HTML/DOM objekata) - može se smatrati je bezbedno koristiti obrađene niske u daljem toku izvršavanja skripte.

Međutim, napomenućemo i to da ne treba smatrati da je svako unošenje apostrofa u HTML polja "pokušaj hakovanja", jer (recimo), sledeće niske ....

		
Shaquille O'Neal
Guns N' Roses
Livin’ on a Prayer
		
	
Slika 13. - Primeri niski koje sadrže specijalne znakove, ali, nisu namenjene "hakovanju" (već predstavljaju obična imena koja se regularno pojavljuju u upitima).

.... predstavljaju poznata imena koja se svakodnevno "provuku" kroz internet pretraživače više desetina hiljada puta. *

Upravo je zato naša obaveza da udesimo (preko funkcija koje smo naveli), da apostrofi budu svedeni na escape sekvence \' (što će biti prepoznato kao običan znak koji je deo unetog podatka, a ne kao znak koji ima posebno značenje u jeziku SQL) - čime se praktično omogućavaju "legitimni" vidovi upotrebe apostrofa na formularima.

* Nismo baš 'sasvim sigurni' da većina korisnika internet pretraživača zapravo upotrebljava velika slova i apostrofe pri pretrazi (ali za sada smo 'izabrali da verujemo' da jeste tako). :)

Takođe, kada je u pitanju sanitacija, možemo reći da su tehnike koje smo prikazali sasvim adekvatne (same po sebi), međutim, postoji i moderniji (i popularniji) način za sanitaciju podataka, preko tzv. 'pripremljenih iskaza'.

Ipak, budući da je u pitanju pristup koji programere 'rasterećuje' po pitanju svesnog vođenja računa o podacima koje korisnici prosleđuju, upoznavanje sa pripremljenim iskazima ostavićemo za kraj (i za sada ćemo se zadržati na 'starinskim' metodama) ....

Provera unetog podatka u odnosu na očekivani obrazac (preg_match)

Postupak za sanitaciju koji smo prikazali (ili postupak preko pripremljenih iskaza koji ćemo tek prikazati), obavezno se primenjuje na svaki uneti podatak (i tokom registracije, i tokom prijave korisnika), ali - pri registraciji - pažnju treba posvetiti i tome da podaci, koje korisnik prosleđuje, obavezno budu uneti u odgovarajućem formatu (dok, u formularima za prijavu, tipično možemo pustiti korisnike da "pišu šta god žele").

Ako vam poslednja konstatacija "zvuči pogrešno" - recimo da treba da bude tako. 🙂 Smatramo da bi svakom web programeru trebalo da bude stalo o sigurnosti podataka, i sledi dodatno objašnjenje ....

U "idejnom smislu", ne želimo da dopustimo korisnicima da pišu "bilo šta", ali:

  • sa jedne strane, praktično se ne može "zabraniti" korisnicima da unose proizvoljne podatke u polja za unos
  • sa druge strane, podaci svakako prolaze proces "sanitacije"

Takođe, pri obavljanju prijave, nije bitno da li se neki od unetih podataka poklapa sa predviđenim formatom, * već je samo bitno da li uneti podaci odgovaraju konkretnim podacima iz baze podataka, ** i stoga bi proces provere formata podataka koji su prosleđeni iz forme - samo nepotrebno opteretio skriptu za obradu unetih podataka (u meri koja ni izdaleka nije "zabrinjavajuća", ali, svejedno težimo tome da programski kod uvek bude optimalan).

* Bitno je samo da uneti podaci ne sadrže nedozvoljene SQL i HTML znakove (kao što smo ranije pokazali).

** Kao što smo već pominjali, uneta lozinka se neće porediti direktno sa "lozinkom iz baze", jer se lozinka u bazi ne čuva u izvornom obliku.

Preko regularnih izraza (koji se koriste na formama za registraciju), nije teško proveriti da li podaci poštuju određene standarde:

  • uneta imena i prezimena mogu sadržati samo znakove ćirilice i latinice, razmake i crtice
  • korisnička imena moraju imati odgovarajuću (minimalnu) dužinu i biti sačinjena od odgovarajućih znakova
  • dužina lozinki mora biti minimalno osam znakova (tipična vrednost) i, takođe, lozinke moraju sadržati sve kategorije znakova (velika i mala slova, cifre, specijalne znakove) *
  • brojevi telefona mogu sadržati samo cifre, kose i ravne crte, i moraju biti formatirani na propisan način
  • e-mail adrese takođe moraju imati pravilan format ("korisničko_ime@domen", bez nedozvoljenih znakova)

Pogledajmo neke od regularnih izraza koji odgovaraju prethodno nabrojanim zahtevima: **

		
// Ime i prezime:
[\p{Letter}\p{Mark} ]+

// E-mail adresa:
[a-z\._]{2,}@([a-z]{2,}\.)+([a-z]{2,}){1}

// Broj telefona:
0[0-9]{2}[/-][0-9]{3,4}-?[0-9]{3,4}
		
	
Slika 14. - Primer nekoliko regularnih izraza za proveru ulaznih podataka.

* U praksi, pri proveri lozinki, obično se u obzir uzima samo minimalna dužina (projektanti sistema za registraciju tipično uvažavaju "realno stanje stvari", a realno stanje stvari podrazumeva da lozinke kreiraju i pamte "obični ljudi", kojima je pamćenje lozinki samo "nužno zlo"). :)

Međutim, primećujemo i to da se navedena situacija polako menja, to jest, sve više i više sajtova ima "oštrije" kriterijume za izbor lozinke pri registraciji.

** Sa prikazanim izrazima upoznali smo se (u najvećoj meri) u članku o regularnim izrazima), a dodatak su moderne klase znakova: \p{Letter} i \p{Mark}, koje omogućavaju pravilno prepoznavanje Unicode znakova koji predstavljaju slova različitih pisama.

(U praktičnom smislu, klase znakova \p{Letter} i \p{Mark} mogu se koristiti za prepoznavanje znakova azbuke i latinice koji se pojavljuju u imenima i prezimenima a ne pojavljuju se u osnovnoj ASCII tabeli, i svakako je u pitanju elegantniji način u odnosu na korišćenje klasa znakova [A-Z] i [a-z] uz 'ručno' dodavanje ostalih znakova.)

Za proveru u PHP-u, koristi se funkcija preg_match (pattern/regular expression match - funkcija koja vraća vrednost true ako se uneta niska poklapa sa navedenim obrascem, ili vrednost false ako se niska ne poklapa sa obrascem), a za primer ćemo uzeti proveru unete e-mail adrese.

Posle provere unetog podatka preko funkcija mysqli_real_escape_string i htmlentities (što smo već obavili), proverićemo i da li je e-mail adresa formatirana pravilno.

Funkciji pregmatch može se proslediti regularni izraz sa slike #14 (u svojstvu argumenta), ali, tipično se u PHP-u zadatak provere e-mail adrese obavlja uz korišćenje još jedne funkcije:

  • funkcija preg_match proverava (samo) da li niska sadrži nedozvoljene znake
  • funkcija filter_var proverava da li se niska podudara sa određenim formatom

Sledeći kod, obaviće zadatak provere e-mail adrese ....

		
<?
	if (!preg_match("/^[A-Za-z0-9@._]*$/", $forma_email) ||
	   !filter_var($forma_email, FILTER_VALIDATE_EMAIL))
	{
		// Dalji koraci u obradi greške:
		// kreiranje odgovarajućeg indeksa
		// u superglobalnoj promenljivoj $_SESSION,
		// zarad prosleđivanja podataka stranici
		// za prijavu/registraciju, i sl ....
	}
?>
		
	
Slika 15. - Primer provere unete email adrese preko funkcija preg_match (koja koristi regularne izraze) i filter_var (koja proverava da li je niska formatirana po određenom obrascu (u ovom slučaju - kao email adresa)).

.... međutim, na ovom mestu verovatno ćete se zapitati (reklo bi se, sasvim opravdano i očekivano :)), zašto je uopšte potrebno koristiti funkciju preg_match, budući da funkcija filter_var proverava da li se niska uklapa u obrazac za formatiranje e-mail adresa?!

Odgovor je jednostavan, ali, istovremeno .... "pomalo čudan".

Funkcija filter_var (zaista) proverava da li se uneta niska poklapa sa obrascima za formatiranje email adresa, ali, pri tom se poštuju međunarodni standardi stari preko 25 godina, koji dopuštaju da se u email adresi nađu i znakovi kao što su #, !, ~ i slični.

Dakle, "što se tiče funkcije filter_var": niska korisnik@domen.rs je formatirana kao email adresa (što je tačno), ali, i niska k0r!$n1k#@d0m#n.r$ je takođe formatirana kao email adresa (što - iako možda jeste u skladu sa prvobitnim standardima - nikako nije nešto što se tipično/redovno sreće u praksi).

U svakom slučaju, upotrebili smo sve mehanizme provere i zaštite koji se razumno mogu predvideti, i sada ("tek sada"), kada smo (konačno!) "prečistili" unete podatke, možemo ih uneti u tabelu.

.... ali, pre nego što se posvetimo unosu podataka, osvrnućemo se prvo na tematiku kriptovanja lozinki (što smo još na početku najavili).

Kreiranje kriptovanog oblika lozinke - password_hash()

Za razliku od ostalih podataka, koji - posle "bezbedonosnih provera" - mogu odmah biti upisani u tabelu, lozinke se prvo podvrgavaju procesu enkripcije, po sledećoj proceduri:

  • korisnik, pri registraciji naloga, unosi lozinku (obavezno dvaput, zarad provere), nakon čega se uneti podatak prosleđuje skripti za kreiranje naloga.
  • uneta lozinka se podvrgava procesu "sanitacije" (ukidanje funkcionalnosti specijalnih znakova)
  • lozinka se hash-uje i skladišti u bazi

Sam proces kreiranja "haširanog" oblika lozinke podrazumeva upotrebu posebnih funkcija koje koriste kriptografske algoritme (koji nisu 'baš skroz jednostavni' za razumevanje i o kojima ćemo diskutovati neki drugi put), ali, procedura za kreiranje hash koda u PHP-u, prilično je jednostavna za implementaciju, i podrazumeva sledeće korake:

		
<?php
	$lozinka = $_POST['forma_lozinka'];
	$lozinka = mysqli_real_escape_string($lozinka);
	$lozinka = htmlentities($lozinka);

	$lozinka_hash = password_hash($lozinka, PASSWORD_DEFAULT);
?>
		
	
Slika 16. - Kreiranje kriptovanog oblika lozinke, preko funkcije password_hash.

Ako unesemo sledeću lozinku ....

		
ParadaYz14
		
	
Slika 17. - Primer lozinke u originalnom obliku.

.... od unete lozinke * (posredstvom funkcije password_hash), nastaje sledeći hash kod: **

		
$2y$10$zvsxp01IjHKVKzT15r5.Ee2sS97G.pCbnJqqd93C7XAY46t53ItEC
		
	
Slika 18. - Primer hash-iranog oblika lozinke sa prethodne slike.

* Kao i obično, apelujemo na vas - zbog vaše sigurnosti - da ne koristite lozinke sa našeg sajta (ili lozinke sa drugih sajtova i sl), odnosno, preporučujemo da kreirate sopstvene lozinke.

** Naravno, red je da se osvrnemo i na to šta je hash kod ....

Funkcije za "haširanje" operišu nad ulaznim niskama proizvoljne širine i primenjuju posebne postupke za mapiranje ulaznih podataka, tako da izlaz bude niska fiksne širine - koja odgovara ulaznom podatku ("i samo ulaznom podatku").

Niska koja se dobija na izlazu, predstavlja hash kod ulaznog podatka (a što se tiče konkretnih kriptografskih algoritama preko kojih se ulazni podaci mapiraju, to će biti tema diskusije nekom drugom prilikom (kao što smo već nagovestili)).

Drugi argument koji se predaje funkciji password_hash, predstavlja izabrani metod kriptovanja (PASSWORD_DEFAULT je standardni/podrazumevani metod, dok, po želji (najčešće samo zarad kompatibilnosti sa starijim, već postojećim bazama podataka), možemo koristiti i druge metode).

Obrađeni podatak se sada može upisati u bazu, i stoga ćemo se u sledećem poglavlju posvetiti upravo unosu podataka, nakon čega ćemo prikazati (u pretposlednjem poglavlju), proceduru provere unete lozinke u odnosu na sačuvani hash kod.

U pretposlednjem poglavlju, biće prikazana celokupna skripta za prijavu korisnika.

Podaci za prijavu

Pošto smo se postarali da podaci koje unosimo budu "onakvi kakvi bi trebalo da budu", možemo podatke (zapravo) i upisati u tabelu.

U pitanju je postupak koji se tipično obavlja pri registraciji, ali, pošto članak na eklektičan način obrađuje obe teme (registraciju i prijavu), jednostavno ćemo podatke uneti ručno (za sam početak), da bismo sistemu obezbedili početnu funkcionalnost.

Kreiranje baze podataka sa korisnicima

Prema uputstvima iz članka o povezivanju PHP skripti sa MySql bazama podataka, kreirajte skriptu za povezivanje sa serverom (za početak, nemojte unositi ime baze - iz očiglednih razloga), i potom pokrenite sledeći upit za kreiranje baze podataka:

		
<?php
	require_once('povezivanje.php');

	$upit = "CREATE DATABASE korisnici";

	$rezultat = mysqli_query($veza, $upit);

	if (!$rezultat) {
		echo "Greška pri kreiranju baze podataka.";
		exit();
	}
?>
		
	
Slika 19. - Skripta za kreiranje baze podataka u kojoj će biti skladišteni korisnički podaci.

Da se podsetimo ('još jednom'): potrebno je smestiti skripte u zajednički folder i dodeliti im prepoznatljiva imena.

Posle kreiranja baze, možemo kreirati i popuniti tabelu sa korisnicima.

Kreiranje tabele sa korisničkim podacima

Prepravite skriptu povezivanje.php, tako da se pri povezivanju koristi i naziv baze ("korisnici"), i kreirajte zatim novu skriptu, preko koje ćemo kreirati tabelu korisnici:

		
<?php
	require_once('povezivanje.php');

	$upit = "CREATE TABLE korisnici
			(
				id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
				korisnicko_ime varchar(255) NOT NULL,
				lozinka_hash   varchar(255) NOT NULL,
				email          varchar(255) NOT NULL
			)";

	$rezultat = mysqli_query($veza, $upit);

	if (!$rezultat) {
		echo "Greška pri kreiranju tabele.";
		exit();
	}
?>
		
	
Slika 20. - Skripta za kreiranje tabele korisnici, u kojoj će direktno biti skladišteni korisnički podaci.

Pošto je uspostavljena osnovna struktura, tabela se (u nastavku) može popuniti korisničkim podacima.

Unos korisničkih podataka u tabelu

Podaci preuzeti iz forme za registraciju, mogu se uneti u tabelu korišćenjem odgovarajuće skripte:

		
<?php
	require_once('povezivanje.php');

	// Preuzimanje podataka iz forme
	// (provera indeksa preko funkcije isset,
	// izostavljena je zarad preglednosti
	// i treba je dodati)

	$korisnicko_ime = $_POST['korisnicko_ime'];
	$lozinka        = $_POST['lozinka'];
	$email          = $_POST['email'];

	// Sanitacija:

	$korisnicko_ime = mysqli_real_escape_string($veza, $korisnicko_ime);
	$korisnicko_ime = htmlentities($veza, $korisnicko_ime);

	$lozinka        = mysqli_real_escape_string($veza, $lozinka);
	$lozinka        = htmlentities($veza, $lozinka);

	$email          = mysqli_real_escape_string($veza, $email);
	$email          = htmlentities($veza, $email);

	// Kreiranje hash-irane verzije lozinke ....

	$lozinka_hash = password_hash($lozinka, PASSWORD_DEFAULT);

	// Upis podataka u tabelu:

	$upit = "INSERT INTO korisnici
			     (korisnicko_ime, lozinka_hash, email)
			 VALUES
				 ('$korisnicko_ime', '$lozinka_hash', '$email')";

	$rezultat = mysqli_query($veza, $upit);

	if (!$rezultat)
	{
		echo "Greška pri unosu podataka u tabelu";
		exit();
	}
?>
		
	
Slika 21. - Skripta za obradu podataka iz formulara za registraciju.

U pitanju je skripta kakvu bismo koristili za obradu podataka koji su prosleđeni preko formulara za registraciju, ali, budući da to (zvanično) nije tema ovog članka, koristićemo pojednostavljenu skriptu sa "hardkodiranim" podacima i nećemo obavljati provere (mi nećemo sami sebe "hakovati", a nemojte ni vi):

		
<?php
	require_once('povezivanje.php');

	// Smatraćemo da su iz forme forme za
	// registraciju preuzeti sledeći podaci:

	$korisnicko_ime = "petar_011";
	$lozinka        = "ApstraKcij4~#";
	$email          = "petar_m@proba.rs";

	// Kreiraćemo hash kod unete lozinke ....

	$lozinka_hash = password_hash($lozinka, PASSWORD_DEFAULT);

	// .... i zatim upisati podatke u tabelu:

	$upit = "INSERT INTO korisnici
			     (korisnicko_ime, lozinka_hash, email)
			 VALUES
				 ('$korisnicko_ime', '$lozinka_hash', '$email')";

	$rezultat = mysqli_query($veza, $upit);

	if (!$rezultat)
	{
		echo "Greška pri unosu podataka u tabelu";
		exit();
	}
?>
		
	
Slika 22. - Pomoćna skripta za "priručno" popunjavanje tabele korisnici (bez potrebe za korišćenjem formulara za registraciju).

Sada, kada postoji (bar jedan) korisnički nalog u tabeli sa korisnicima (bez čega mehanizam za prijavu praktično ne može da funkcioniše), možemo se posvetiti izradi skripte za prijavu (što - ako smo usput možda i zaboravili - i dalje "zvanično" predstavlja glavnu temu članka). :)

Obrada podataka za prijavu

Kreirajte datoteku sa nazivom obrada.php i unesite u datoteku sledeći kod (objašnjenja su u komentarima):

		
<?php
	require_once('povezivanje.php');

	// Prijem podataka;
	// (dodajte proveru indeksa preko funkcije isset)

	$korisnicko_ime = $_POST['korisnicko_ime'];
	$lozinka        = $_POST['lozinka'];

	// Sanitacija:

	$korisnicko_ime = mysqli_real_escape_string($veza, $korisnicko_ime);
	$korisnicko_ime = htmlentities($korisnicko_ime);

	$lozinka = mysqli_real_escape_string($veza, $lozinka);
	$lozinka = htmlentities($lozinka);

	// Prijava:

	$upit     = "SELECT * FROM korisnici WHERE
	             korisnicko_ime='$korisnicko_ime'";
	$rezultat = mysqli_query($veza, $upit);

	// Ukoliko je korisničko ime pravilno uneto, tabela
	// rezultat sadržaće tačno jedan red (u suprotnom
	// prekinućemo dalje izvršavanje skripte)

	if (mysqli_num_rows($rezultat) != 1) {
		echo "Uneto korisničko ime nije prepoznato.<br>";
		echo "Vratite se nazad i pokušajte ponovo.<br>";
		exit();
	}

	// Ukoliko je do sada bilo sve u redu,
	// potrebno je proveriti i lozinku.
	// Prvo se čita prvi (i jedini) red
	// tabele (if nije potreban, jer smo
	// prethodno ustanovili da postoji
	// tačno jedan red u tabeli) ....

	$red = mysqli_fetch_assoc($rezultat);

	// .... a onda se može proveriti i lozinka

	if (!password_verify($lozinka, $red['lozinka_hash'])) {
		echo "Pogrešno uneta lozinka.<br>";
		echo "Vratite se nazad i pokušajte ponovo.<br>";
		exit();
	}

	// Dakle, ako funkcija password_verify
	// ustanovi da uneta lozinka ne vraća
	// odgovarajući hash kod, prekida se
	// izvršavanje skripte.
	// U suprotnom, prelazi se na ....

	// OSTATAK SKRIPTE

	echo "Uspešno ste se prijavili!<br>";

	// .... prikazivanje pozdravne poruke,
	// učitavanje sadržaja shodno korisničkom
	// nalogu i sl ....
?>
		
	
Slika 23. - Skripta za obradu podataka iz formulara za prijavu.

Pred kraj, pogledaćemo kako korisnika možemo obavestiti o neuspešnom pokušaju prijave, vraćanjem na stranicu za prijavu i označavanjem polja sa pogrešno unetim podacima.

Vraćanje podataka stranici za prijavu, preko superglobalne promenljive $_SESSION

Sa jedne strane može se reći da je krajnje adekvatno da se skripta za obradu unetih podataka koristi i za ispis poruka o greškama pri prijavljivanju ....

U primerima koje prikazujemo, obrada se obavlja preko skripte obrada.php.

.... međutim, nepisana pravila modernog web dizajna podrazumevaju malo drugačiji pristup: u slučaju neuspešnog pokušaja prijave, korisnike treba obaveštavati preko istog formulara preko koga su prvobitno pokušali da obave prijavu (pri čemu, zbog brzine izvršavanja, često deluje da se korisnik nije ni udaljio sa stranice za prijavu).

Sa navedenim pristupom već smo se upoznali, u članku o superglobalnoj promenljivoj $_SESSION, pa ovoga puta neće biti teško da implementiramo formular za prijavu uz korišćenje već poznatih ideja (bitni detalji implementacije navedeni su u komentarima):

		
<?php
	// Da se podsetimo, komanda session_start()
	// poziva se na samom početku:

	session_start();

	// .... a provera indeksa preko funkcije isset,
	// i ovoga puta je izostavljena zarad preglednosti
	// (i treba je dodati)

	require_once('povezivanje.php');

	$korisnicko_ime = $_POST['korisnicko_ime'];
	$lozinka        = $_POST['lozinka'];

	$korisnicko_ime = mysqli_real_escape_string($veza, $korisnicko_ime);
	$korisnicko_ime = htmlentities($korisnicko_ime);
	$korisnicko_ime = trim($korisnicko_ime);

	$lozinka = mysqli_real_escape_string($veza, $lozinka);
	$lozinka = htmlentities($lozinka);
	$lozinka = trim($lozinka);

	// Ovoga puta, potrebno je proveriti
	// da li je korisničko ime UOPŠTE uneto:

	if (strlen($korisnicko_ime) == 0)
	{
		$_SESSION['greska_korisnicko_ime'] = "Unesite korisničko ime";
		header("location: index.php");
		exit();
	}

	unset($_SESSION['greska_korisnicko_ime']);

	$upit     = "SELECT * FROM korisnici WHERE
	             korisnicko_ime='$korisnicko_ime'";
	$rezultat = mysqli_query($veza, $upit);

	if (mysqli_num_rows($rezultat) != 1)
	{
		// Ovoga puta, poruku o grešci se prosleđuje 'unazad'
		// preko superglobalne promenljive $_SESSION
		
		$_SESSION['greska_korisnicko_ime'] = "Korisničko ime nije prepoznato.";
		header("location: index.php");
		exit();
	}

	// Ako je skripta došla do ovog mesta, smatraćemo da
	// sa unosom korisničkog imena nije bilo grešaka, i stoga
	// se može ukloniti indeks 'greska_korisnicko_ime'

	unset($_SESSION['greska_korisnicko_ime']);

	$red = mysqli_fetch_assoc($rezultat);

	if (!password_verify($lozinka, $red['lozinka_hash']))
	{
		// Kao i za korisničko ime, ovoga puta ćemo
		// poruku o grešci proslediti unazad
		// preko superglobalne promenljive $_SESSION

		$_SESSION['greska_lozinka'] = "Pogrešno uneta lozinka.<br>Pokušajte ponovo.<br>";
		header("location: index.php");
		exit();
	}

	unset($_SESSION['greska_lozinka']);

	echo "Uspešno ste se prijavili!<br>";
?>
		
	
Slika 24. - Dopunjena skripta za obradu podataka iz formulara za prijavu. Da bi početnoj stranici bili prosleđeni podaci o greškama koje se mogu pojaviti pri pokušaju prijave, koristi se superglobalna promenljiva $_SESSION (u slučaju pojave grešaka - sledi povratak na stranicu za prijavu i posebno označavanje polja za unos).

Sada možemo prepraviti i formu za prijavu (zarad preglednosti nećemo prikazivati celu skriptu):

		
<form method='post' action='prijava.php'>
	<input
		<?php
			if (isset($_SESSION['greska_korisnicko_ime']))
			{
				echo "class = 'okvir_crveni'";
			}
			else
			{
				echo "class = 'okvir_crni'";
			}
		?>

		type        = 'text'
		placeholder = 'Korisničko ime'
		name        = 'korisnicko_ime'
	/>
	
	<input
		<?php
			if (isset($_SESSION['greska_lozinka']))
			{
				echo "class = 'okvir_crveni'";
			}
			else
			{
				echo "class = 'okvir_crni'";
			}
		?>

		type        = 'password'
		placeholder = 'Lozinka'
		name='lozinka'
	/>
	
	<input
		type  = 'submit'
		value = 'PRIJAVA'
	/>
</form>

<!--
	Ispod forme, dodaćemo div u kome se ispisuju greške:
-->

<div id='ispis_gresaka'>
	<?php
		if (isset($_SESSION['greska_korisnicko_ime'])) {
			echo $_SESSION['greska_korisnicko_ime'];
		}
		else {
			echo "";
		}

		if (isset($_SESSION['greska_lozinka'])) {
			echo $_SESSION['greska_lozinka'];
		}
		else {
			echo "";
		}
	?>
</div>
		
	
Slika 25. - PHP kod preko koga se definiše formular za prijavu (sa slike #1). Formular sadrži PHP blokove u kojima se superglobalna promenljiva $_SESSION koristi zarad povratka informacije o pogrešno unetim podacima: ukoliko su podaci pogrešno uneti, stranica za obradu vraća posetioca sajta na formular za prijavu, zatim, označava - crvenim okvirom - polja sa pogrešno unetim podacima, i takođe ispisuje poruke u pomoćnom div-u ispod formulara.

Osvrnimo se na nekoliko detalja:

  • budući da su atributi u <input> poljima zapisani pedantno (jedni ispod drugih), lako je bilo zaključiti gde treba "uglaviti" blokove PHP koda
  • informacije o pojavi grešaka prikazuju se uključivanjem crvenih okvira na <input> poljima i ispisom grešaka u pomoćnom <div> elementu (ispod forme)

Za sam kraj (kao što smo ranije najavili), sledi uvod u moderniji i popularniji način za prosleđivanje upita ....

Kratak osvrt na pripremljene iskaze ("prepared statements")

Pripremljeni iskazi (eng. prepared statement(s)), pojavljuju se kao dodatna mogućnost na MySql serverima i praktično predstavljaju 'šablone za izvršavanje upita'.

Način upotrebe je idejno sličan postupku koji je ranije opisan u članku, * i obuhvata dve etape:

  • pripremu i prosleđivanje šablona
  • prosleđivanje podataka i izvršavanje upita

* Proces svakako jeste sličan (naizgled), ali, ima i 'dodatnih pogodnosti' (koje ćemo prikazati).

U prvoj etapi priprema se šablon (koji nalikuje 'običnom upitu', ali, sadrži generičke oznake za vrednosti polja (?)), nakon čega se šablon prosleđuje MySql serveru, što praktično 'otvara mogućnost' da navedeni šablon posluži za kreiranje upita koji će biti pokrenut(i) u nekom kasnijem trenutku.

U drugoj etapi (koja tipično sledi neposredno nakon prve), prosleđuju se realni parametri i pokreće se upit (pri čemu se sanitacija podataka podrazumeva, to jest, odvija se automatski, bez potrebe za eksplicitnim navođenjem naredbi sa kojima smo se ranije upoznali).

Pogledajmo tipičan primer upotrebe pripremljenog iskaza:

		
<?php
	// priprema:

	$upit = "INSERT INTO t1(ime, prezime, email) VALUES (?, ?, ?)";
	$stmt = mysqli_prepare($veza, $upit);

	// povezivanje sa realnim parametrima:

	$ime     = "Petar";
	$prezime = "Marić";
	$email   = "petar_maric@domen.rs";
	mysqli_stmt_bind_param($stmt, "sss", $ime, $prezime, $email);

	// izvršavanje upita:

	mysqli_stmt_execute($stmt);

	/*
		INSERT INTO t1
			(ime, prezime, email)
		VALUES
			("Petar", "Marić", "petar_maric@domen.rs")
	*/
?>
		
	
Slika 26. - Pripremljeni iskazi ('prepared statements') - opšta šema.

Kao što vidimo, prve dve komande ne obuhvataju prosleđivanje i pokretanje upita (kao u ranijim primerima), već: pripremu šablona, i prosleđivanje šablona na MySql server.

U sledeće tri naredbe definišu se promenljive koje sadrže vrednosti (praktično: vrednosti polja u 'budućem upitu'), nakon čega se poziva funkcija mysqli_stmt_bind_param, preko koje se navedene PHP promenljive povezuju sa placeholderima ? iz ranije prosleđenog upita.

U konkretnom primeru, niska "sss" (koja se predaje kao drugi argument), ukazuje na to da parametri (redom) predstavljaju niske (tj. "stringove")).

Ukoliko bi upit sadržao dva parametra koji predstavljaju, redom: celobrojnu promenljivu i nisku, niska koja se predaje funkciji mysqli_stmt_bind_param imala bi sledeći oblik: "is" (integer-string).

Na kraju, preko funkcije mysqli_stmt_execute, na MySql serveru se pokreće upit (koji je ranije pripremljen).

U nekom kasnijem trenutku, isti objekat ($stmt), može se koristiti za prosleđivanje (praktično) istog upita, ali - sa drugim parametrima (pri čemu se navode samo 'nove' vrednosti promenljivih).

Na primer:

		
<?php
	$ime     = "Milan";
	$prezime = "Kovačević";
	$email   = "milan_kovacevic@domen.rs";

	mysqli_stmt_execute($stmt);

	/*
		INSERT INTO t1
			(ime, prezime, email)
		VALUES
			("Milan", "Kovaćević", "milan_kovacevic@domen.rs")
	*/
?>
		
	
Slika 27. - Pripremljeni iskaz - primer prosleđivanja novog upita.

Preko primera koji smo prikazali, moguće je sagledati opšte 'tehničke karakteristike' pripremljenih iskaza:

  • objekat $stmt povezuje se sa određenim 'pripremljenim upitom' (u konkretnom primeru, sa upitom INSERT INTO t1(ime, prezime, email) VALUES (?, ?, ?))
  • generičke vrednosti polja iz šablona (?), povezuju se sa konkretnim vrednostima pre pokretanja upita

Način povezivanja i pokretanja, ni u kom slučaju nije komplikovan za razumevanje, međutim, potrebno je dodatno se osvrnuti na drugu stavku iz gornje liste:

  • pripremljeni iskazi se tipično povezuju sa promenljivama (baš kao u primeru koji smo prikazali)
  • u trenutku pokretanja upita, koriste se trenutne vrednosti promenljivih, ali .... upit je i 'nadalje' povezan sa promenljivom
  • ukoliko se vrednost određene promenljive promeni, pri sledećem pokretanju upita biće upotrebljena nova vrednost

Summa summarum: sintaksa pripremljenih iskaza je ponešto različita i neznatno kompleksnija (u odnosu na 'ručno prečišćavanje podataka'), ali, pristup je u idejnom smislu gotovo isti (a vredi pomenuti i to da drugi popularni jezici takođe podržavaju upotrebu pripremljenih iskaza, pri čemu su 'tehnikalije' vrlo slične).

Kao što naslov odeljka sugeriše, prikazali smo samo kratak pregled osnovnih mogućnosti pripremljenih iskaza, međutim, u pitanju je tema koja (ipak) zahteva nešto više vremena i prostora za pravo upoznavanje, i stoga ćemo ovoj temi u dogledno vreme posvetiti zaseban članak.

Za kraj ....

Za kraj ostaje da vam ponovo predložimo da isprobate tehnike koje smo opisali, kroz sledeće primere:

  • probajte (ponovo) da kreirate formular za prijavu korisnika, ali - ovoga puta samostalno
  • probajte da predate upite preko pripremljenih iskaza (bar ponegde)
  • probajte da samostalno kreirate formular za registraciju korisnika

Takođe, ukoliko želite da isprobate formular koji smo izrađivali u članku, možete ispratiti sledeći link (ukoliko već niste):

Formular za prijavu korisnika

Podaci za prijavu su oni koje smo koristili u članku.

Autor članka Nikola Vukićević Za web portal codeblog.rs
Napomena: Tekstovi, slike, web aplikacije i svi ostali sadržaji na sajtu codeblog.rs (osim u slučajevima gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog pismenog odobrenja autora.
© 2020-2026. Sva prava zadržana.
Facebook LinkedIn Twitter Viber WhatsApp E-mail
početna > Članci > Tutorijal - PHP - Kreiranje forme za prijavu korisnika
codeBlog codeBlog
Sajt posvećen popularizaciji kulture i veštine programiranja.
Napomena: Tekstovi i slike na sajtu codeblog.rs (osim u slučajevima, gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog odobrenja autora.
© 2020-2026. Sva prava zadržana.
Facebook - logo
Instagram - logo
LinkedIn - logo
Twitter - logo
E-mail
Naslovna
   •
Uslovi korišćenja
   •
Obaveštenja
   •
FAQ
   •
Kontakt