V PHP vgrajene spremenljivke
PHP tečaj: V PHP vgrajene spremenljivke
Naš PHP program (skripta) lahko pri izvajanju dostopa do vrednosti številnih vgrajenih spremenljivk in polj. Tako lahko dostopamo na primer do podatkov, ki nam jih je uporabnik poslal preko spletnega obrazca. Lahko dostopamo tudi do uporabnikovega IP naslova, do piškotkov v uporabnikovem brskalniku in tako naprej.
Vse te vgrajene spremenljivke so "superglobalne", kar v praksi pomeni, da lahko do njih dostopamo tudi znotraj funkcij brez uporabe ukaza global ali argumentov.
Za začetek si poglejmo, kako preberemo podatke, ki nam jih uporabniki pošljejo npr. preko spletnega obrazca.
Vse poslane podatke (imena spremenljivk in njihove vrednosti) navedemo na koncu URL naslova, pred njih pa najprej dodamo znak ?.
Pozor: Če želimo v neko povezavo <a> vstaviti podatke, jih moramo najprej ustrezno "zakodirati" z že omenjeno funkcijo urlencode(), da so podatki primerni za prenos preko URL naslova.1
Primer: http://www.primer.si/stran.php?ime=Janez&poklic=programer
Z obiskom tega spletnega naslova v skripto stran.php pošljemo podatka o imenu ter poklicu osebe. Do teh dveh podatkov lahko skripta stran.php dostopa preko spremenljivk $_GET['ime'] ter $_GET['poklic'].
Če dobro pogledate, je $_GET v resnici asociativno polje (ang. array). V našem primeru ima to polje pod ključem 'ime' shranjeno poslani podatek o imenu osebe, pod ključem 'poklic' pa podatek o poklicu osebe.
Zato rečemo, da poslane podatke preko GET protokola beremo iz polja $_GET.
Varnost: Kar se tiče varnosti, bomo obdelali splošna načela v naslednjem poglavju o polju $_POST.
Varnost: Podatke iz piškotkov in tiste, ki so poslani preko HTTP metod GET in POST, moramo obravnavati kot potencialno "nevarne", saj jih lahko zlonameren uporabnik poljubno spreminja in dodaja.
Če pričakujete številčne podatke, uporabite funkciji intval() in doubleval().
Če pričakujete tekstovne podatke, uporabite sledeče funkcije:
Primer kode, kjer preko metode POST za podatek leto_rojstva sprejmemo samo cela števila:
Po tej operaciji smo lahko prepričani, da imamo v spremenljivki $_POST['leto_rojstva'] shranjeno celo število. Če je zlonameren uporabnik poslal karkoli drugega kot celo število, smo namreč z operacijo intval() poslano vrednost avtomatsko pretvorili v število 0.
Na tej točki lahko preverimo, če imamo opravka s številom 0, in v tem primeru uporabnika obvestimo o vnosu neveljavnega podatka. Primer kode:
Še vedno pa nam lahko v tem primeru zlonameren uporabnik pošlje letnico rojstva 492, ki je očitno nesmiselna. Našo kodo lahko izboljšamo takole:
Varnost: Podatka o imenu in vrsti datoteke nista zanesljiva in ju moramo v skripti dodatno preveriti, npr. s funkcijama basename() ter mime_content_type().
Primer: Nalaganje datoteke iz spletnega obrazca, kjer imamo okence za izbiro datoteke z imenom datoteka1. Datoteko na strežniku iz začasne mape premaknemo2 v mapo slike z uporabo funkcije move_uploaded_file().3
Če želimo preko spletnega obrazca na strežnik nalagati večje datoteke, moramo povečati PHP nastavitvi post_max_size ter upload_max_filesize. To lahko naredimo kar znotraj našega programa s funkcijo ini_set(nastavitev, vrednost). Za nalaganje slik in podobnih dokumentov predlagamo maksimalno vrednost "32M" oziroma 32 megabajtov.
Vrednosti v polju $_SERVER so odvisne od strežniške programske opreme (Apache, IIS, Lighttpd, ...) in zato niso vedno enake.
Večina strežnikov nam znotraj polja ponuja sledeče podatke:
V piškotkih shranjujemo krajše podatke (npr. uporabniško ime in kodirano geslo), ki se shranijo na uporabnikov računalnik. Do njih lahko kasneje dostopamo in jih po želji tudi spreminjamo ali brišemo.
Če si pogledamo piškotek z imenom geslo, do njegove vrednosti dostopamo preko $_COOKIE['geslo'].
Piškotke upravljamo z vgrajeno funkcijo setcookie(ime_piskotka, vrednost [, potece [, pot [, domena ]]]), kjer moramo obvezno navesti najmanj prva dva argumenta: ime piškotka in njegovo vrednost. Lahko navedemo tudi timestamp poteka7 ter pot8 in domeno9 na strežniku, kjer je do piškotka moč dostopati.
Piškotek izbrišemo tako, da mu določimo prazno vrednost in timestamp poteka, ki predstavlja nek trenutek v preteklosti.
Primer kode za izbris piškotka z imenom "geslo":
Podobno kot funkcijo header() moramo tudi funkcijo setcookie() klicati pred začetkom izpisa npr. s funkcijo echo in pred morebitno HTML kodo.
Do vrednosti piškotka preko polja $_COOKIE lahko dostopamo šele ob uporabnikovem naslednjem obisku strani, zato je priporočljivo, da pri klicu funkcije setcookie() ročno določimo še vrednost spremenljivke v polju $_COOKIE.
Primer kode za nastavitev piškotka z imenom "geslo":
Varnost: Uporabnik lahko s posebnimi orodji ali z lokalnim proxy strežnikom spreminja in bere piškotke. Zaradi tega moramo morebitne "občutljive" podatke v piškotkih kodirati, npr. s funkcijo md5() ali sha1(). Veljavnost prebranih piškotkov moramo vsakič znova preveriti — o tem smo v tem poglavju že govorili, v razdelku "Varnost" pri polju $_POST.
Zaradi preglednosti vaše programske kode sicer priporočamo, da posamezne spremenljivke vedno berete iz namenskih polj, v katera sodijo.
Uporabnik ob prvem obisku naše spletne strani v obliki piškotka dobi unikatno ID oznako seje (ang. session ID). Ob vsakem nadaljnem obisku naše spletne strani potem uporabnikov spletni brskalnik strežniku avtomatsko pošlje to ID oznako seje, na podlagi katere lahko uporabnik posledično dostopa do svojih "sejnih" spremenljivk na strežniku.
"Sejni" podatki so na voljo samo uporabniku z ustrezno ID oznako seje, na voljo pa so mu v vseh PHP skriptah na istem strežniku. Seja se zaključi in pobriše, ko uporabnik zapre okno spletnega brskalnika ali pa je dalj časa nedejaven.10
Uporabo seje v programskem jeziku PHP pričnemo s klicem funkcije session_start(), ki ga moramo izvesti še pred prvo uporabo funkcije echo za izpis in pred prvo uporabo HTML kode.
Ko je seja aktivna, lahko polju $_SESSION prirejamo nove vrednosti in jih tekom seje tudi preberemo. Če želimo izničiti posamezne sejne spremenljivke, uporabimo funkcijo unset().
Primer kode za uporabo "sejnih" spremenljivk:
S tem smo spoznali v PHP vgrajene spremenljivke, do katerih ima naš PHP program vedno dostop. Videli ste, da te vgrajene spremenljivke uporabljamo med drugim tudi za branje podatkov, ki nam jih preko spletnih obrazcev pošljejo naši uporabniki.
Kaj pa, če želimo prejete podatke shraniti za kasnejšo uporabo? O tem bomo govorili v naslednjem poglavju...
Vse te vgrajene spremenljivke so "superglobalne", kar v praksi pomeni, da lahko do njih dostopamo tudi znotraj funkcij brez uporabe ukaza global ali argumentov.
Za začetek si poglejmo, kako preberemo podatke, ki nam jih uporabniki pošljejo npr. preko spletnega obrazca.
Polje $_GET
V tem polju se nahajajo spremenljivke, ki smo jih skripti poslali preko HTTP metode GET. Pri tej metodi se imena spremenljivk in njihove vrednosti pošiljajo kar preko URL naslova. Vrednost nekemu imenu spremenljivke priredimo z enačajem =, pare spremenljivk in vrednosti pa združujemo z znakom &.Vse poslane podatke (imena spremenljivk in njihove vrednosti) navedemo na koncu URL naslova, pred njih pa najprej dodamo znak ?.
Pozor: Če želimo v neko povezavo <a> vstaviti podatke, jih moramo najprej ustrezno "zakodirati" z že omenjeno funkcijo urlencode(), da so podatki primerni za prenos preko URL naslova.1
Primer: http://www.primer.si/stran.php?ime=Janez&poklic=programer
Z obiskom tega spletnega naslova v skripto stran.php pošljemo podatka o imenu ter poklicu osebe. Do teh dveh podatkov lahko skripta stran.php dostopa preko spremenljivk $_GET['ime'] ter $_GET['poklic'].
Če dobro pogledate, je $_GET v resnici asociativno polje (ang. array). V našem primeru ima to polje pod ključem 'ime' shranjeno poslani podatek o imenu osebe, pod ključem 'poklic' pa podatek o poklicu osebe.
Zato rečemo, da poslane podatke preko GET protokola beremo iz polja $_GET.
Varnost: Kar se tiče varnosti, bomo obdelali splošna načela v naslednjem poglavju o polju $_POST.
Polje $_POST
V tem polju se nahajajo spremenljivke, ki smo jih skripti poslali preko HTTP metode POST. Običajno za pošiljanje spletnih obrazcev (ang. forms) uporabljamo to metodo.Varnost: Podatke iz piškotkov in tiste, ki so poslani preko HTTP metod GET in POST, moramo obravnavati kot potencialno "nevarne", saj jih lahko zlonameren uporabnik poljubno spreminja in dodaja.
Če pričakujete številčne podatke, uporabite funkciji intval() in doubleval().
Če pričakujete tekstovne podatke, uporabite sledeče funkcije:
- htmlspecialchars() — če želite morebitno HTML kodo iz uporabnikovega niza spremeniti v navadno besedilo, s čimer se zaščitite pred XSS (Cross-Site Scripting) napadi
- strip_tags() — če želite morebitno HTML kodo popolnoma odstraniti
- mysql_real_escape_string() — če želite podatke "escapati", preden jih vstavite v MySQL podatkovno bazo, s čimer se zaščitite pred SQL Injection napadi
- uporabite lahko tudi regularne izraze, s katerimi točno določite dovoljeno obliko vnešenih nizov
Primer kode, kjer preko metode POST za podatek leto_rojstva sprejmemo samo cela števila:
$_POST['leto_rojstva'] = intval($_POST['leto_rojstva']);
Po tej operaciji smo lahko prepričani, da imamo v spremenljivki $_POST['leto_rojstva'] shranjeno celo število. Če je zlonameren uporabnik poslal karkoli drugega kot celo število, smo namreč z operacijo intval() poslano vrednost avtomatsko pretvorili v število 0.
Na tej točki lahko preverimo, če imamo opravka s številom 0, in v tem primeru uporabnika obvestimo o vnosu neveljavnega podatka. Primer kode:
$_POST['leto_rojstva'] = intval($_POST['leto_rojstva']);
if ($_POST['leto_rojstva'] == 0) {
exit("Vnesli ste neveljavno letnico rojstva.");
}
/* v nasprotnem primeru se koda izvaja dalje,
letnico rojstva lahko npr. shranimo v podatkovno bazo */
Še vedno pa nam lahko v tem primeru zlonameren uporabnik pošlje letnico rojstva 492, ki je očitno nesmiselna. Našo kodo lahko izboljšamo takole:
$_POST['leto_rojstva'] = intval($_POST['leto_rojstva']);
if ($_POST['leto_rojstva'] == 0) {
exit("Vnesli ste neveljavno letnico rojstva.");
} else if ($_POST['leto_rojstva'] < 1900) {
exit("Dvomimo, da štejete krepko čez 100 let.");
}
/* če zgornja pogoja nista resnična, se funkcija exit()
ne pokliče, torej se koda izvaja dalje */
Polje $_FILES
V tem polju naš PHP program prejme podatke o morebitnih naloženih datotekah, ki smo jih skripti poslali z metodo POST. Za vsako datoteko so nam na voljo naslednji podatki:- name — originalno ime datoteke
- type — MIME tip datoteke
- size — velikost datoteke v bajtih
- tmp_name — začasna pot do datoteke na strežniku
Varnost: Podatka o imenu in vrsti datoteke nista zanesljiva in ju moramo v skripti dodatno preveriti, npr. s funkcijama basename() ter mime_content_type().
Primer: Nalaganje datoteke iz spletnega obrazca, kjer imamo okence za izbiro datoteke z imenom datoteka1. Datoteko na strežniku iz začasne mape premaknemo2 v mapo slike z uporabo funkcije move_uploaded_file().3
move_uploaded_file(
$_FILES['datoteka1']['tmp_name'],
"slike/{$_FILES['datoteka1']['name']}"
);
Če želimo preko spletnega obrazca na strežnik nalagati večje datoteke, moramo povečati PHP nastavitvi post_max_size ter upload_max_filesize. To lahko naredimo kar znotraj našega programa s funkcijo ini_set(nastavitev, vrednost). Za nalaganje slik in podobnih dokumentov predlagamo maksimalno vrednost "32M" oziroma 32 megabajtov.
Polje $_SERVER
To polje vsebuje podatke o strežniku in odjemalcu (ang. client). Odjemalec je v tem primeru naš spletni brskalnik, s katerim poganjamo PHP skripto.Vrednosti v polju $_SERVER so odvisne od strežniške programske opreme (Apache, IIS, Lighttpd, ...) in zato niso vedno enake.
Večina strežnikov nam znotraj polja ponuja sledeče podatke:
- $_SERVER['SERVER_ADDR'] — IP naslov strežnika, na katerem se skripta izvaja
- $_SERVER['SERVER_SOFTWARE'] — podatek o programski opremi strežnika
- $_SERVER['HTTP_REFERER'] — naslov morebitne spletne strani, ki je uporabnika usmerila na to skripto4
- $_SERVER['HTTP_USER_AGENT'] — podatki o spletnem brskalniku uporabnika5
- $_SERVER['REMOTE_ADDR'] — IP naslov uporabnika6
Polje $_COOKIE
V tem polju se nahajajo vsi uporabnikovi piškotki, ki so relevantni (veljavni) za trenutno domeno in pot do skripte.V piškotkih shranjujemo krajše podatke (npr. uporabniško ime in kodirano geslo), ki se shranijo na uporabnikov računalnik. Do njih lahko kasneje dostopamo in jih po želji tudi spreminjamo ali brišemo.
Če si pogledamo piškotek z imenom geslo, do njegove vrednosti dostopamo preko $_COOKIE['geslo'].
Piškotke upravljamo z vgrajeno funkcijo setcookie(ime_piskotka, vrednost [, potece [, pot [, domena ]]]), kjer moramo obvezno navesti najmanj prva dva argumenta: ime piškotka in njegovo vrednost. Lahko navedemo tudi timestamp poteka7 ter pot8 in domeno9 na strežniku, kjer je do piškotka moč dostopati.
Piškotek izbrišemo tako, da mu določimo prazno vrednost in timestamp poteka, ki predstavlja nek trenutek v preteklosti.
Primer kode za izbris piškotka z imenom "geslo":
setcookie("geslo", null, time() - 100000);
Podobno kot funkcijo header() moramo tudi funkcijo setcookie() klicati pred začetkom izpisa npr. s funkcijo echo in pred morebitno HTML kodo.
Do vrednosti piškotka preko polja $_COOKIE lahko dostopamo šele ob uporabnikovem naslednjem obisku strani, zato je priporočljivo, da pri klicu funkcije setcookie() ročno določimo še vrednost spremenljivke v polju $_COOKIE.
Primer kode za nastavitev piškotka z imenom "geslo":
// uporabnikovo geslo si zapomnimo za eno uro (3600 sekund)
setcookie("geslo", "janez123", time() + 3600);
$_COOKIE['geslo'] = "janez123";
Varnost: Uporabnik lahko s posebnimi orodji ali z lokalnim proxy strežnikom spreminja in bere piškotke. Zaradi tega moramo morebitne "občutljive" podatke v piškotkih kodirati, npr. s funkcijo md5() ali sha1(). Veljavnost prebranih piškotkov moramo vsakič znova preveriti — o tem smo v tem poglavju že govorili, v razdelku "Varnost" pri polju $_POST.
Polje $_REQUEST
To polje vsebuje vse spremenljivke iz polj $_COOKIE, $_GET in $_POST za lažji dostop.Zaradi preglednosti vaše programske kode sicer priporočamo, da posamezne spremenljivke vedno berete iz namenskih polj, v katera sodijo.
Polje $_SESSION
Seje so podobne piškotkom, le da se njihove vrednosti shranjujejo na strežniku.Uporabnik ob prvem obisku naše spletne strani v obliki piškotka dobi unikatno ID oznako seje (ang. session ID). Ob vsakem nadaljnem obisku naše spletne strani potem uporabnikov spletni brskalnik strežniku avtomatsko pošlje to ID oznako seje, na podlagi katere lahko uporabnik posledično dostopa do svojih "sejnih" spremenljivk na strežniku.
"Sejni" podatki so na voljo samo uporabniku z ustrezno ID oznako seje, na voljo pa so mu v vseh PHP skriptah na istem strežniku. Seja se zaključi in pobriše, ko uporabnik zapre okno spletnega brskalnika ali pa je dalj časa nedejaven.10
Uporabo seje v programskem jeziku PHP pričnemo s klicem funkcije session_start(), ki ga moramo izvesti še pred prvo uporabo funkcije echo za izpis in pred prvo uporabo HTML kode.
Ko je seja aktivna, lahko polju $_SESSION prirejamo nove vrednosti in jih tekom seje tudi preberemo. Če želimo izničiti posamezne sejne spremenljivke, uporabimo funkcijo unset().
Primer kode za uporabo "sejnih" spremenljivk:
$_SESSION['ime'] = "Janez"; // v sejo shranimo uporabnikovo ime
unset($_SESSION['poklic']); // iz seje pobrišemo (predhodno shranjen) uporabnikov poklic
S tem smo spoznali v PHP vgrajene spremenljivke, do katerih ima naš PHP program vedno dostop. Videli ste, da te vgrajene spremenljivke uporabljamo med drugim tudi za branje podatkov, ki nam jih preko spletnih obrazcev pošljejo naši uporabniki.
Kaj pa, če želimo prejete podatke shraniti za kasnejšo uporabo? O tem bomo govorili v naslednjem poglavju...