Sunteți pe pagina 1din 98

Ce este acest ghid?

Acesta ghid este un manual de initiere in programarea web folosind limbajul PHP. Scopul acestui ghid este
de a oferi informatii complete ce pot fi folosite de oricine doreste sa invete sa dezvolte aplicatii web
utilizand PHP. Manualul este in totalitate in limba romana, cuprinde notiuni legate de limbajul PHP,
explicatii, exemple practice si aplicatii si acopera intregul ciclu de invatare, de la nivelul elementar pana la
cel avansat. Asadar, acest ghid reprezinta o resursa completa in invatarea limbajului PHP. Parcurgand acest
curs veti putea dobandi notiunile necesare intelegerii si crearii scripturilor PHP de orice nivel de
complexitate.

Cui se adreseaza acest ghid?

Acest ghid se adreseaza persoanelor care doresc sa se initieze in programarea web. Este important de
mentionat ca in acest manual for fi tratate strict problemele legate de programare. Elementele de design
(HTML, CSS, etc), baze de date, sau alte tehnologii web vor fi tratate punctual, doar acolo unde explicarea
lor este necesara in intelegerea conceptelor de programare expuse. Asadar, acest ghid va fi util doar
persoanelor care sunt interesate in mod direct de programare si de dezvoltarea aplicatiilor web dinamice.

Cum este structurat ghidul?

Acest ghid imbraca forma unui tutorial web si cuprinde mai multe lectii grupate in functie de dificultate:

partea I cuprinde lectiile introductive in care se explica pe larg ce este si cum functioneaza PHP

partea a II-a cuprinde lectiile despre elementele de baza ale limbajului PHP (sintaxa, elemente de
limbaj, instructiuni uzuale, etc) precum si functionalitatile limbajului (lucrul cu formulare, cu data si
timpul, etc)

partea a III-a cuprinde lectiile despre facilitatile avansate ale limbajului PHP

partea a IV-a cuprinde aplicatii practice mai complexe, care constau intr-o suita de script-uri PHP.

partea a V-a cuprinde cateva pagini cu informatii aditionale, nu in mod necesar legate de
programarea in PHP, dar care pot fi utile oricarui dezvoltator web.Fiecare lectie contine, de regula, pe
langa notiunile prezentate, explicatii si exemple de cod-sursa.

Cu ce incep? Si mai pe urma?

Ideal, cu prima lectie. Daca nu ati mai avut contact cu programarea web, este foarte important sa intelegi
mecanismul de functionare, modul de deservire a paginilor si toate detaliile de care va veti lovi mereu ca
programator web. Nu "sariti" nici o lectie din partea I. Daca ati lucrat deja cu o alta tehnologie web si vreti
sa va familiarizati cu PHP, atunci puteti incepe cu partea a II-a.

Nu este nevoie sa parcurgeti intregul tutorial. Doar atat cat este nevoie sa intelegeti cum stau lucrurile si sa
va simtiti pregatiti pentru a incepe singuri un micro-proiect. Acesta este de fapt si scopul acestui site: sa va
ofere informatii de baza si mici exemple pentru ca voi sa incepeti singuri lucrul la un proiect pe parcursul
caruia sa dobanditi cat mai multe cunostinte.

De altfel, nu este nici suficient sa parcurgeti acest site in totalitate. Si nici o carte de specialitate. Pana nu
incepeti sa lucrati efectiv la ceva, sa scrieti cod PHP, nu veti reusi sa invatati cu adevarat.

1
Asadar, cititi explicatiile, cititi comentariile adaugate de alte persoane, incercati singuri toate exemplele, dar
nu zaboviti prea mult. Ganditi-va la un proiect bun pentru inceput, la care sa incepeti sa lucrati singuri: un
site de administrare link-uri, o librarie de melodii/poze, un guest-book. Ceva simplu pe care sa-l puteti si
termina. Nu va ganditi ca lucrurile astea au fost facute deja de alte persoane; este important sa fie facute si de
voi, ca sa puteti "prinde gustul" programarii in PHP.

Ce trebuie sa stiu ca sa invat PHP?

Pentru a putea parcurge cu usurinta acest ghid si pentru a intelege notiunile prezentate este necesar sa
detineti urmatoarele cunostinte:

cunostine minime de programare. Daca nu intelegeti termeni ca variabila, instructiune, compilare,


atunci probabil ar trebui sa cititi mai intai o carte pentru initiere in bazele programarii.

notiuni elementare de HTML (ce inseamna HTML, structura unui document HTML, cum este afisat
in browser fata de ce este scris in sursa, etichetele uzuale)

notiuni elementare despre internet (cum functioneaza) si serviciile de internet (www, transfer de
fisiere, etc)

Nu este nevoie sa aveti experienta cu dezvoltarea web sau sa stiti lucruri de detaliu despre tehnologiile web.
Tot ce este necesar sa stiti va fi explicat pe indelete in acest tutorial.

Ce imi trebuie pentru a lucra in PHP?

Pentru a putea incepe sa programati in limbajul PHP, aveti nevoie de urmatoarele:

un server web ce dispune de interpretorul PHP


Cel mai simplu este sa va instalati singuri un web-server, pe calculatorul personal. Detalii in lectia
"Instalare PHP"

de un editor text. Detalii pe pagina "Editoare PHP"

sa salvati toate scripturile pe care le creati in locatia speciala numita Document Root
Asta este doar un avertisment, pentru a va atrage atentia ca este important ca fisierele sa fie puse intr-
un anumit director de unde sa poata fi preluate de serverul web (mai multe detalii in lectia de
Instalare PHP)

de un browser web (Firefox, Internet Explorer, Chrome, Opera, Safari, etc)

de un calculator (laptop sau de birou)

Unde gasesc alte informatii, cursuri sau tutoriale PHP?

Alte resurse de PHP sunt disponibile la urmatoarele locatii:

Site-ul oficial PHP

Lectii de PHP

Oriunde...


2
Ce inseamna server?

Toata lumea stie, probabil, ce inseamna Internet: acea colectie uriasa de echipamente legate intre ele
in scopul schimbului de informatii sau al furnizarii de servicii. Daca ar fi sa simplificam mult ideea
de internet, am putea considera ca acesta este o retea de calculatoare in care fiecare nod (calculator)
gazduieste informatii sau servicii ce pot fi accesate de publicul larg. Aceste calculatoare din internet
poarta numele de servere.

In sens larg, un server este un dispozitiv (combinatie de hardware si software) care ofera servicii
si/sau informatii utilizatorilor (clientilor).

Odata cu notiunea de server apare si cea de arhitectura client-server, care se refera la un ansamblu
format dintr-un dispozitiv server (furnizor de informatii) si un dispozitiv (calculator) client, conectate
prin intermediul unei retele si care fac schimb de informatii. Cel mai comun exemplu al acestui
ansamblu este dat de functionalitatea de partajare a fisierelor in retea (File Sharing). Spre exemplu,
un calculator contine un folder partajat (share-uit) si un alt calculator copiaza folderul prin retea. In
aceasta situatie, calculatorul care ofera folderul are functia de server iar cel care preia folderul - pe
cea de client. Rolul de client/server nu este statornic in acest scenariu, oricare din cele doua
calculatoare putand oricand sa detine oricare din functii. Asadar notiunea de server se aplica in
momentul in care dispozitivul din retea (calculatorul) ofera informatii sau servicii.

Server web

Un tip particular de server, este server-ul web. Un server web este un sistem care gazduieste si ofera
pagini web prin intermediul unei retele. De cele mai multe ori, termenul de server web desemneaza
a aplicatie, un program care ruleaza pe calculatorul-server si care este responsabil cu primirea
cerintelor de la utilizatori si transferarea paginilor web catre ei.

Ce inseamna site?

Paginile stocate pe un calculator-server si oferite publicului larg sunt grupate sub denumirea generica
de site. Un site (denumit si website) este, asadar, o colectie de pagini web, interconectate, stocate pe
un server web.

Deservirea paginilor

In momentul in care un server web primeste o cerinta de la un utilizator pentru o pagina, se verifica
mai intai existenta acesteia. Daca pagina exista fizic pe server atunci este transmisa catre utilizator.
Paginile returnate de un server web sunt de obicei in format HTML. Navigatoarele web (browserele)
sunt capabile sa interpreteze codul HTML si sa afiseze informatiile intr-un mod usor de citit.

In imaginea de mai jos este reprezentata o comunicare tipica intre un server web si un client.

3

Deservirea unei pagini statice, fara interventia interpretorului
PHP

In lumea reala, paginile deservite de un server web sunt de cele mai multe ori modificate inainte de a
fi transmise catre clienti. Exista situatii cand paginile cerute nici nu exista fizic pe calculatorul server
si cu toate astea ele sunt construite si deservite la cerere.

Acest lucru este posibil gratie unor module sau aplicatii aditionale care functioneaza impreuna cu
aplicatia de server web. Unul din aceste module este PHP.

Pe scurt, ce este PHP? Ca idee generala, PHP reprezinta un limbaj de programare ce permite
modificarea paginilor web inainte ca acestea sa fie transmise de server catre browserele utilizatorilor.

PHP poate genera continut HTML pe baza unor fisiere existente sau pornind de la zero, poate sa
afiseze o imagine sau orice alt continut accesibil prin web, sau sa redirectioneze utilizatorul catre alte
pagini. In cadrul acestui proces, PHP poate consulta baze de date, fisiere externe sau alte resurse,
poate trimite email-uri sau executa comenzi ale sistemului de operare. Intrucat procesarea se
realizeaza la nivelul serverului web, inainte ca paginile web sa ajunga in browser, PHP este
considerat un limbaj de programare server-side.

Modul in care PHP genereaza continut pentru o pagina ce va fi afisata de browser este prin
instructiunile delimitate de etichetele <?php si ?>. Astfel, orice se afla intre aceste tag-uri va fi
considerat cod-sursa si va fi executat de interpretorul PHP si inlocuit cu rezultatul executiei. Ce este
in afara tag-urilor ramane neschimbat si este transmis catre browser. Spre exemplu, avem o pagina ca
mai jos.

Testeaza

<html>
<body>
Azi e <?php print date( 'd.m.Y' ); ?>
</body>
</html>
Rezultatul va fi o pagina HTML ce va contine cuvintele "Azi e" si rezultatul codului PHP (in cazul acesta - data
curenta). Codul HTML final, transmis de server in urma procesarii PHP este urmatorul:

4
<html>
<body>
Azi e 07.08.2013
</body>
</html>

Codul PHP nu trebuie sa fie neaparat intercalat in pagina HTML. Secventa de mai jos produce o
pagina similara celei de mai sus (in acest caz PHP produce o pagina HTML de la zero).

Testeaza

<?php
print '<html><body>';
print 'Azi e' . date( 'd.m.Y' );
print '</body></html>';
?>

Nota: interpretorul PHP nu este instalat implicit pe orice calculator. Pentru ca toate exemplele de pe
site sa functioneze, trebuie sa instalati (manual) un interpretor. Vedeti sectiunea "Instalare PHP"
pentru detalii.

Programare web

PHP este un limbaj de programare de tip interpretat. Asta inseamna ca fisierele ce contin cod-sursa
PHP sunt interpretate ca atare in momentul executiei, de catre PHP. Asadar, pentru executia unei
portiuni de cod PHP este folosit codul-sursa asa cum a fost scris el, si nu este transformat intr-o
forma intermediara (binara sau cod-masina) cum se intampla la Java sau C/C++. Acest lucru ofera
flexibilitate, intrucat orice modificare a fisierelor sursa va fi aplicata imediat la urmatoarea executie,
fara alti pasi intermediari. Exista si dezavantaje la acest mod de lucru, cum ar fi timp mai mare de
executie a codului, dar in anumite situatii avantajele pot cantari mai mult decat dezavantajele.
Datorita faptului ca limbajul este unul interpretat, PHP mai este numit si limbaj de scripting.

In sens mai larg, PHP este un limbaj de programare universal (sau general-purpose), oferind toate
facilitatile oricarui limbaj avansat. Codul scris in PHP poate face aproape aceleasi lucruri ca un cod
de C/C++ sau Java. Cu toate astea, PHP s-a impus in zona web, ca limbaj server-side, ce extinde
functionalitatea serverelor web. Din acest motiv programarea in PHP mai este denumita si
programare web sau programare web server-side.

In acest ghid ne vom axa pe programarea in PHP ca limbaj server-side. Desi notiunile prezentate nu
sunt legate de un mod de lucru anume si majoritatea exemplelor pot fi executate si din linie de
comanda, vom presupune ca PHP va fi folosit doar pentru programarea web, ca modul al unui server
web.

In cele de urmeaza va fi explicat mecanismul de functionare a interpretorului PHP si cum intervine el


in procesul de furnizare a paginilor web.

PHP si paginile dinamice 4

5
Interpretorul PHP actioneaza ca o componenta aditionala, o extensie a serverului web care este
invocata de ori cate ori o pagina PHP este accesata. Aceasta componenta proceseaza codul-sursa din
pagina si apoi transmite rezultatul inapoi la web-server, ajungand in final in browserele utilizatorilor.
Acest proces este prezentat in imaginea din dreapta de mai jos.

Deservirea unei pagini statice, fara interventia interpretorului


PHP

Deservirea unei pagini dinamice, modificata de PHP in momentul request-ului

Static si dinamic

Din imaginile de mai sus, se observa ca atunci cand nu exista un interpretor PHP, paginile sunt
transmise direct catre utilizatori asa cum sunt salvate pe disc, fara modificari. Pentru a actualiza
continutul acestora, este nevoie de interventie directa asupra lor si salvarea modificarilor pe server.
Aceste pagini sunt denumite "pagini statice".

6
Spre exemplu, presupunand ca avem o pagina statica ce afiseaza membrii unei comunitati, la fiecare
inscriere a unei noi persoane, pagina ar trebui modificata manual de catre cineva cu acces la serverul
web. Lucrurile se complica daca acea lista este personalizata, cu trimiteri catre alte informatii (cum ar
fi detalii de contact pentru fiecare, etc) sau cu un design intortocheat. Toate aceste probleme pot fi
rezolvate cu ajutorul PHP.

Folosind o secventa de cod PHP am putea prelua lista de membri dintr-o baza de date, eliminand
problema actualizarii - nu va mai fi nevoie sa se modifice pagina odata cu fiecare membru nou,
scriptul PHP va afisa in mod automat noile persoane adaugate in baza de date. Este rezolvata si
problema linkurilor personalizate, sau a designului - toate elementele specifice unei persoane pot fi
generate in mod automat.

Aceste pagini sunt, asadar, modificate de catre PHP la momentul accesarii lor de catre utilizatori. In
functie de parametrii primiti si de secventa de cod definita de programator, aceasi pagina poate avea
continut diferit. Aceasta proprietate este denumita dinamism, iar o astfel de pagina este considerata
pagina dinamica.

Cel mai simplu mod de a lucra cu PHP este sa fie instalat pe calculatorul personal. Este nevoie, asadar, ca
propriul calculator sa devina un server web mai intai. Acest lucru este posibil instaland o aplicatie capabila
sa accepte cerinte si sa transmita pagini web ca raspuns. O astfel de aplicatie este Apache HTTP Server. La
aceasta aplicatie, vom "atasa" apoi interpretorul PHP care va interveni in procesul de servire a paginilor web.

Nota: daca nu este clar modul de functionare a interpretorului PHP, consultati pagina Ce inseamna PHP?
care descrie cum intervine el in procesul de furnizare a paginilor web.

Instalarea interpretorului PHP pe GNU/Linux

Daca utilizati un sistem de operare GNU/Linux este posibil sa aveti deja instalate atat aplicatia de server web
(Apache HTTP Server, sau httpd) cat si modulul PHP, in functie de configurarea aleasa la instalarea
sistemului de operare. Daca acestea nu sunt deja instalate, le puteti adauga cu usurinta fie din linia de
comanda, fie din managerul de aplicatii al interfetei grafice folosite (unde apar de obicei in categoria
development). Intrucat exista diferente notabile de la o distributie la alta, nu voi detalia procesul de instalare
a PHP pe Linux.

Instalarea interpretorului PHP pe Windows

Pentru inceput, cea mai simpla modalitate de a avea totul pregatit pentru a lucra cu PHP sub Windows este
un pachet "All in one". Voi descrie pe scurt pasii necesari instalarii programului EasyPHP, o aplicatie care
include serverul web Apache, interpretorul PHP, sistemul de gestiune a bazelor de date MySQL si aplicatia
de administrare a bazelor de date phpMyAdmin.

1. Descarcati EasyPHP. Mergeti la http://www.easyphp.org/ -> Download EasyPHP (sau direct la


http://www.easyphp.org/save-easyphp-latest.php)

2. Instalati EasyPHP (pastrand configurarile implicite). Nota: trebuie sa dezinstalati Apache, PHP sau
MySQL de pe calculator (daca le aveti deja) inainte de a instala EasyPHP.

3. Porniti programul EasyPHP (de cele mai multe ori va porni automat)
Nota: la avertizarile de la firewall (cel de Windows XP/Vista/7 sau orice alta aplicatie de securitate)
trebuie sa se aleaga "Allow" sau "Unblock", altfel este posibil ca serverul web sa nu functioneze.

4. In fereastra de EasyPHP apasati F8 (sau click-dreapta pe iconita EasyPHP de langa ceas si alegeti
Explore). Se va deschide un folder, care reprezinta locatia de unde vor fi luate fisierele cand sunt

7
afisate in browser (de obicei C:\Program Files\EasyPHP-12.0\www). Aceasta locatie poarta numele
de Document Root si aici trebuie puse toate fisierele .php pe care le scrieti.

5. Salvati un fisier de test in locatia de mai sus. Dati-i un nume sugestiv, gen test.php. Editati fisierul
astfel incat sa contina urmatoarea secventa:

Testeaza

<?php print "Salut, ai reusit! Iata primul tau script PHP"; ?>

6. Intr-un browser mergeti la http://localhost/ (sau la http://127.0.0.1/). Va fi afisata o pagina cu linkuri


catre fisierele/folderelor din Document Root care pot fi accesate. Faceti click pe test.php. O alta
modalitate de a accesa un fisier este sa mergeti direct la http://localhost/[cale]/[nume].php, de
exemplu http://localhost/test.php.

7. Accesand http://localhost/test.php ar trebui sa fie afisata o pagina alba cu mesajul de mai sus.

Retineti! Toate fisierele PHP pe care le scrieti (inclusiv cele de test preluate de pe acest site) *trebuie*
salvate in folderul Document Root (locatia implicita este C:\Program Files\EasyPHP-12.0\www). Web-
server-ul local instalat de EasyPHP va cauta fisierele doar in aceasta locatie. Daca fisierele sunt salvate in
alta parte ele nu vor fi disponibile.

Note:

Pe unele sisteme Windows, EasyPHP configureaza diferit serverul web local, astfel ca scripturile sunt
accesibile la http://localhost:8888/, caz in care aceasta adresa trebuie folosita. In orice caz, indiferent
de configurare, serverul local se poate accesa din meniul EasyPHP (prin click-dreapta pe iconita
EasyPHP de langa ceas si alegand optiunea Local Web).

Pe majoritatea sistemelor Windows, fisierele PHP se salveaza cu extensie dubla (fisier.php.txt) atunci
cand este folosit Notepad. Acest lucru este gresit iar fisierele trebuie redenumite astfel incat sa aiba
doar extensia .php. Pentru a verifica extensia fisierelor, debifati optiunea Hide extensions for
known file types din Folder Options (in Control Panel).

De ce imi trebuie un server web?

Instaland pachetul EasyPHP, calculatorul personal devine un server web (local, ce-i drept - accesibil doar de
catre tine). Practic PC-ul se comporta ca un site ce are adresa http://localhost/ (sau http://127.0.0.1/). Este
foarte important ca fisierele PHP sa fie accesate prin intermediul serverului web, deoarece acesta recunoaste
scripturile PHP si invoca automat interpretorul PHP. Fara aceasta intermediere oferita de web-server,
scripturile PHP nu ar fi procesate ci trimise asa cum sunt la browser.

De exemplu, avem un fisier care contine doar urmatorul cod: (atentie la semnul ! in afara tagurilor)

Testeaza

<?php print "Salut"; ?> !

Sa presupunem ca fisierul se numeste salut.php


- Daca il accesam in browser folosind adresa "http://localhost/salut.php" (prin intermediul serverului web
local) atunci *interpretorul PHP este invocat*, scriptul este executat iar rezultatul procesarii afisat de
browser va fi "Salut!".
- Daca accesam fisierul direct de pe disc, scriind in browser calea lui "file:///C:/Program Files/EasyPHP-
12.0/www/salut.php" se va afisa (in cel mai fericit caz) doar "!". Asta pentru ca interpretorul PHP *nu este
8
invocat*, iar fisierul este transmis ca atare, cu secventa de cod PHP ne-interpretata (accesati view-source din
browser pentru a verifica).

Testarea online a codului-sursa PHP

In cazul in care nu reusiti (sau nu doriti) sa instalati PHP pe calculatorul personal, puteti testa exemplele si
secventele de cod-sursa direct de pe site.

In dreptul fiecarei portiuni de cod-sursa ce poate fi testat exista un buton numit "Testeaza", in coltul din
dreapta-sus. Apasand acel buton se va deschide o noua fereastra ce permite vizualizarea secventei de cod si a
rezultatului executiei. Din acea fereastra se poate modifica secventa de cod si se poate executa in noua
varianta. Totul se face online, cu ajutorul unui instrument pus la dispozitie de site-ul www.ideone.com, fara a
fi nevoie sa aveti PHP instalat local.

Aceasta facilitate este utila pentru verificari imediate si pentru a testa rapid exemplele de pe site. Este
recomandat totusi sa instalati un server web si interpretorul PHP pe calculatorul personal, intrucat veti avea
nevoie de ele pentru aplicatiile mai complexe.

Taguri PHP, instructiuni, punct si virgula

Codul PHP trebuie inclus in fisiere cu extensia .php ce vor fi deservite utilizatorilor finali si trebuie delimitat
de restul continutului prin tagul de inceput <?php si tagul de sfarsit ?>. Practic tot ce se afla in interiorul
acestor etichete va fi interpretat ca fiind cod-sursa PHP (cod ce va fi executat de interpretorul PHP). Textul
din afara celor 2 taguri este lasat neschimbat, fiind ulterior interpretat de browser. Se pot folosi si alte
etichete in functie de configuratia serverului web, dar acestea nu sunt recomandate.

Testeaza

<?php
/* forma recomandata */
?>

<script language="php">
/* forma disponibila oricand, putin folosita */
</script>

<?
/* taguri scurte, acceptarea lor de catre web-server depinde de configurare */
?>

<%
/* taguri in stilul asp, acceptarea lor de catre web-server depinde de configurare */
%>
Codul PHP este format din instructiuni - comenzi date catre interpretor, in urma carora se executa ceva. Asa
cum s-a mai spus, PHP este folosit in principal pentru a genera cod HTML, asa ca de cele mai multe ori
instructiunile folosite sunt cele de afisare. In aplicatii mai complexe se pot insa folosi si instructiuni de
conectare la bazele de date, de citire/scriere/manipulare fisiere, intructiuni de trimitere email-uri si altele.
Instructiunile se pot grupa in blocuri delimitate de acolade { }. Aceste blocuri, numite si "instructiuni
complexe" se comporta ca si cum ar fi o singura instructiune (vezi mai jos exemple de blocuri).

Toate instructiunile (in afara de blocuri) trebuie sa fie terminate cu punct si virgula ( ; ). Lipsa acestuia
genereaza o eroare.

Afisarea textului in PHP

9
In multe din scripturile scrise de incepatori (si nu numai) continutul rezultat in urma executiei este un text
(de obicei in format HTML). Pentru a obtine acest text, secventele de cod trebuie sa contina instructiuni
explicite care sa "spuna" intrepretorului ce anume trebuie afisat.

Instructiunile de afisare sunt print, echo si printf. Primele doua sunt echivalente si fac acelasi lucru
(exista unele diferente de forma, vezi exemplul de mai jos, dar poate fi folosita oricare dintre ele); printf
este folosita mai rar datorita sintaxei oarecum greoaie.

Testeaza
<?php
# cele 2 instructiuni de mai jos sunt echivalente
print "Text";
echo "Text";

# o singura instructiune echo poate primi mai multi parametri, separati prin virgula
echo "<br />", "Afisez", " un text din ", 4, " bucati";

# o singura intstructiune print poate primi doar unul


print "<br />";
print "Afisez";
print " un text din ";
print 4;
print " bucati";

# printf este folosita pentru a formata continutul, la fel ca in C/C++


printf( "<br />Am %4.2f lei", 102.123456 ); // afiseaza Am 102.12 lei
?>

Ce afiseaza PHP?

Rezultatul unui script PHP este de cele mai multe ori un text simplu in format HTML. Cu alte cuvinte, in
majoritatea cazurilor PHP returneaza o pagina HTML ce va fi afisata in browser. La inceput, acest lucru
poate genera confuzii, intrucat sursa HTML este diferita de ceea ce se afiseaza efectiv in browser.

Spre exemplu, fie urmatoarea secventa de cod:

Testeaza

<?php
print "Salut";
print "Acesta este un script simplu";
?>

Probabil v-ati astepta ca rezultatul sa fie un text afisat pe 2 linii. Salvand aceasta secventa intr-un fisier PHP
si accesandu-l prin intermediul unui web-server, veti observa ca rezultatul este urmatorul:
SalutAcesta este un script simplu
Desi este confuz, rezultatul este corect. Codul PHP afiseaza doar caracterele care i-au fost indicate.
Sfarsitul de linie reprezinta un caracter separat, ne-printabil, dar care controleaza cum apare textul pe ecran.
In cazul nostru, nu s-a transmis acest caracter (numit si new-line) si prin urmare PHP nu l-a afisat.

Sa rescriem exemplul de mai sus pentru a se afisa si caracterul "sfarsit de linie"

Testeaza

<?php
print "Salut";

10
print "\n"; # se afiseaza caracterul "new-line" care determina trecerea la un rand nou
# randul nou va fi afisat in textul trimis catre browser

print "Acesta este un script simplu";


?>

Verificand iar in browser veti constata ca nu s-a schimbat nimic. La prima vedere. In realitate rezultatul este
afisat pe 2 linii, in textul trimis de PHP catre browser. Intrucat pagina este interpretata ca fiind HTML,
browserul ignora caracterele new-line. Pentru verificare vizualizati sursa paginii (meniul View din browser
-> view source).

Pentru a ajunge la rezultatul dorit (acela de a afisa un text pe 2 linii in pagina) trebuie folosita urmatoarea
secventa:

Testeaza

<?php
print "Salut";
print "\n"; # se afiseaza caracterul "new-line" care determina trecerea la un rand nou
# randul nou va fi afisat in textul primit de browser (vizibil in sursa HTML)

print "<br>"; # se afiseaza tagul BR ce va fi interpretat de browser ca 'linie noua'


# linia noua va fi afisata in pagina finala HTML dupa ce este interpretata de
# browser si nu are nici o legatura cu \n

print "Acesta este un script simplu";


?>

Sursa paginii arata in felul urmator:


Salut
<br>Acesta este un script simplu
In browser tagul BR este interpretat ca sfarsit de linie (line break). Caracterul "new-line" afisat de noi (in
print "\n") este ignorat oricum in HTML. Rezutatul, asa cum se vede in fereastra browser-ului:
Salut
Acesta este un script simplu

Nota: Este foarte important sa se inteleaga diferenta dintre ceea ce se returneaza in urma executiei unui
script PHP si ceea ce se afiseaza propriu-zis in browser. Pe scurt, PHP printeaza cod HTML care este afisat
diferit de browsere.

De asemenea, trebuie inteles faptul ca functia print nu afiseaza textul pe mai multe linii daca nu se
specifica acest lucru in mod express. Spre exemplu fie urmatoare secventa de cod:

Testeaza

<?php
print "1";
print "2";
print "3";
?>
Rezultatul va fi
123
S-a afisat doar ce s-a indicat, 3 caractere, pe o singura linie, fara spatii.

Un alt lucru important de retinut este faptul ca odata printat, un text nu mai poate fi "sters". Nu exista "undo"
pentru un print. Se poate captura intregul continut ce se transmite la finalul executiei, dar nu se poate altera

11
textul afisat de o instructiune print anume. Intelegand aceste aspecte va va fi mai usor in lucrul cu PHP si in
modul in care verificati rezultatele scripturilor voastre.

Siruri de caractere

In majoritatea scripturilor PHP se lucreaza cu bucati de text denumite siruri de caractere sau string-
uri. Sirurile de caractere reprezinta expresii (entitati ce au/returneaza o valoare) si pot fi folosite, la afisare,
in atribuiri, la verificari, etc.

In limbajul PHP, sirurile de caractere pot fi delimitate de ghilimele duble, ghilimele simple sau printr-o
notatie speciala folosind operatorul <<< (numit heredoc).

Testeaza

<?php
print "Salut, straine! "; // sir simplu, delimitat de ghilimele duble
print 'Salut din nou! '; // sir simplu, delimitat de apostrof

// sir delimitat prin notatia speciala heredoc


print <<<SIR
Salut iar!
SIR;
?>

Nota: in acest exemplu nu este nici o diferenta intre modul de definire a sirurilor - toate cele 3 stringuri
afisate sunt echivalente, indiferent ca au fost delimitate prin ghilimele, apostrof sau operatorul heredoc. Cu
toate astea, PHP trateaza in mod diferit aceste moduri de delimitare. Mai multe explicatii si exemple sunt
prezentate in pagina Operatii cu siruri.

Comentarii in PHP

Comentariile sunt portiuni de cod care nu se executa. Sunt folosite de programatori de regula pentru a da
diverse explicatii despre logica aplicatiei, variabile si altele. Comentariile nu afecteaza executia unui script si
pot fi sterse din cod fara nici un efect.

Testeaza

<?php
// acesta este un comentariu. intreaga linie nu va fi luata in considerare (doar o
linie)
// print "hello";
// linia de mai sus nu se executa

# la fel ca mai sus


# print "hello";
# nu se executa

/* comentariu cu delimitator de inceput si sfarsit


se poate intinde pe oricate linii; se termina la
intalnirea marcajului de sfarit */

print /* partea asta e ignorata */ "Salut!";

/* afiseaza
Salut!
*/
?>
Nota: comentariile /* */ nu pot fi imbricate (inserate unele in altele). Exemplul urmator nu este un cod valid.
<?php
12
// exemplu gresit de comentariu PHP
/* comentariu /* altul */ inapoi la primul */
?>

Este un lucru foarte util sa folositi comentarii in cod pentru a explica modul de rezolvare a problemei
abordate, sau pentru a da detalii despre operatiile efectuate. Acestea va vor ajuta mai tarziu daca veti vrea sa
modificati codul scris, sau vor oferi altor persoane informatii (valoroase) despre cum ati gandit codul
respectiv.

Variabile in PHP

Ce sunt variabilele?

Variabilele sunt elemente ce au o anumita valoare la un moment dat. Valoare unei variabile se poate schimba
de-a lungul executiei unui script.

Lucrul cu variabile in PHP este foarte usor. Nu trebuie specificat un tip pentru ele (de genul "variabila text",
"variabila numerica") ci acesta este determinat in mod automat.

Variabilele sunt diferentiate de celelalte elemente ale limbajului prin caracterul $. Astfel, o variabila are
forma $nume. Numele variabilei poate fi orice identificator valid (un text ce contine doar litere, cifre si
underscore, fara spatii sau alte caractere; un identificator nu poate incepe cu o cifra).

Declararea variabilelor

In PHP declararea variabilelor se realizeaza in acelasi timp cu initializarea lor (cu atribuirea unei valori de
inceput). Atribuirea unei valori se realizeaza cu ajutorul instructiunii de atribuire ce are forma <nume
variabila> = <valoare>;

Testeaza

// variabile numerice
$variabila = 1;
$numar = 0;

// variabile text (stringuri)


$text = "Salut";
$text2 = 'Ce faci?';

// variabile logice (boolean)


$stiuPHP = true;
$uitRepede = false;

// vector
$vectorGol = array();
$vectorS = array( 10,11,12,13 ); // vector simplu

// vector asociativ
$vector = array(
'luni' => 'Monday',
'marti' => 'Tuesday',
'miercuri' => 'Wednesday'
);

// definirea unei noi componente a unui vector asociativ


$vector[ 'joi' ] = 'Thursday';

// vector simplu definit ca asociativ, echivalentul lui $vectorS


$vectorS2 = array(

13
0 => 10,
1 => 11,
2 => 12,
3 => 13
);

Nota: un vector asociativ se diferentiaza de unul normal prin faptul ca are chei alfa-numerice (cuvinte).

Atentie: PHP face distinctie intre literele mari si mici. Astfel, cele 3 variabile de mai jos sunt TOTAL
diferite: Testeaza

$variabila = "negru";
$vaRiabilA = "alb";
$Variabila = 1;

Atribuirea de valori

Se realizeaza la fel ca si declararea prin intermediul instructiunii de atribuire.

Testeaza

# atribuirea unei valori anume


$variabila = 2;

# copierea valorii de la o alta variabila


$text = $variabila;

# copierea valorii functioneaza si in cazul vectorilor


# in urma copierii cei 2 vectori vor fi identici
$vectorS = $vectorS2; # toate componentele lui $vectorS2 sunt copiate in $vectorS

# in cazul vectorilor se pot atribui valori separat fiecarei componente


$vectorS[ 0 ] = 100;
$vectorS[ 3 ] = 10;

$vector[ 'luni' ] = 'Lundi';


$vector[ 'joi' ] = 'Jeudi';

Stergerea variabilelor

De obicei nu e nevoie ca variabilele sa fie sterse dupa ce au fost folosite. Totusi, lucrul aceste se poate face in
urmatoarele moduri:

Testeaza

unset( $variabila );
$variabila = null;

Afisarea variabilelor

Afisarea se realizeaza utilizand oricare din instructiunile de afisare:

Testeaza

$variabila = "Text";
$randNou = "<br>";

print $variabila;
14
print $randNou;

// echivalent cu cele doua instructiuni print


echo $variabila, $randNou;

In anumite situatii, in special atunci cand testati sau depanati codul PHP, puteti folosi doua instructiuni de
afisare detaliata a continutului variabilelor: instructiunea print_r, utila in cazul vectorilor, pentru ca
afiseaza componentele variabilei specificate, si instructiunea var_dump, ce poate fi folosita pentru orice tip
de variabila. Aceasta din urma specifica tipul de data continut si lungimea sa.

Testeaza

$var1 = 123;

print "\n print_r: "; print_r($var1); // afiseaza 123


print "\n var_dump: "; var_dump($var1); // afiseaza int(123)

$var2 = "test";

print "\n print_r: "; print_r($var2); // afiseaza test


print "\n var_dump: "; var_dump($var2); // afiseaza string(4) "test"

$var3 = array('aaa', 'bbb', 'ccc');

print "\n print_r: "; print_r($var3); // afiseaza Array ( ... )


print "\n var_dump: "; var_dump($var3); // afiseaza array(3) { ... }

Serializarea si deserializarea variabilelor

Serializarea unei variabile presupune transpunerea continutului ei intr-o forma ce poate fi stocata cu usurinta
ca text simplu. Deserializarea este operatia inversa, prin care o variabila este recreata pe baza unui text
provenit de la o serializare. Astfel, o variabila definita in PHP poate fi serializata si apoi scrisa intr-un fisier
text sau salvata intr-o baza de date, avand posibilitatea de a o restaura oricand.

Serializarea se face folosind functia serialize care primeste ca parametru o variabila si returneaza un text.
Operatia inversa se realiza cu ajutorul functiei unserialize.

Testeaza

$variabila = array("componenta1", 2, 3);


$ser = serialize($variabila);

echo $ser, "\n"; // afiseaza a:3:{i:0;s:11:"componenta1";i:1;i:2;i:2;i:3;}

$des = unserialize($ser);
print_r($des); // afiseaza vectorul initial

Serializarea este utila atunci cand o variabila trebuie sa fie stocata sau transmisa ca text catre un alt proces.
Este necesar insa ca deserializarea sa fie facuta tot din PHP pentru a asigura recrearea corecta a continutului
initial.

O alternativa la serializare si deserializare o constituie transformarea continutului variabilei intr-un format


text standard, cum este JSON. Avantajul este ca reconstituirea continutului poate fi facuta de orice proces, nu
doar de un script PHP.

15
Ponturi de PHP

Diferenta dintre ghilimele simple si duble la declararea variabilelor

Ghilimelele duble permite compilatorului sa "citeasca" variabilele ce apar in interiorul textului.

Testeaza

$today = date( 'd-m-Y' );


$text1 = "Azi e $today";

print $text1; // Azi e 17-07-2008

Astfel, textul cuprins intre ghilimele duble este procesat inainte de afisare: variabilele sunt cautate iar
valoarea lor este afisata in locul numelui.
In cazul apostrofului, textul este afisat neschimbat, iar variabilele nu sunt interpretate.

Testeaza

$today = date( 'd-m-Y' );


$text2 = 'Azi e $today';

print $text2; // Azi e $today

Verificarea daca o variabila e definita

Se pot folosi 2 functii: isset si empty .

Testeaza

// definim o variabila, cealalta definire nu se executa

$var = 0;
// $var2 = 1;

var_dump( isset($var) ); // bool(true)


var_dump( isset($var2) ); // bool(false)

var_dump( empty($var1) ); // bool(true), pentru ca 0 este considerat nul


var_dump( empty($var2) ); // bool(true)
Atentie, isset verifica daca variabila a fost definita, pe cand empty verifica daca a fost definita si daca are o
valoare considerata vida. O variabila este vida daca are urmatoarele valori:

"" (text de lungime 0)

0 (cifra 0)

"0" (textul "0")

null

false

array() (vector gol)

16
Nota: pentru valorile de mai sus, empty returneaza true

Operatorul {}

Pot exista situatii cand anumite variabile trebuie procesate mai inainte decat altele, sau mai inainte de
procesarea intregii instructiuni. De exemplu:

Testeaza

$salut = array(
'dimineata' => 'Buna dimineata',
'pranz' => 'Buna ziua',
'seara' => 'Noapte buna'
);

print "$salut[ 'pranz' ], vizitatorule"; // eroare

Modul in care am scris variabila ($salut[ 'pranz' ]) este corect. Doar ca PHP-ul nu "stie" sa vada variabila
noastra ca pe un element din vector, sa-i ia valoarea si apoi sa afiseze tot textul. Pentru a rezolva aceasta
problema folosim acoladele:

print "{$salut[ 'pranz' ]}, vizitatorule"; // "Buna ziua, vizitatorule"

In acest caz spunem compilatorului sa interpreteze mai intai ce este intre acolade (elementul
$salut[ 'pranz' ] din vector) si apoi sa afiseze tot textul.
Ori de cate ori e nevoie ca o variabila sa fie interpretata cu prioritate, ea trebuie pusa intre acolade.

Dubla indirectare ($$nume)

Limbajul PHP permite referirea la numele unei variabile printr-o alta variabila.

Testeaza

$masina = "Chevrolet";
$avion = "Boeing";
$tren = "TGV";

$obiect = 'masina';
print $$obiect; // Chevrolet

$obiect = 'tren';
print $$obiect; // TGV
Pentru a intelege ce se intampla, trebuie mentionat ca ultima linie poate fi scrisa astfel:
print ${$obiect};
In virtutea explicatiei de mai sus a operatorului {}, putem vedea usor ca PHP mai intai extrage valoarea
variabilei $obiect ( care este: "masina" ) si apoi afiseaza variabila $masina (care are valoarea "Chevrolet").

Constante

Constantele sunt entitati care nu isi schimba valoarea pe parcursul executiei. Sunt utile pentru a recunoaste
usor valorile folosite in cod. De exemplu, e mai usor de inteles urmatorul cod, cand se foloseste o constanta
decat daca s-ar folosi cifra 5

Testeaza

define( 'ZILE_LUCRATOARE', 5);


$zile = array( 'luni', 'marti', 'miercuri', 'joi', 'vineri', 'sambata', 'duminica' );
17
print 'Zilele lucratoare sunt: ';
for( $i = 0; $i < ZILE_LUCRATOARE; $i++ ) {
print $zile[ $i ] . ' ';
}

Asadar constantele de definesc folosind define:

Testeaza

define( 'NUME', "Flo" );


define( 'VARSTA', 10 );
define( "ADEVARAT", true );

Este recomandat ca numele constantelor sa fie scris cu majuscule (pentru a fi mai usor identificate) desi nu
este obligatoriu. Atunci cand se folosesc, se specifica doar numele, fara ghilimele sau $:

Testeaza

print "Ma numesc " . NUME;


print " si am " . VARSTA . " ani";

Pentru a verifica daca o constanta este definita, se foloseste functia defined

Testeaza
if( defined( 'NUME' ) ) {
print "Ma numesc " . NUME;
}

if ( !defined( 'VARSTA2' ) ) {
define( 'VARSTA2' , 20 );
}
print " Am " . VARSTA . " ani";

Expresii in PHP

Expresiile sunt constructii ale limbajului PHP care au o valoare. O expresie poate fi un sir de caractere, un
numar, o variabila sau chiar o constructie mai complexa (cum ar fi un apel de functie). Ideea de baza este ca
orice poate fi evaluat la o valoare este considerat a fi expresie.

Limbajul PHP este construit in jurul expresiilor, iar acest concept, desi ignorat de multi programatori, este
foarte important in intelegerea corecta a modului in care interpretorul PHP evalueaza si executa secventele
de cod.

Cele mai simple expresii in PHP sunt, asa cum am amintit, numerele (denumite si number literals) sau
sirurile de caractere (string literals). Acestea au o valoare ce poate fi determinata in orice moment, iar
aceasta valoare poate fi folosita in operatii (cel mai adesea, la atribuiri). In urma unei atribuiri, o variabila va
prelua valoarea expresiei atribuite, devenind ea insasi o expresie. Asadar, avand o instructiune de atribuire de
forma

$a = 1;
1 este o expresie (number literal) si $a este la randul ei o expresie (variabila).

Mai mult decat atat, in PHP instructiunea de atribuire este in sine o expresie, in sensul ca returneaza o
valoare; astfel $a = 1 va returna valoarea expresiei atribuite (1, in acest exemplu). In acest context, putem
scrie

18
// atribuie lui $a valoarea 1, apoi printeaza rezultatul expresiei $a = 1, adica 1
print ($a = 1);

Sau chiar

// atribuie lui $a valoarea 1, apoi atribuie lui $b rezultatul expresiei, adica 1


$b = ($a = 1);

De mentionat este ca expresiile sunt evaluate de la dreapta la stanga. In exemplul de mai sus, mai intai se
executa si evalueaza expresia $a = 1 iar apoi se executa atribuirea $b = ... in care operandul din dreapta
este inlocuit cu valoarea efectiva obtinuta.

Nu doar atribuirile sunt expresii. Apelurile de functii (predefinite sau definite de programator) sunt
considerate expresii si ele, intrucat returneaza o valoare. De asemenea, asocierea mai multor expresii,
folosind operatori, genereaza o noua expresie.

Un alt lucru important referitor la expresii este ca valoarea lor se poate modifica in functie de context. Mai
exact, se modifica tipul de date de care apartine expresia (din string in numeric, din numeric in logic, etc).
Astfel, daca intr-o operatie este necesar un anumit tip de date, iar expresia folosita are alt tip, atunci valoarea
este convertita in mod automat. Asta poate fi un lucru bun, sau poate introduce erori in cod; de aceea este
important sa se acorde o atentie sporita valorilor expresiilor, in special atunci cand se combina tipuri de date
diferite.

Expresiile sunt fundamentul limbajului PHP si aproape orice este o expresie. Ele apar peste tot in codul sursa
si pot fi folosite in atribuiri, ca parametrii ai functiilor sau pentru specificarea conditiilor din structurile de
control. In cele ce urmeaza vor fi prezentati operatorii limbajului PHP care pot fi aplicati unor expresii si
care genereaza (prin compunere) noi expresii.

Operatori in PHP

Operatorii sunt elemente de limbaj ce se aplica expresiilor si dau nastere unor noi expresii. Exista mai multe
tipuri de operatori, cu sintaxa si roluri diferite. De retinut este ca toti operatorii vor determina conversia
expresiilor componente atunci cand acestea au tipuri diferite de date. Regula de conversie difera de la un tip
de date la altul si de la un operator la altul.

Mai jos sunt detaliati operatorii disponibili in PHP.

Operatori de comparare

Operatorii de comparare sunt folositi de cele mai multe ori in cadrul instructiunii if pentru a exprima
conditia ce trebuie verificata.

$a == $b // egal
$a === $b // identic (aceeasi valoare si acelasi tip)

$a != $b // diferit
$a <> $b // diferit
$a !== $b // ne-identic

$a < $b // strict mai mic


$a <= $b // mai mic sau egal

$a > $b // strict mai mare


$a >= $b // mai mare sau egal
Exemple:

19
Testeaza

<?php
#initializari
$a = 4; # initializam $a cu numarul 4
$b = "4"; # initializam $b cu string-ul "4"

# operatorul de egalitate
if( $a == 4 ) print "\$a este 4"; # va afisa "$a este 4"
else print "\$a nu este 4";

# operatorul de egalitate
if( $a == $b ) print "Sunt egale"; # va afisa "Sunt egale"
else print "Nu sunt egale";

# operatorul de echivalenta
if( $a === $b ) print "Sunt identice"; # va afisa "Nu sunt identice"
else print "Nu sunt identice";
# Nota: deoarece $a este numar iar $b string, ele nu sunt identice

# operatorul de comparare
if( $a > 4 ) print "\$a este mai mare decat 4";
?>

Atentie! Daca se compara un string (text) cu un numar, stringul este convertit la un numar. Exemplu:
"text" == 0 // echivalent 0 == 0, evalueaza la true

Daca se compara 2 stringuri ce contin numere, acestea sunt mai intai convertite la numerele pe care le
reprezinta si apoi are loc comparatia. Astfel, 2 texte care sunt diferite ar putea fi considerate egale. Exemplu:

"1" == "01" // echivalent 1 == 1, evalueaza la true


"1" == "1e0" // echivalent 1 == 1, evalueaza la true
Nota: "01" si "1e0" sunt notatii matematice diferite pentru numarul 1.

Diferenta intre operatorii == si =


Operatorul == este diferit de operatorul de atribuire = si nu trebuie confundati. Dublu-egal (==) este folosit
pentru comparare iar egal simplu (=) - pentru atribuirea de valori unei variabile.

Testeaza

# $a = 5 este o atribuire.
var_dump( $a = 5 ); // 5
# instructiunea print afiseaza rezultatul atribuirii (rezultatul unei atribuiri este
# intotdeauna egal cu valoarea atribuita)

# $a == 1 este o verificare. Instructiunea afiseaza rezultatul verificarii.


var_dump( $a == 1 ); // false

In timp ce atribuirile se pot folosi atat de sine statator ($a = 1;), cat si ca expresii in cadrul instructiunilor
(print $a = 1; return $a = 1;) operatorii == sau === sunt folositi doar in cadrul instructiunilor.

Testeaza

# corect
$a = 10; # atribuire de sine statatoare
var_dump( $a = 10 ); # atribuire + afisarea rezultatului atribuirii

# incorect - nu genereaza erori dar aceasta constructie este inutila.


$a == 1; # nu se face nimic cu rezultatul comparatiei

# corect
20
var_dump( $a == 1 ); # se afiseaza rezultatul comparatiei
var_dump( $a === '1' ); # se afiseaza rezultatul comparatiei exacte
if( $a == 1 ) echo 'egal'; # se face o verificare

Operatorul ternar

PHP ofera un operator care are 3 termeni si a carui evaluare returneaza o valoare. Sintaxa lui este
urmatoarea:

(conditie ? adevarat : fals )

De remarcat ca adevarat, fals si conditie nu sunt instructiuni ci expresii (variabile, constante, stringuri, etc)
iar operatorul returneaza o valoare si nu o variabila.

print ( 1 == 2 ? 'egal' : 'ne-egal' ); // afiseaza ne-egal


$a = ( 1 == 2 ? 'egal' : 'ne-egal' ); // $a va avea valoarea ne-egal

Operatori de incrementare/decrementare

Incrementare inseamna cresterea valorii, de obicei cu o unitate, iar decrementarea este operatia inversa. PHP
ofera (ca si C/C++) posibilitatea ca incrementarea/decrementarea sa se faca printr-un operator, fara sa fie
nevoie de o instructiune separata. Spre exemplu:

$a = 1; // initializare

// pentru a-l creste pe $a cu o unitate, normal am scrie:


$a = $a + 1;

// folosind operatorul de incrementare scriem:


$a++;
// sau
++$a;

// pentru a afisa noua valoare, putem aplica operatorul direct din instructiunea print:
print ++$a;

Dupa cum se poate observa, putem scrie $a++ si ++$a. Diferenta este ca atunci cand ++ apare inainte de
variabila, PHP face mai intai incrementarea si apoi returneaza noua valoare. Cand ++ apare dupa, se
returneaza valoarea actuala (ne-incrementata) si apoi se creste cu o unitate. Exemplu:

$a = 1;
print $a++; // afiseaza 1 - mai intai se afiseaza valoarea curenta, dupa care $a devine
2;
print $a; // afiseaza 2 - $a are valoarea 2 dupa incrementare;

$a = 1
print ++$a; // afiseaza 2 - mai intai $a creste cu o unitate, apoi este afisata noua
valoare
print $a; // afiseaza 2 - $a are valoarea 2;

Nota: aceleasi observatii (legate de pozitie) se aplica si pentru operatorul de decrementare.

$a = 2;
print $a--; // afiseaza 2 - mai intai se afiseaza valoarea curenta, dupa care $a devine
1;
print $a; // afiseaza 1 - $a are valoarea 1 dupa decrementare;

$a = 2
print --$a; // afiseaza 1 - mai intai $a scade cu o unitate, apoi este afisata noua
valoare
21
print $a; // afiseaza 1 - $a are valoarea 1;

Operatori de atribuire
$a = 1; // atribuire simpla

$a += 4; // echivalent cu $a = $a + 4; $a are valoarea 5 acum


$a -= 1; // echivalent cu $a = $a - 1;
$a *= 2; // echivalent cu $a = $a * 2;
$a /= 3; // echivalent cu $a = $a / 3;
$a %= 2; // echivalent cu $a = $a % 2; restul impartirii lui $a la 2

$a = &$b; /* $a este o referinta la $b, adica ambele variabile fac referire


la aceeasi entitate; daca $a se schimba, se va schimba si $b.
Altfel spus, $a este un alias pentru $b */

$s = "Salut"; // atribuire simpla


$s .= " straine!"; // echivalent $s = $s . " straine!";

Operatori pentru siruri de caractere

In aceasta categorie sunt inclusi 2 operatori ".=" (operator de atribuire prin concatenare - vezi mai sus) si "."
Punctul (.) este operatorul de concatenare (legare) stringuri.

print "Text1" . " legat de " . "Text2"; // afiseaza Text1 legat de Text2

$a = "Eu am";
print $a . " mere"; // afiseaza Eu am mere;

Operatori de control al erorilor @

Operatorul @ este folosit pentru a suprima erorile sau avertismentele produse de PHP.

// $nedefinit = 1; - nu se executa, variabila nu e definita


print $nedefinit; // Notice: Undefined variable: nedefinit in file.php on line 120
@print $nedefinit; // nu va genera nici un avertisment / notificare

include( "inexistent.php" ); // Warning: include(nedefinit) failed to open...


@include( "inexistent.php" ); // nu afiseaza nici un avertisment

Operatorul de executie ` `

Operatorul de executie permite rularea unor aplicatii sau comenzi ale sistemului de operare direct din PHP.
Rezultatul executiei este capturat de script si poate fi prelucrat sau afisat. Operatorul ` ` este echivalent cu
functia shell_exec.

# in ambele situatii de mai jos este afisat continutul directrului curent


$output = `ls -al`;
echo "<pre>$output</pre>";

$output = shell_exec('ls -al');


echo "<pre>$output</pre>";

Alti operatori

PHP mai dispune de urmatoarele tipuri de operatori:

Operatori aritmetici: +, -, *, etc

22
Operatori pe biti: &, |, ^, ~, <<, >>

Operatori logici: and, or, xor, &&, ||

Operatori de tip: instanceof

Operatori pentru vectori: asemanatori celor de comparare, doar ca se aplica vectorilor, operatorul
de uniune (+) leaga doi sau mai multi vectori

Siruri de caractere

Sirurile de caractere sunt bucati de text, bine delimitate, folosite in codul-sursa pentru diferite scopuri. PHP
prezinta particularitati in modul in care sunt folosite string-urile, dupa cum se poate vedea in exemplele de
mai jos.

Important! Sirurile de caractere sunt expresii (entitati ce au si returneaza o valoare). Asadar, un string poate
fi folosit, pe langa, afisare, in atribuiri, la verificari, etc. In exemplele ce urmeaza s-a optat pentru afisarea
sirurilor.

Siruri de caractere delimitate de ghilimele duble

Sirurile delimitate prin ghilimele duble au particularitatea ca pot interpreta variabilele si caracterele speciale
din interiorul lor. Astfel, la evaluarea textului, variabilele existente in interiorul lui sunt inlocuite cu valoarea
lor iar rezultatul final este returnat.

Testeaza
<?php
$a = "valoarea variabilei"; // definesc o variabila
print "Textul definit cu ghilimele contine $a";

// va afisa
// Textul definit cu ghilimele contine valoarea variabilei
?>

O alta particularitate a acestor siruri o reprezinta folosirea backslash-ului (caracterul \). Acesta are o functie
speciala de marcare a anumitor caractere care nu pot fi incluse in mod normal intr-un text (din cauza ca sunt
ele insele caractere speciale). Din acest motiv backslash-ul poarta numele de escape character.

Testeaza
<?php
print "Ma numesc \"Alex\"!"; // sir ce contine ghilimele, se foloseste \" pentru a
afisa ghilimele

print "Text afisat pe 3 linii: \n linia 2 si \n linia3";


// atentie, textul e afisat pe 2 linii in sursa HTML cu ajutorul caracterului \n (new-
line)
// pentru verificare vizualizati sursa paginii (alegeti "View Source" din browser)

print "Am castigat \$30 :D"; // caracterul dolar are un statut aparte (marcheaza
variabilele)
// pentru a afisa semnul $ asa cum este se foloseste \$

print "Text cu \\backslash\\."; // intrucat backslash \ este un caracter special el


// poate fi afisat ca atare intr-un text doar daca este dublat

23
// daca e folosit doar un singur \ PHP ar trata textul diferit:
print "Text fara \backslash\- \nu se afiseaza corec\t.";

?>

Siruri de caractere delimitate de ghilimele simple

Sirurile delimitate prin ghilimele simple nu permit interpretarea variabilelor continute si nici a caracterelor
speciale cu exceptia \' si \\

Testeaza
<?php
$a = 'valoarea variabilei'; // definesc o variabila
print 'Textul definit cu ghilimele contine $a'; // Textul definit cu ghilimele contine
$a

print 'Porecla ta e Kelu\' ?'; // sir delimitat de ghilimele simple ce contine un


apostrof
print 'Text cu backslash \\'; // sir delimitat de ghilimele simple ce contine un
backslash

print 'Alte escape chars nu sunt interpretate \n \t \b'; // textul este afisat ca atare
?>

Siruri de caractere delimitate cu notatia speciala <<<

Aceste siruri de caractere au avantajul ca nu necesita marcarea (escaparea) delimitatorilor prin \' sau \". In
rest, aceste stringuri sunt tratate in acelasi mod ca cele delimitate de ghilimele duble, in sensul ca permit
interpretarea variabilelor si a altor caractere speciale.

Testeaza
<?php
$a = 'valorii lor'; // definesc o variabila

print <<<TXT
Text pe mai multe linii. <br />
Delimitatorii pot avea orice nume: TXT, START, etc, cu urmatoarele conditii: <br />
- ambii delimitatori (de inceput si sfarsit) trebuie sa aiba acelasi nume
- inainte de primul delimitator se foloseste <<<
- delimitatorul de inceput nu trebuie sa fie urmat de spatiu sau alt caracter
(important!)
- delimitatorul de final sa fie la inceputul liniei (fara spatii inainte)
- dupa delimitatorul final se pune punct si virgula ;
- pot contine ghilimele " sau apostrof ' fara nevoia de a le escapa
- permit interpretarea variabilelor si afisarea $a
TXT;
?>

In versiunile mai noi de PHP (de la 5.3.0) a fost introdusa posibilitatea de a defini siruri prin notatia speciala
<<< fara a interpreta variabilele continute. Exemplul de mai jos foloseste un sir astfel definit (vezi diferenta
la delimitatorul de inceput).

<?php
$a = 'valoarea'; // definesc o variabila

print <<<'TXT'
Incepand cu versiunea 5.3.0 exista un alt mod de delimitare a sirurilor
in care variabilele si caracterele speciale nu sunt interpretate. <br />
Asadar $a si \n raman asa cum sunt.
TXT;
?>

24
Operatii cu siruri de caractere

Mai jos sunt prezentate operatiile uzuale cu siruri de caractere si functiile oferite de limbajul PHP pentru
realizarea lor.

Lungimea sirului

Testeaza
$s = "acesta este un text";
$sir = "stiu PHP stiu HTML stiu CSS";

# ce lungime are sirul? (numarul de caractere)


print strlen( $s ); // 19

Cautarea unei secvente

Testeaza
# verific daca un cuvant sau text (in cazul de fata cuvantul 'PHP') apare in
# sirul exprimat prin variabila $sir
if( strstr( $sir, 'PHP' ) !== false ) print 'gasit';
else print "nu am gasit";

# pentru a nu tine cont de litere mari/mici se foloseste stristr


if( stristr( $sir, 'phP' ) !== false ) print 'gasit';

Afisarea unui subsir

Testeaza
# afisez o sectiune din sir
print substr( $sir, 0, 4); // stiu
print substr( $sir, 5 ); // PHP stiu HTML stiu CSS
print substr( $sir, 5, -3 ); // PHP stiu HTML stiu
print substr( $sir, -3 ); // CSS

# returnez doar un caracter din string


print $sir{5}; // P
print $sir{ strlen($sir)-1 }; // S

Transformarea sirului

Testeaza
# inlocuirea unor secvente
print str_replace( "stiu", "invat", $sir); // invat PHP invat HTML invat CSS

# schimb tipul literelor (mari, mici)


print strtoupper( $s ); // ACESTA ESTE UN TEXT
print strtolower( $sir ); // stiu php stiu html stiu css
print ucfirst( $s ); // Acesta este un text
print ucwords( $s ); // Acesta Este Un Text

# sterg spatiile de la inceput si sfarsit: trim, ltrim, rtrim


print trim(' ok '); // ok

# caractere "enter" transformate in <br />


print nl2br( "acesta e afisat pe \n 2 linii" ); // acesta e afisat pe <br /> 2 linii

25
Impartirea (spargerea) sirului

Testeaza
# impart sirul dupa un caracter, cuvant sau un alt sir
$output1 = explode( "stiu ", $sir ); // impart dupa stiu<spatiu>
/*
Array (
[0] => PHP
[1] => HTML
[2] => CSS
)
*/

# impart sirul dupa o expresie regulata (regex)


$output2 = preg_split( '/ /', $s ); // impart dupa spatiu
/*
Array (
[0] => acesta
[1] => este
[2] => un
[3] => text
)
*/

# operatia inversa impartirii unui sir:


$a = implode( 'invat ', $output1 ); // invat PHP invat HTML invat CSS
$b = join( '-', $output2 ); // acesta-este-un-text
Nota: implode si join sunt echivalente (nu exista nici o diferenta intre ele), pe cand explode si preg_split
sunt diferite.

Concatenarea (legarea) sirurilor

Testeaza
print 'Text 1' . " legat de " . 'text 2' . "\n"; // Text 1 legat de text 2

// se pot concatena siruri rezultate din alte functii sau din variabile
print ucfirst($sir) . '!!! ' . $s;

Nota: prin concatenarea sirurilor se obtine in final un singur sir, care este tratat ca atare, de sine statator.
Altfel spus, prin legarea mai multor siruri se obtine o singura entitate (o singura expresie). Aceasta poate fi
transmisa ca parametru unor functii sau instructiuni precum print care accepta un singur argument.

Interpretarea sirului

Testeaza
# parsez un Query String
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
print $first; // value
print $arr[0]; // foo bar
print $arr[1]; // baz

parse_str($str, $output);
print $output['first']; // value
print $output['arr'][0]; // foo bar
print $output['arr'][1]; // baz

26
Masuri de siguranta

In cazul in care textul provine din surse nesigure (cum ar fi un formular de comentarii), atunci este indicat sa
fie "sterilizat" (sanitized), prin eliminarea elementelor ce pot fi daunatoare (tag-uri HTML, caractere
speciale, etc).

Testeaza
print addslashes( "Baiatu' ia vino-ncoa'!" ); # Baiatu\' ia vino-ncoa\'!
# functia inversa este stripslashes();

print htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);


# afiseaza &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
# functia inversa este htmlspecialchars_decode()

print strip_tags( "<p>E <b>bold</b></p>" ); // E bold


print strip_tags( "<p>E <b>bold</b></p>", '<b>' ); // E <b>bold</b>

Structuri de control in PHP

In limbajul PHP, la fel ca in oricare alt limbaj de programare, instructiunile cuprinse intr-o secventa de cod-
sursa se executa succesiv, una dupa alta. Exista insa anumite instructiuni care modifica ordinea de executie a
liniilor de cod. Din acest motiv ele poarta numele de structuri de control, intrucat ele controleaza fluxul de
executie.

Structurile de control din PHP sunt: structura alternativa (instructiunea if cu variantele ei), structura de
selectie multipla (switch), structuri repetitive (for, while, do... while, foreach), structuri de
intrerupere a fluxului (break, continue, return), structura de salt neconditionat (goto), directivele de
includere (include, require) si directiva declare.

O parte din acestea sunt rar folosite in practica (cum ar fi goto sau declare), motiv pentru care nu le vom
trata in acest ghid. Restul vor fi prezentate succint in cele ce urmeaza sau in lectia urmatoare.

Structura alternativa if

Poate cea mai des intalnita structura de control este instructiunea if. Aceasta este folosita pentru a executa o
secventa de cod in functie de valoarea de adevar a unei conditii. Sintaxa este prezentata mai jos:

if( conditie ) instructiune 1;


Aceasta forma permite executarea unei instructiuni numai daca este indeplinita o conditie. Conditia poate fi
orice expresie de genul "2 mai mic decat 3", "variabila $a este definita", s.a. tradusa in limbajul PHP.
Instructiunea de executat poate fi simpla (o singura instructiune) sau un bloc (mai multe instructiuni
delimitate de acolade). Regula este ca atunci cand este nevoie sa se execute mai mult de o instructiune,
trebuie obligatoriu creat un bloc (trebuie folosite acoladele).
Exemplu:

Testeaza

<?php
if( 2 < 4 ) print "2 e mai mic decat 4 <br />";

if( 3 > 1 ) {
print "3 e mai mare ca 1 \n";
print "<br />";
}
?>

27
Atentie! Daca nu se foloseste un bloc in cadrul instructiunii if, atunci doar prima instructiune dintre cele
existente se executa sau nu, in urma evaluarii conditiei, pe cand celelalte se vor executa intotdeauna,
indiferent de rezultatul verificarii. De exemplu:
Testeaza
<?php
echo "Este 3 mai mic decat 2? <br />\n";
if( 3 < 2 )
print "Da, 3 < 2 - prima linie <br />";
print "Da, 3 < 2 - a doua linie <br />";
?>
Codul de mai sus va afisa:
Este 3 mai mic decat 2? <br />
Da, 3 < 2 - a doua linie <br />
Pentru ca nu am inclus cele 2 instructiuni print intr-un bloc, a doua instructiune s-a executat indiferent de
valoarea de adevar a conditiei. Practic, doar prima instructiune print a fost considerata ca facand parte din
structura if. Codul corect (din punct de vedere logic) ar fi urmatorul, care contine un bloc de instructiuni:
Testeaza
<?php
echo "Este 3 mai mic decat 2? <br />\n";
if( 3 < 2 ) {
print "Da, 3 < 2 - prima linia <br />";
print "Da, 3 < 2 - a doua linie <br />";
}
?>
Instructiunea if - else

De multe ori este nevoie sa se specifice si o operatie ce trebuie efectuata daca nu este indeplinita o conditie.
In acest caz se foloseste if - else.

if( conditie ) instructiune 1;


else instructiune 2;

Aceasta forma permite executarea unei instructiuni atunci cand se indeplineste conditia sau executarea alteia
diferite in caz contrar. Aceleasi observatii ca si mai sus se aplica.

Testeaza
<?php
echo "Este 3 mai mic decat 2? <br />\n";
if( 3 < 2 ) {
print "Da, 3 < 2 - prima linia <br />";
print "Da, 3 < 2 - a doua linie <br />";
} else {
print "Nu, 3 > 2 - prima linia <br />";
print "Nu, 3 > 2 - a doua linie <br />";
}
?>
Instructiunea de selectie multipla

O instructiune ce se aseamana cu if este switch, o structura ce permite executarea uneia sau mai multor
linii de cod in functie de valoarea unei expresii. Instructiunea switch este utila in cazurile in care este nevoie
sa se verifice mai multe valori posibile ale unei expresii.

Testeaza
<?php
$var = 3;

28
// se vor executa instructiunile de pe ramura care
// corespunde valorii variabilei $var
switch( $var ) {
case 0:
print 'zero';
break;
case 1:
print 'unu';
break;
case 2:
print 'doi';
break;
case 3:
print 'trei'; // afisez trei
break; // intrerup fluxul executiei switch
case 4:
print 'patru';
break;
case 5:
print 'cinci';
break;
}

echo "\n", 'Gata!';


?>

De mentionat este faptul ca, daca nu se foloseste instructiunea de control break, in momentul in care o
ramura este selectata, se vor executa atat instructiunile aferente acelei ramuri cat si instructiunile ramurilor
urmatoare. Acest lucru poate sa nu fie dorit intotdeauna, de aceea este important ca break sa fie folosita ori
de cate ori fluxul de executie al blocului switch trebuie intrerupt.

Exemplul de mai jos va executa instructiunea print 2; si toate celelalte instructiuni print care urmeaza,
intrucat fluxul nu este intrerupt prin break.

Testeaza
<?php
$numar = 2;

// se vor executa instructiunile de pe ramura care


// corespunde valorii variabilei $numar
switch( $numar ) {
case 0:
print 0;
case 1:
print 1;
case 2:
print 2;
case 3:
print 3;
case 4:
print 4;
case 5:
print 5;
}

echo "\n", 'Gata!';

// va afisa 2345 Gata


?>

Includerea altor scripturi

29
PHP permite referirea unor fisiere PHP externe si includerea lor in fluxul curent de executie folosind
functiile include sau require. Important de mentionat, in momentul in care un script este inclus cu una din
cele 2 functii, el este imediat si executat (interpretat). Practic, fluxul de executie al scriptului initial (cel in
care apare instructiunea include sau require) este intrerupt temporar pentru a executa scriptul inclus,
urmand ca dupa finalizarea executiei, fluxul initial sa fie reluat.

Spre exemplu, daca avem doua fisiere ca mai jos, la accesarea scriptului script.php vor fi afisate ambele
mesaje - asta pentru ca in urma instructiunii include scriptul config.php este imediat interpretat.

<?php
// fisierul config.php
echo 'Sunt in config.php <br />';
?>

<?php
// fisierul script.php
include( 'config.php' );
echo 'Sunt in script.php <br />';
?>

Prin functionalitatea lor, instructiunile include si require devin utile la organizarea codului PHP si la
mentinerea unei structuri simple de executie prin folosirea mai multor fisiere pentru o singura activitate.
Astfel, putem sa separam codul in scripturi PHP de sine statatoare ce vor fi "puse cap la cap" prin apeluri de
include sau require.

Spre exemplu, putem avea niste declaratii de date intr-un script numit config.php si codul propriu-zis intr-
un altul, pagina.php. Putem apoi include fisierul de configurari (config.php) direct din scriptul principal
(pagina.php), reusind astfel sa mentinem codul aerisit.

Include sau require?

Functia require face acelasi lucru ca si include dar exista o diferenta intre cele doua: daca fisierul solicitat
pentru includere nu exista, include va returna un avertisment, continuand executia, pe cand require va
returna o eroare iar executia codului va fi intrerupta.

Testeaza
<?php
include( 'fisier_inexistent.php' ); // genereaza un warning si merge mai departe
echo 'Acest mesaj va fi afisat';

require( 'fisier_inexistent.php' ); // genereaza o eroare iar executia se intrerupe


echo 'Aceasta instructiune nu va mai fi executata';
?>

Cele doua functii au fiecare cate o varianta: include_once respectiv require_once. Aceste forme, dupa
cum si numele o spune, includ fisierul specificat o singura data, astfel incat, daca fisierul solicitat a fost deja
inclus la o noua apelare a include_once sau require_once acesta nu va fi inclus a doua oara. Aceste forme
ale functiilor sunt utile atunci cand fisierle incluse contin declaratii ce trebuie sa fie facute o singura data.

Operatii cu variabile. Structuri repetitive

O structura repetitiva este o secventa de cod ce permite realizarea repetata a aceleiasi operatii de un anumit
numar de ori. O structura repetitiva este definita de 2 elemente: operatia care este executata si conditia de
oprire a executiei. In unele cazuri se cunoaste si numarul de executii (sau iteratii).

30
Iata cateva aplicatii care implementeaza anumite tipuri de structuri in PHP:

Structura repetitiva for

Se foloseste atunci cand se cunoaste dinainte numarul de repetitii (numarul de pasi ce se vor executa). Are
urmatoarea sintaxa:

for( [instructiune1] , [conditie], [instructiune2] ) { [instructiune3] }

unde:

instructiune1 este o instructiune de executat la inceput

conditie este o expresie care daca este evaluata ca adevarata va determina repetarea ciclului - este
denumita generic conditia de repetare

instructiune2 se va executa la fiecare pas al repetarii

instructiune3 reprezinta operatia efectiva care se repeta in cadrul FOR-ului

In general, [instructiune1] este o expresie de initializare de forma $i = 1, conditia de repetare este de forma
$i <= numarul de pasi si [instructiune2] este o expresie de incrementare $i++.

for( $i = 1; $i <= $n; $i++) { /* operatii */ }

In limbaj natural, intructiunea se traduce prin "plecand de la $i = 1, executa operatia si creste-l pe $i cu o


unitate; apoi repeta totul atat timp cat $i <= $n

De retinut: instructiunea din cadrul for-ului se executa doar daca expresia (conditia) este adevarata, deci
pot exista situatii cand expresia este falsa si [instructiune3] nu se executa niciodata. Exemplu:

for( $i = 0; $i > 10; $i++ ) {


echo 'Aceasta instructiune nu se executa niciodata';
}

Structura repetitiva while

Instructiunea while este folosita atunci cand nu se cunoaste dinainte numarul de executii. Are o forma mai
intuitiva decat for si multe persoane o considera mai usor de folosit. Diferenta dintre while si for este
aceea ca prima este mai generala si mai flexibila. Se poate chiar afirma ca for este o situatie particulara a
unei structuri while. Sintaxa este urmatoarea:

while( [conditie] ) { [instructiune] }

Este probabil usor de inteles ca [instructiune] se executa atata timp cat [conditie] este adevarata. La
fel ca si la for, exista posibilitatea ca instructiunea sa nu fie executata niciodata.

De retinut: este de datoria programatorului sa includa in [instructiune] codul necesar iesirii din bucla.
Daca acest lucru nu se realizeaza, instructiunea se va executa la nesfarsit. Exemplu:

$continua = true;
while( $continua == true ) {
echo 'La nesfarsit', '<br>';
}
echo 'Aici nu se mai ajunge';
31
Varianta corecta a exemplului de mai sus este urmatoarea:

$continua = true;
while( $continua == true ) {
echo 'La nesfarsit', '<br>';
$continua = false; # modific variabila de testare a conditiei
}
echo 'Acum se ajunge aici';

Structura repetitiva do... while

O alta structura repetitiva este do... while. Diferenta fata de while este ca verificarea de face la final,
dupa ce se executa cel putin o data secventa de cod. O traducere in cuvintele noastre ar fi: "executa
secventa si cat timp conditia este adevarata, repet-o".

Exemplul de mai sus, rescris ar arata asa:

$vector = array( 3, 4, 5, 1, 2, 9, 76, 42, 2, 9, 6, 0, 4, 1, 10 );

# operatia: se verifica daca elementul curent al vectorului este 0


# conditia de oprire: elementul curent este 0 sau s-a ajuns la finalul vectorului
# nota: desi putem afla numarul de elemente al vectorului, in functie de care
# putem hotari numarul maxim de repetari, se va folosi o alta sctructura repetitiva

$pozitie = 0; // plecam de la primul element

// parcurgem vectorul pana cand ajungem la final sau gasim valoarea 0


do {
// presupun mai intai ca elementul e gasit
$gasit = true;

// verific daca elementul curent (initial primul element) este diferit de 0


// cu alte cuvinte, deocamdata nu am gasit ce caut, deci merg mai departe
if( $vector[ $pozitie ] != 0 ) {
$gasit = false;

// trec la pozitia urmatoare pentru verificare


$pozitie++;
}

} while ( !$gasit && $pozitie < count( $vector ) );

if( $gasit ) print "Am gasit 0 pe pozitia $pozitie";


else print "Nu am gasit 0 in vectorul asta";

/* afiseaza
Am gasit 0 pe pozitia 11
*/

Iterarea cu foreach

PHP ofera o structura repetitiva foarte puternica si des folosita: foreach. Aceasta permite iterarea prin toate
elementele unui vector. Pot fi folositi si vectori simpli si asociativi. Spre deosebire de celelalte instructiuni,
pentru foreach nu trebuie specificata explicit o conditie de oprire, fiind de datoria interpretorului PHP sa
opreasca iterarea atunci cand s-a ajuns la finalul vectorului.

// parcurgerea unui vector cu foreach


$vector = array( 3, 4, 5, 1, 2, 9 );
32
// afiseaza: 3 4 5 1 2 9
foreach( $vector as $element) {
print "$element ";
}

// parcurgerea unui vector cu foreach, folosind cheile si valorile


$vector = array( 'a', 'b', 'c', 'd', 'e', 'f' );

// afiseaza: a b c d e f
foreach( $vector as $cheie => $element) {
print "$element ";
}

// afiseaza: 0 1 2 3 4 5
foreach( $vector as $cheie => $element) {
print "$cheie ";
}
// Nota: chiar daca $vector nu este asociativ in mod explicit,
// elementele sale oricum au chei implicite valorile 0, 1, 2, 3 ...

// vector asociativ (definit explicit cu chei)


$zile = array(
'luni' => 'Mo',
'marti' => 'Tu',
'miercuri' => 'We',
'joi' => 'Th',
'vineri' => 'Fr',
'sambata' => 'Sa',
'duminica' => 'Su'
);
// afiseaza Mo Tu We Th Fr Sa Su
foreach( $zile as $eng) {
print "$eng ";
}

// afiseaza si cheia si valoarea intr-un text


foreach( $zile as $rom => $eng) {
print "$eng inseamna $rom <br />";
}

/* afiseaza
Mo inseamna luni
Tu inseamna marti
We inseamna miercuri
Th inseamna joi
Fr inseamna vineri
Sa inseamna sambata
Su inseamna duminica
*/

Intreruperea fluxului de executie

In toate structurile repetitive prezentate mai sus, executia poate fi intrerupta, partial sau total, folosind
instructiunile continue sau break.

continue

Instructiunea continue permite oprirea iteratiei curente a unei structuri repetitive si trecerea imediata la
iteratia urmatoare. Folosind continue toate instructiunile din blocul structurii sunt sarite pentru iteratia
curenta, iar executia continua cu iteratia urmatoare. Un exemplu:
33
for($i = 0; $i < 10; $i++) {
/* la toate executiile in care $i <= 5, se va "sari" peste
* instructiunile print; practic, dupa apelul continue,
* executia "trece" la pasul urmator, crescandu-l pe $i */
if( $i <= 5 ) {
continue;
}
print $i;
print "<br />\n";
}

In exemplul de mai sus avem o structura repetitiva for cu 10 executii (de la 0 la 9). Pentru iteratiile in care
$i este sub 6, se va executa instructiunea de control continue, care va sari peste tot ce urmeaza (doua
instructiuni print) si va forta trecerea la iteratia urmatoare. Asadar, la finalul executiilor se vor afisa doar
numerele de la 6 pana la sfarsit.

De retinut, continue afecteaza doar iteratia curenta; celelalte iteratii se pot executa complet, atat timp cat
continue nu este apelata din nou. Nu este nici o diferenta de la o structura repetitiva la alta (for, while, do
while) - continue se comporta la fel.

break

Instructiunea break permite intreruperea totala a executiei structurii curente si trecerea la urmatoarea linie
de cod. Folosind break toate instructiunile din blocul structurii sunt sarite pentru toate iteratiile (curenta si
cele urmatoare). Practic se "iese" fortat din blocul structurii repetitive, iar fluxul de executie continua cu
instructiunea de dupa structura repetitiva.

Testeaza
for($i = 0; $i < 10; $i++) {
// cand $i == 2, se va "iesi" din structura
if( $i == 2 ) {
break;
}
print $i;
print "<br />\n";
}
print "Gata!"; // cand $i == 2 se "sare" direct aici, ignorand celelalte iteratii

Spre deosebire de continue, instructiunea break afecteaza toate iteratiile unei structuri; nici o alta iteratie a
blocului structurii nu se mai realizeaza dupa break.

Un apel break are acelasi efect pentru toate structurile repetitive. In plus, instructiunea se poate folosi si in
alte structuri de control, cum este switch, avand ca efect "iesirea" din blocul de selectie.

Structuri multiple

In cazul in care exista structuri repetitive multiple, incluse unele in interiorul celorlalte, instructiunile break
si continue pot primi ca parametru nivelul structurii pe care o afecteaza. Spre exemplu, daca avem 2 for-
uri ca in secventa de cod de mai jos, apelul break 1; se refera la for-ul din interior, pe cand break 2; se
refera la primul for (cel cu $i).

Testeaza
$n = 7;
for($i = 0; $i < $n; $i++) {
// la fiecare iteratie a lui $i, avem un alt for
echo 'Iteratia #', $i, ': ';
for($j = 0; $j < $n; $j++) {
34
if( $i == 4 && $j == 4 ) {
break 2; // se aplica la for-ul mare
}
if( $j >= $n - $i ) {
continue 1; // se aplica la for-ul din mijloc
}
print "$j ";
}
print "\n";
}

De obicei, se recomanda evitarea unor astfel de constructii, intrucat codul devine greu de urmarit si pot sa
apara usor probleme. De cele mai multe ori, nici nu va fi nevoie sa apelati continue sau break cu
parametru, dar in orice caz, incercati sa evitati pe cat posibil intreruper iteratiilor pe mai multe nivele.

Diferenta dintre break si exit

Intrucat am vorbit despre intreruperea executiei, este posibil sa apara confuzii intre break si exit sau die.
Este adevarat ca atat break cat si celelalte intrerup executia secventei de cod, doar ca aceasta intrerupere se
realizeaza la niveluri diferite. Astfel, break actioneaza doar la nivelul structurii din este apelat, pe cand exit
si die actioneaza la nivelul intregului script PHP.

Instructiunea break va intrerupe executia structurii care o contine, dar va permite continuarea executiei cu
alte instructiuni ce urmeaza. Exit sau die nu mai permit nici o alta executie.

Aplicatii - Structuri repetitive

Cum definesc un vector ale carui elemente sa aiba valori incrementale?


/* vrem sa construim un vector in care fiecare element sa fie initializat
* cu o valoare dinamica si incrementala; avem, asadar, o aceeasi operatie
* care se repeta de mai multe ori, motiv pentru care vom folosi un for */

$vector = array();
$n = 10;

# operatia repetitiva: definirea si initializarea unui element al vectorului


# conditia de continuare: inca nu s-au efectuat $n repetari
# nota: in acest caz cunoastem numarul de repetari, dat de variabila $n

for( $i = 1; $i <= $n; $i++) {


# intre paranteze se specifica expresia de initializare $i = 1
# conditia de continuare $i <= $x si o expresie de iterare $i++

$vector[ $i ] = "php$i"; # aceasta este operatia


}

print_r( $vector );

/*afiseaza:
Array
(
[1] => php1
[2] => php2
[3] => php3
[4] => php4
[5] => php5
[6] => php6
[7] => php7
[8] => php8
[9] => php9
35
[10] => php10
)
*/
Cum afisez o lista de link-uri?
<?php
/* similar exemplului anterior */

# operatia repetitiva: afisarea unui element de tip <li> cu valori dinamice


# conditia de continuare: inca nu s-au efectuat $n repetari

# va trebui sa avem lista de link-uri definita intr-un vector.


$links = array(
'www.punctsivirgula.ro',
'php.punctsivirgula.ro',
'php.punctsivirgula.ro?despre',
'php.punctsivirgula.ro?legal'
);

# determin lungimea listei


$n = count( $links );

# avand lungimea, folosesc o structura for pentru a afisa lista


echo '<ul>';
for( $i = 0; $i < $n; $i++ ) {
echo <<<LINK
<li>
<a href="http://{$links[ $i ]}" title="{$links[ $i ]}">{$links[ $i ]}</a>
</li>
LINK;
}
echo '</ul>';

?>
Rezultat:
www.punctsivirgula.ro
php.punctsivirgula.ro
php.punctsivirgula.ro?despre
php.punctsivirgula.ro?legal

Cum afisez un element de tip select cu valori de la 1 la 100?


/* similar exemplului anterior */

$end = 100;

# operatia repetitiva: afisarea unui element de tip <option>


# conditia de continuare: inca nu s-au efectuat $end repetari
# nota: ca zi in cazul anterior se cunoaste numarul de repetari

print "<select>";
for( $i = 1; $i <= $end; $i++ ) {
print "<option value=\"$i\">$i</option>\n";
}
print "</select>";

Rezultatul codului de mai sus este urmatorul:

Cum afisez un element de tip select cu toate tarile?


<?php

# ne trebuie o lista de tari. Cel mai uzual pastram doar codul tarii, iar numele il
afisam doar.
36
# Astfel, optiunile vor avea ca "value" codul tarii iar ca "text" - numele.

$countries = array(
'AF'=>'Afghanistan',
'AL'=>'Albania',
'DZ'=>'Algeria',
'AS'=>'American Samoa',
'AD'=>'Andorra',
'AO'=>'Angola',
'AI'=>'Anguilla',
'AQ'=>'Antarctica',
'AG'=>'Antigua And Barbuda',
'AR'=>'Argentina',
'AM'=>'Armenia',
/* ... */
'WS'=>'Western Samoa',
'YE'=>'Yemen',
'YU'=>'Yugoslavia',
'ZM'=>'Zambia',
'ZW'=>'Zimbabwe'
);

# avand un array asociativ, este mai dificil sa-i accesam elementele, asa ca nu vom
# mai folosi for. Vom folosi in schimb un iterator

echo '<select name="tara">', "\n"; # afisez pe alt rand pentru a aseza in pagina sursa
HTML
foreach( $countries as $code => $name ) {
echo '<option value="', $code, '">', $name, '</option>', "\n";
}
echo "</select>\n";

?>

Rezultat:

Cum caut o valoare intr-un vector?


/* avem un vector cu un numar necunoscut de valori; vrem sa cautam valoarea 0
* folosind o structura repetitiva */

$vector = array( 3, 4, 5, 1, 2, 9, 76, 42, 2, 9, 6, 0, 4, 1, 10 );

# operatia repetitiva: se verifica daca elementul curent al vectorului este 0


# conditia de oprire: elementul curent este 0 sau s-a ajuns la finalul vectorului
# nota: desi putem afla numarul de elemente al vectorului, in functie de care
putem determina numarul maxim de repetari, se va folosi structura while

$gasit = false;
$pozitie = 0; // plecam de la primul element

// parcurgem vectorul pana cand ajungem la final sau gasim valoarea 0


while( !$gasit ) { // echivalent cu while( $gasit == false )
// verific daca elementul curent (initial primul element) este 0
if( $vector[ $pozitie ] == 0 ) {
$gasit = true;
print "Am gasit 0 pe pozitia $pozitie";
}

// trec la pozitia urmatoare pentru verificare


$pozitie++;
// spre deosebire de "for" incrementarea trebuie realizata explicit

37
// verific daca am ajuns la sfarsitul verctorului
if( $pozitie == count( $vector ) ) {
$gasit = true; // ca sa nu mai repete
print "Nu am gasit 0 in vectorul asta";
}
}

# in limbaj natural, instructiunea while se poate transpune in "cat timp


# conditia este indeplinita executa operatiunea"

/* afiseaza
Am gasit 0 pe pozitia 11
*/
Exemplul de mai sus este dat pentru a intelege cand si de ce se foloseste 'while'. Toata verificarea se poate
face mult mai rapid folosind o functie oferita de limbaj: array_search.
// alternativa
$vector = array( 3, 4, 5, 1, 2, 9, 76, 42, 2, 9, 6, 0, 4, 1, 10 );

$pozitie = array_search(0, $vector );

if( $pozitie === false ) print "Nu am gasit 0 in vectorul asta";


else print "Am gasit 0 pe pozitia $pozitie";

Cum validez mai multe email-uri introduse de un utilizator?


<?php

# presupunem ca exista mai multe textbox-uri intr-un formular, numite email[]


$emails = $_POST[ 'email' ]; # pentru detalii despre $_POST vedeti lectia "Formulare"

# pentru teste se poate folosi:


$emails = array( 'ok@test.com', 'zzz', 'test@site', 'test@test.com', 'aaa' );

# folosesc o variabila ce actioneaza ca un flag/switch


$gasitInvalid = false;

# determin nr de email-uri
$n = count( $emails );

# plec de la primul email-uri


$i = 0;

// parcurgem vectorul pana cand ajungem la final sau gasim un email invalid
while( $gasitInvalid == false && $i < $n ) {
// verific daca elementul curent (din iteratia curenta) este invalid
if( strpos( $emails[ $i ], '@' ) === false ||
strpos( $emails[ $i ], '.' ) === false ) {
# un email valid trebuie sa contina @ si un punct
$gasitInvalid = true;
echo 'Am gasit un email invalid: ', $emails[ $i ], '<br />';

//break;
/* pot folosi break dar este inutil pentru ca se va iesi oricum
din bucla while datorita variabilei $gasitInvalid care e true */
}
$i++; # cresc pe $i
}

# daca s-a ajuns la sfarsitul sirului de email-uri si $gasitInvalid este tot false
# inseamna ca nu exista nici un element invalid
if( !$gasitInvalid ) echo 'Toate email-urile sunt valide!<br />';

?>

38
Rezultat:

Am gasit un email invalid: zzz

Nota: se putea folosi si structura repetitiva for pentru ca se cunosteau dinainte numarul de pasi ce trebuiau
efectuati. In schimb, folosind aceasta implementare, atunci cand se gaseste un email valid se opreste executia
(se iese din bucla while), asadar codul ar putea fi mai performant decat in cazul folosirii for.

Spre exemplu, daca avem un vector cu 15 elemente, iar pe pozitia a doua se afla un email invalid, atunci
executia se termina dupa 2 pasi: la primul pas se verifica primul element care este valid, iar la al doilea,
gasindu-se un email invalid se iese din ciclul while (din cauza ca $gasitInvalid nu mai este false).

Operatii cu vectori

Operatiile clasice de cautare, sortare, inserare, etc se pot realiza foarte usor cu ajutorul functiilor specializate,
fara sa fie necesara parcurgerea manuala a vectorilor. Iata cateva exemple.

$vector = array( 1, 2, 3, 4, 5, 6 );
$vectAs = array(
'unu' => 'one',
'doi' => 'two',
'trei' => 3
);

// lungimea unui vector (numarul de elemente)


print count( $vector ); // 6

// se gaseste o valoare in vector?


print in_array( 3, $vector ); // true

// exista o anumita cheie in vector?


print array_key_exists( 'trei', $vectAs ); // true

// returneaza toate cheile din vector:


print_r( array_keys( $vectAs ) ); // Array ( [0] => unu [1] => doi [2] => trei )

// returneaza toate valorile din vector:


print_r( array_values( $vectAs ) ); // Array ( [0] => one [1] => two [2] => 3 )

// returneaza o parte din vector


print_r( array_slice( $vector, 3 ) ); // de la pozitia 3 pana la final: 4, 5, 6
print_r( array_slice( $vector, 3, 2 ) ); // de la pozitia 3, doua elemente: 4, 5
print_r( array_slice( $vector, -5, 3 ) ); // de la final inapoi 5 pozitii: 2, 3, 4

// foloseste cheile unui vector ca variabile:


extract( $vectAs );
print $unu; // one
print $doi; // two
print $trei; // 3

// sorteaza un vector
sort( $vector ); // 1, 2, 3, 4, 5, 6
rsort( $vector ); // 6, 5, 4, 3, 2, 1
asort( $vectAs ); // sorteaza valorile si mentine asocierea cheilor

// preluare elemente unice din vector


print_r( array_unique( $vector ) );

// adauga o valoare la sfarsitul unui vector


$vector[] = 7;
array_push( $vector, 8 );
39
# nota: cele 2 instructiuni de mai sus sunt echivalente

// modifica un anumit element din vector


$vectAs[ 'trei' ] = 'three';

Aplicatie: Sa se afiseze tipul browserului folosit de utilizator


// afisarea unui 'dump' al vectorului - o lista cu toate elementele.
//De obicei se foloseste la depanare:

print_r( $vectAs );
/* afiseaza
Array
(
[unu] => one
[doi] => two
[trei] => 3
)
*/

// se afiseaza la fel ca mai sus o lista cu elementele vectorului, doar


// ca se specifica si tipul fiecaruia.

var_dump( $vectAs );
/* afiseaza
array(3) {
["unu"]=>
string(3) "one"
["doi"]=>
string(3) "two"
["trei"]=>
int(3)
}
*/

Operatii comune cu indicatori de timp

Limbajul PHP ofera solutii simple (dar puternice) pentru lucrul cu data si timpul. In versiunile mai noi (dupa
5.1) sunt introduse facilitati avansate cum ar fi DST (Daylight Saving Time), Timezones, Date Intervals, s.a.
Inainte de acestea insa lucrul cu timpul se realiza folosind Unix timestamp.

Conceptul de Unix timestamp desemneaza numarul de secunde scurse de la 1 ianuarie 1970 (cand se
considera ca a inceput era Unix).

Unix Timestamp-ul curent:


1375871343

Fiind vorba de un numar pozitiv ce are mereu aceeasi referinta, este usor sa se realizeze operatii cum ar fi
scaderea, adunarea sau compararea a doua date reprezentate printr-un Unix timestamp.

Mai jos sunt cateva aplicatii menite sa evidentieze cat de usor se pot manipula date si ore in PHP.

<?php
// data curenta
print date( 'd.m.Y H.i.s' ); // 07.08.2013 13.29.03

// data in format Unix (UNIX timestamp)


print time(); // 1375871343

// alegerea unui fus orar


40
date_default_timezone_set( 'Europe/Bucharest' );

// parsarea unei date


print strtotime("now");
print strtotime('1st January 2004'); //1072915200
?>

Cum aflu o data din trecut sau viitor?

Sunt mai multe posibilitati. Se poate pleaca de la o data cunoscuta (pentru care avem Unix timestamp) si prin
adunari/scaderi de secunde se afla data dorita (vezi aplicatia de mai jos). Sau se poate parsa o data folosind
strtotime. Aceste solutii nu sunt intotdeauna aplicabile, iar in aceste cazuri se foloseste functia mktime.

Functia mktime primeste ca parametri anul, luna, ziua, ora pentru care se doreste aflarea detaliilor. Rezultatul
este un timestamp ce poate fi formatat dupa cum se doreste.

<?php
# care este timestamp-ul pentru 31 januarie 2004, ora 13:00
echo mktime( 13, 0, 0, 1, 31, 2004); // afiseaza 1075546800

# care este timestamp-ul pentru 3 septembrie 2014, ora 10:30


echo mktime( 10, 30, 0, 9, 3, 2014); // afiseaza 1409729400

# ultima zi a unei luni poate fi exprimata ca ziua "0" a lunii urmatoare.


$ultima = mktime(0, 0, 0, 3, 0, 2000);
echo strftime("Ultima zi din Februarie 2000 este: %d", $ultima );
// afiseaza Ultima zi din Februarie 2000 este: 29

# se pot folosi si valori negative


$zi = mktime(0, 0, 0, 3, -3, 2000);
echo strftime("Inainte de Martie 2000 cu 4 zile: %d", $zi );
// afiseaza Inainte de Martie 2000 cu 4 zile: 26

?>

Important: inainte de PHP 5.1.0, timestamp-urile negative nu erau suportate in unele sisteme (inclusiv
Windows). De aceea domeniul valid al anilor era limitat intre 1970 si 2038.

Cum se formateaza data sau ora?

Formatarea datei sau a orei se poate realiza usor folosind functia date. Cu ajutorul acesteia se pot "extrage"
doar acele parti din data care sunt necesare si se poate specifica formatul dorit. Spre exemplu, folosind
functia date putem afisa data in format lung (de genul: "marti, 30 septembrie 2001") sau scurt (30.11.2001)
sau cu aceeasi functie putem afisa ora sau oricare combinatie a celor doua.

Formatul se specifica print-un text format din caractere ce au o semnificatie anume, transmis ca parametru
functiei date. Pentru detalii complete despre fiecare caracter in parte accesati
http://www.php.net/manual/ro/function.date.php.

<?php
# se preia data/ora curenta
$acum = time(); // $acum este o data in format Unix: 1375871343

# formatarea se realizeaza cu functia date


# daca nu se specifica altfel, functia date va formata data/ora curenta
echo date("H:i:s") . "<br>"; // afiseaza 13:29:03
echo date("Y-m-d") . "<br>"; // afiseaza 2013-08-07
echo date("F j, Y, g:i a") . "<br>"; // afiseaza August 7, 2013, 1:29 pm
echo date("l") . "<br>"; // afiseaza Wednesday

41
# se poate specifica un al doilea parametru ce reprezinta data/ora care se formateaza
echo date("d-m-Y H:i:s", $acum) . "<br>"; // afiseaza 07-08-2013 13:29:03
echo date("D, M d, Y", 1072915200) . "<br>"; // afiseaza Thu, Jan 01, 2004

# combinat cu mktime, se pot obtine informatii despre zile din trecut sau viitor
# de exemplu, ce zi a fost pe 4 iulie 2000
$iulie4 = mktime( 0, 0, 0, 7, 4, 2000 ); # aflu timestamp-ul
echo date( 'l', $iulie4 ); # formatez acel timestamp - extrag doar ziua
// afiseaza Tuesday

?>

Cum determin ce zi si ora va fi peste 480 ore?

Pentru a efectua usor operatii cu zile si ore, se va folosi formatul de data Unix (UNIX timestamp), returnat
de functia time(). Practic, data este afisata ca numarul de secunde scurs de la 1 ianuarie 1970, ora 00:00.
Avand aceasta noua perspectiva (de a privi datele ca un numar de secunde), operatiile cu date (de genul 'cat
va fi peste 2 zile', 'ce ora a fost acum xxx minute', etc) devin extrem de simple luand forma unor simple
scaderi si adunari de secunde.

<?php
// cerinta este: "cat va fi ora peste 480 de ore, adica peste (480 * 60 *60) secunde

$acum = time();
$maiTarziu = 480 /*ore*/ * 60 /*minute*/ * 60 /*secunde*/;

print "Data ceruta este: " . date( 'd.m.Y H.i.s', $acum + $maiTarziu );
// Data ceruta este: : 27.08.2013 13.29.03
?>

Cum validez o data sau un timp?

Sunt mai multe modalitati de a valida datele si orele introduse de un utilizator, in functie de formatul
acestora. Cel mai uzual insa se folosesc cele 2 functii de aflare a timestamp-ului: mktime si strtotime.
Acestea returneaza anumite valori in cazul in care data verificata nu este valida.

<?php
# mktime se foloseste cand avem date bine definite
# de exempleu, verificam daca a existat 29 februarie 2004
$rezultat = mktime( 0, 0, 0, 2, 29, 2004 );
if( $rezultat === FALSE || $rezultat === -1 ) {
# daca rezultatul nu este un timestamp inseamna ca data nu e valida
echo "Data nu exista";
} else {
echo "Data este valida: " . date( 'd.m.Y', $rezultat);
}
// Rezultat: Data este valida: 29.02.2004

# strtotime se foloseste cand avem date relative


$rezultat = strtotime( "2 days ago" );
if( $rezultat === FALSE || $rezultat === -1 ) {
echo "Data nu exista";
} else {
echo "Data este valida: " . date( 'd.m.Y', $rezultat);
}
// Rezultat: Data este valida: 05.08.2013

?>

Cum afisez un mesaj de salut in functie de ora curenta (a serverului)?


42
<?php
$t = localtime( time(), true ); // returneaza un vector cu elementele datei si orei
locale
$h = $t[ 'tm_hour' ]; // iau doar ora

if( $h >= 7 && $h <= 11 ) print "Buna dimineata!";


elseif( $h > 11 && $h < 18 ) print "Buna ziua!";
elseif( $h >= 18 && $h < 22 ) print "Buna seara!";
elseif( $h >= 22 ) print "Noapte buna!";
else print "Ce? Esti treaz(a) la ora asta?";

// Buna ziua!
?>

Cum afisez luna curenta si toate cele 12 luni in limba romana?

Nota: aceasta secventa de cod depinde de configurarile serverului pe care este executata. Limba romana
trebuie instalata pe server pentru a avea rezultatele scontate.

<?php
setlocale( LC_TIME , 'ROM_ROM' );

// afiseaza numele celor 12 luni


for( $m = 1; $m <= 12; $m++ ) {
print strftime( "%B", mktime( 0,0,0, $m, 1, 2008 ) ) . "\n";
}

// afiseaza luna curenta


print 'Luna curenta este: ' . strftime( "%B", time() );
?>
Rezultatul (este posibil sa nu fie in limba romana!):
January
February
March
April
May
June
July
August
September
October
November
December

Luna curenta este: August

Cum determin durata de executie a unui script PHP?


<?php
$time_start = microtime(true); # la inceputul codului PHP

/* ... codul PHP cu diverse operatii ... */

# la final se face diferenta si se afiseaza


$time_end = microtime(true);

print "Durata de executie (secunde): " . ( number_format($time_end - $time_start, 6) );


// Durata de executie (secunde): 0.003122
?>

43
Instructiuni uzuale folosite in PHP

Pe langa instructiunile comune amintite in lectiile anteriorare - instructiunile de afisare, instructiunile de


control, instructiunile pentru vectori, string-uri sau timp - exista o serie de alte functii ale limbajului PHP
care sunt folosite cu precadere de orice programator.

Detaliem in cele ce urmeaza cateva dintre ele.

Functia mail()

PHP poate trimite emailuri daca pe serverul curent este instalata si o aplicatie de email (un server de email).
Nu este nevoie de configurari suplimentare atat timp cat serverul de email nu are restrictii si poate fi accesat
de aplicatiile locale. Intr-o instalare pe calculatorul personal, cum este cea descrisa in primele pagini ale
acestui tutorial, nu este posibila trimiterea de mesage email, iar functia mail va returna o eroare. Pe un web-
server configurat complet si corect, cum sunt serverele ce ofera gazduirea site-urilor, functia mail
functioneaza corect.

<?php
// trimitere mesaj simplu
mail('adresa@exemple.com', 'Subiect mesaj', 'Mesaj simplu');

// trimiterea unui mesaj in care se specifica date aditionale


$to = 'adresa@example.com';
$subject = 'Subiect mesaj';
$message = 'Mesaj simplu cu date aditionale';
$headers = 'From: punctsivirgula@example.com' . "\r\n" .
'Reply-To: punctsivirgula@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);


?>

Functii matematice

Limbajul PHP dispune de majoritatea functiilor matematice uzuale. Cateva dintre ele sunt prezentate mai jos
cu titlu exemplificativ. Lista completa poate fi gasita pe site-ul de documentatie PHP.

<?php
echo abs(-7); // functia "valoare absoluta", afiseaza 7
echo sin(60); // functia "sinus", afiseaza -0.304810621 ...
echo decbin(12); // returneaza reprezentarea binara a numarului, afiseaza 1100
echo base_convert('7DB', 16, 10); // returneaza convesia dintr-o baza in alta,
afiseaza 2011
echo round(12.3); // returneaza o rotunjire la cel mai apropiat intreg, afiseaza 12

echo rand(); // afiseaza un numar aleator


echo rand(10, 70); // afiseaza un numar aleator din intervalul specificat
?>

Functia set_time_limit()

Functia set_time_limit se foloseste pentru a configura timpul maxim cat scriptul curent are voie sa se
execute. Este utila atunci cand codul PHP trebuie sa execute un volum mare de operatii care ar putea dura
cateva zeci de secunde (spre exemplu la un upload de fisiere). Daca dupa expirarea timpului scriptul inca se
afla in executie, serverul va intrerupe executia fi va returna o eroare.

<?php
set_time_limit(50); // seteaza limita la 50 secunde
44
set_time_limit(0); // dezactiveaza limita - scriptul poate rula la nesfarsit
?>

Functia flush()

Functia flush trimite catre browser tot ceea ce a fost afisat deja de script. In mod normal, rezultatul unui
script PHP este trimis catre browser pentru afisare doar la finalul executiei intregului script. Aceasta functie
ofera posibilitatea trimiterii catre browser a rezultatului pe parcurs ce acesta este printat in PHP. Asta
inseamna ca pagina poate fi afisata partiala in timp ce inca se incarca.

<?php
echo 'Text 1<br />';
echo 'Text 2<br />';
flush();
?>

Terminarea executiei

Sunt situatii in care se doreste oprirea executiei unui script PHP. Acest lucru este posibil folosind una din
cele doua functii de mai jos.

Testeaza
<?php
exit( "Script terminat" );
die( "Script terminat" );

print "Acesta linie nu se afiseaza niciodata";


?>
Nota: instructiunile die si exit sunt echivalente.

Functii de transformare base64

Functiile de codificare base64 sunt folosite pentru codificarea/decodificarea unui text in si din formatul
Base64.

<?php
$text = 'Tutorial PHP in limba romana';
echo base64_encode($text); // afiseaza VHV0b3JpYWwgUEhQIGluIGxpbWJhIHJvbWFuYQ==
echo base64_decode('VHV0b3JpYWwgUEhQIGluIGxpbWJhIHJvbWFuYQ=='); // Tutorial PHP in
limba romana
?>

Functia phpinfo()

Functia phpinfo ofera informatii despre instalarea PHP curenta si despre serverul pe care aceasta este
executata. Rolul acestei functii este pur informativ; functia nu poate fi folosita intr-un script care are un alt
scop bine definit. De aceea, este recomandata apelarea acestei functii intr-un script PHP separat, intrucat
aceasta creaza o pagina HTML completa.

<?php
phpinfo(); // returneaza o pagina HTML cu informatii despre instalarea PHP
?>

O alta functie, ce poate fi utila in scripturile voastre, este phpversion - aceasta returneaza doar versiunea
curenta a interpretorului PHP. Un exemplu al folosirii acestei functii este mai sus la functia mail.

45
Extensii ale limbajului PHP

Pe langa functiile de baza, limbajul PHP ofera posibilitatea extinderii capacitatilor sale prin folosirea
extensiilor. Extensiile sunt librarii dezvoltate de regula de cei care au creat limbajul PHP si care ofera
functionalitati aditionale, cum ar fi posibilitatea de a manipula anumite tipuri de fisiere (PDF, Excel, Word),
posibilitatea de a crea imagini, de a comunica cu alte aplicatii, etc.

Extensiile cele mai uzuale sunt activate implicit la instalarea interpretorului PHP, dar cele mai multe trebuie
activate manual prin modificarea configurarii PHP. Intrucat in acest tutorial nu vom folosi nici o
functionalitate care sa necesite vreo extensie a PHP-ului, nu vom insista asupra acestora. E bine de stiut doar
ca pentru operatiuni specializate si/sau avansate, sunt sanse mari sa existe o extensie care sa usureze lucrul.

Functii in PHP

Functiile sunt blocuri de cod PHP (secvente de cod) bine delimitate si identificate printr-un nume, ce executa
un set de operatii. Functiile pot fi executate de mai multe ori in cadrul unui script prin simpla apelare a
numelui lor.

Exista functii predefinite, specifice limbajului PHP (cum ar fi print, empty, etc) ce poti fi folosite in orice
moment, fara a fi nevoie de vreo actiune speciala; si exista functii definite de utilizator, scrise practic de
programatori. Pentru ca acestea sa poata fi folosite este nevoie sa fie declarate (si implementate).

Exemplu de functie definita de utilizator:

<?php

# functiile se declara folosind cuvantul cheie "function" urmat de numele functiei


# numele functiei trebuie sa fie orice identificator valid (adica sa inceapa cu
# litere sau cu caracterul _ ) si sa nu contina caractere speciale sau spatiu
# dupa numele functiei se pun paranteze rotunde
# corpul functiei (implementarea) trebuie incadrata in acolade
function afisLuna()
{
$luni = array( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
echo '<select>';
for( $i = 0; $i < 12; $i++ ) {
# intrucat se cunosc nr de pasi, se foloseste structura repetitiva for
echo "<option>{$luni[ $i ]}</option>\n";
}
echo '</select>';
}

# mai jos vom folosi functia pentru a afisa un drop-down cu lunile anului:
echo 'Luna inceperii activitatii: ';
afisLuna();

echo '<br /><br />Luna terminarii activitatii: ';


afisLuna();

?>

Rezultatul codului PHP este reprezentat mai jos:

Luna inceperii activitatii:

Luna terminarii activitatii:

46
Am scris, asadar, o singura data codul care afiseaza lunile anului si l-am apelat de cate ori am avut nevoie.
Apelarea functiei se face prin specificarea numelui urmat de paranteze. Intre paranteze se pot specifica
parametrii, dupa cum vom vedea mai jos. Alternativ, o functie definita de utilizator se poate apela folosind
instructiunea call_user_func

# vom rescrie ultima parte a codului


echo 'Luna inceperii activitatii: ';
call_user_func( 'afisLuna' );

echo '<br /><br />Luna terminarii activitatii: ';


call_user_func( 'afisLuna' );

Instructiunea call_user_func este utila atunci cand numele functiei este furnizat de o variabila, cu ajutorul
caruia se poate apela dinamic o functie. Exemplu:

<?php

# definesc 2 functii diferite


function unu() {
print 'Azi suntem in intai!<br />';
}

function alta() {
print 'Azi e o zi obisnuita<br />';
}

# declar o variabila care sa aiba ca valoare numele functiei


$functie = 'unu';

# variabila $functie poate sa se schimbe in functie de diferite conditii


# in cazul nostru, daca ziua curenta e prima zi din luna, valoarea va fi 'unu'
if( date( 'd' ) == 1 ) $functie = 'unu';
else $functie = 'alta';

# la final apelez dinamic functia data de variabila


# Interpretorul nu stie exact care functie va fi - el doar executa ce-i transmite
variabila

# eventual pot face niste validari:


# - function_exists verifica daca functia transmisa a fost definita
# - is_callable verifica daca variabila transmisa poate fi apelata ca functie

if( function_exists( $functie ) && is_callable( $functie ) ) {


call_user_func( $functie );
} else {
echo "Nu pot apela functia $functie";
}
// Rezultat (live): Azi e o zi obisnuita
?>

Foarte important de stiut este faptul ca variabilele definite in afara functiilor nu sunt disponibile in
interiorul lor. Astfel, codul de mai jos nu va functiona asa cum ne asteptam:

<?php

# declar o variabila
$a = "Afara e frumos";

# definesc o functie

47
function afisMesaj() {
echo $a;
}

# apelez functia
afisMesaj(); // nu va afisa nimic!!

?>

Functia nu va afisa mesajul, asa cum v-ati fi gandit la prima vedere. Asta pentru ca ce este definit in afara
functiei nu este recunoscut in interior. In mod similar, variabilele definite in interiorul unei functii se
pierd si NU sunt disponibile in afara acesteia.

Exista totusi o modalitate prin care variabilele definite in afara unei functii sa fie 'aduse' in interiorul ei:
folosind intructiunea global.

<?php

# declar o variabila
$a = "Afara e frumos";

# definesc o functie
function afisMesaj() {
# folosind cuvantul 'global' ii spun interpretorului PHP ca
# vreau sa folosesc o variabila din afara functiei
global $a;
echo $a;
}

# apelez functia
afisMesaj(); // va afisa Afara e frumos

?>

Daca e nevoie sa se foloseasca mai multe variabile globale in cadrul unei functii, acestea se pot specifica
toate intr-o singura instructiune global:

global $a, $b, $Vector;

De ce sunt folosite functiile?

Printre avantajele folosirii functiilor, se numara:

reutilizarea codului
Spre exemplu, daca este nevoie sa se execute aceeasi secventa de cod in mai multe parti ale unui
programm sau script, pentru a nu se rescrie codul de fiecare data, se defineste o functie care este
apelata de mai multe ori, asa cum am facut in primul exemplu de mai sus

modularizare
Odata cu aparitia functiilor (a subprogramelor, in general) s-a introdus si conceptul de modularizare
care presupune impartirea (spargerea) problemei ce trebuie rezolvata in probleme mai mici. Fiecare
modul problema mai mica reprezinta un subprogram, implementat intr-o functie care contribuie la
rezultatul final.
Spre exemplu, avem o operatie (relativ) complexa: afisarea inbox-ului unui utilizator. Aceasta
problema poate fi impartita in parti mai mici/simple. Pentru fiecare parte s-ar defini cate o functie in
loc sa se scrie un singur script foarte mare, iar la final codul va arata cam in felul urmator:

preluareDateAutentificare();

48
verificareDate();
preluareMesajeInbox();
afisareInbox();

mentinerea usoara a codului si intelegerea mai usoara a logicii aplicatiei sau a scriptului
Acestea sunt urmari imediate ale primelor 2 puncte. Daca scriptul este structurat, impartit in bucati
mai mici, in care aceleasi secvente de cod nu se repeta atunci va fi mai usor si de inteles si de
modificat sau intretinut.

Valori returnate. Parametri

De multe ori este nevoie ca o functie sa returneze o valoare. Majoritatea functiilor predefinite fac lucrul asta;
spre exemplu empty returneaza TRUE sau FALSE in functie de starea si continutul unei variabile transmise
ca parametru.Si functiile definite de utilizator pot returna o valoare, cu ajutorul instructiunii return.
Exemplu:

<?php

function formatareData() {
$rezultat = date( 'd-m-Y' );
return $rezultat;
}

# rezultatul returnat de functie poate fi folosit in diferite moduri:


$azi = formatareData(); // atribuirea rezultatului
print formatareData(); // afisarea rezultatului
formatareData(); // rezultatul nu este folosit - daca functia nu printeaza ceva
// atunci apelul nu are nici un efect vizibil
?>

De asemenea, functiile pot primi date ce pot fi folosite in interiorul lor pentru diverse prelucrari. Aceste date
de intrare sunt transmise sub forma de parametrii.

Pentru ca o functie sa poata primi parametrii, aceasta trebuie sa ii declare intre parantezele rounde, ca in
exemplul de mai jos

<?php

# functia este declarata sa primeasca 2 parametrii ce vor fi prelucrati


# functia returneaza si o valoare, in functie de datele de intrare
function minim($a, $b) {
if( $a < $b ) return $a;
else return $b;
}

# la apelul functiei, este obligatoriu sa se transmita 2 parametrii


# parametrii pot fi orice expresie (variabile, constante, rezultatul altor functii,
etc)

print minim( 3, 4 ); // parametrii sunt 2 valori numerice

$x = 1; $y = 4;
print minim( $x, $y ); // parametrii sunt 2 variabile

$x = 4; $a = 3; $b = 5;
print minim( $x, minim( $a, $b ) ); // parametrii primului apel sunt: variabila $x
// si rezultatul unui alt apel cu 2 parametrii diferiti

?>

49
Nota: intrucat functia minim() returneaza o valoare, ea poate fi folosita ca si cum ar fi un numar normal. De
aceea apelul de mai sus este valid. Alte exemple valide sunt mai jos:

<?php

$a = 1 + minim( 4, 3 );

if( minim( $a, 4 ) > 5 ) { echo "If-ul este True"; }


else { echo "If-ul este False"; }

?>

O facilitate avansata oferita de limbajul PHP este folosirea valorilor predefinite pentru parametrii functiilor.
Aceasta permite ca o functie sa nu fie apelata cu toti parametrii ei, urmand ca pentru valorile care lipsesc sa
fie folosite valorile predefinite. Functia minim() definita mai sus poate fi rescrisa in felul urmator:

<?php

function minim($a = 1, $b = 2) {
if( $a < $b ) return $a;
else return $b;
}

?>

Declararea functiei de mai sus se traduce in felul urmator: daca functia minim() nu este apelata cu toti
parametrii, atunci foloseste valoarea 1 pt $a si valoarea 2 pt $b in calculele din interiorul functiei. In acest
caz, functia se poate apela in felul urmator:

<?php

echo minim(); // echivalent cu echo minim(1,2);


echo minim(7); // echivalent cu echo minim(7,2);
echo minim(7,8); // apel normal cu toti parametrii

?>

Superglobals, variabile speciale

PHP dispune de cateva variabile implicite. Acestea sunt pre-populate de PHP in momentul executiei, deci nu
trebuie definite sau initializate. Sunt disponibile in orice portiune a codului si in orice script PHP si pot fi
folosite fara sa fie nevoie de alte pregatiri. Anumite variabile (ca de exemplu $_POST) au valori doar in
anumite situatii (spre exemplu, doar atunci cand sunt folosite formulare).

Mai jos sunt descrise pe scurt aceste variabile, cu mentiunea ca in lectiile urmatoare vor fi folosite in
exemple din care veti intelege (usor) rostul lor.

$_GET
Vector asociativ ce contine parametrii transmisi prin URL sau printr-un formular. De exemplu, daca
pagina noastra PHP se numeste test.php, un URL de genul

http://localhost/test.php?nume=Alex&varsta=12&ocupatie=elev

ar popula variabila $_GET cu urmatoarele valori:

Testeaza

print_r( $_GET );
50
/* afiseaza:
Array
(
[nume] => Alex
[varsta] => 12
[ocupatie] => elev
)
*/

Nota: numele parametrilor au rol de cheie in vectorul $_GET.


Vectorul $_GET este de asemenea populat la folosirea formularelor GET.

$_POST
Similar cu $_GET, doar ca parametrii sunt transmisi prin formulare (forms) - vezi lectia Formulare
pentru detalii.

$_REQUEST
Inglobeaza atat $_GET cat si $_POST.

$_SESSION
Folosita pentru a defini date ce sunt disponibile atata timp cat utilizatorul acceseaza site-ul, indiferent
de paginile vizualizate. In mod normal o variabila este definita doar cand un utilizator cere o pagina.
La finalul executiei scriptului, valorile variabilelor se pierd (inclusiv variabile $_GET, $_POST, etc).
Daca sunt puse in vectorul $_SESSION, valorile pot persista si dupa terminarea executiei scripturilor.
Vezi lectia Sesiuni pentru detalii.

$_SERVER
Furnizeaza informatii despre server, pagina ceruta si utilizatorul care acceseaza pagina.

Testeaza

print_r( $_SERVER );
/* afiseaza ceva asemanator cu ce e mai jos:
Array
(
[REDIRECT_STATUS] => 200
[HTTP_VIA] =>
[HTTP_COOKIE] =>
[HTTP_REFERER] => http://php.punctsivirgula.ro/
[HTTP_USER_AGENT] => Mozilla/5.0 ...
[HTTP_HOST] => php.punctsivirgula.ro
[HTTP_ACCEPT] =>
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[HTTP_ACCEPT_LANGUAGE] => ro-ro,ro;q=0.8,en-us;q=0.6,en-gb;q=0.4,en;q=0.2
[HTTP_ACCEPT_CHARSET] => UTF-8,*
[HTTP_KEEP_ALIVE] => 300
[HTTP_CACHE_CONTROL] => max-age=0, max-age=0
[HTTP_CONNECTION] => Keep-Alive
[PATH] => /bin:...:/usr/bin:/bin
[SERVER_SIGNATURE] => Apache/2.2.9 (Unix) ... at php.punctsivirgula.ro Port
80
[SERVER_SOFTWARE] => Apache/2.2.9 (Unix) ...
[SERVER_NAME] => php.punctsivirgula.ro
[SERVER_ADDR] => 89.xx.xx.xx
[SERVER_PORT] => 80
[REMOTE_ADDR] => 69.xx.xx.xx
[DOCUMENT_ROOT] => /.../
[SERVER_ADMIN] => webmaster@...
[SCRIPT_FILENAME] => /.../index.php

51
[REMOTE_PORT] => 35423
[REDIRECT_QUERY_STRING] =>
[REDIRECT_URL] => /arrays/
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /arrays/
[SCRIPT_NAME] => /index.php
[PHP_SELF] => /index.php
[REQUEST_TIME] => 1250589158
[argv] => Array()
[argc] => 0
)
*/

$_ENV
Afiseaza informatii despre mediul curent in care este instalat si ruleaza interpretorul PHP, despre
scriptul curent, etc

$_COOKIE
Folosita pentru a vedea elementele de tip Cookies de la site-ul/pagina curenta, disponibile pe
calculatorul utilizatorilor - vezi lectia Cookies pentru detalii.

$_FILES
Folosita la incarcarea fisierelor pe server (file uploads) - vezi lectia File upload pentru mai multe
detalii

Desi toate aceste variabile au si nume alternative, este recomandat sa se foloseasca in forma in care au fost
prezentate mai sus.

Constante predefinite

In PHP exista o serie de constante ce pot fi folosite in orice moment. Ca si in cazul vectorilor superglobali,
acestea sunt populate de catre interpretorul PHP si sunt disponibile in toate fisierele sursa.

PHP_EOL - contine caracterul new-line ce poate fi afisat pentru a formata rezultatul unui script pe
mai multe linii.

echo "Linia 1", PHP_EOL, "Linia 2";


// alternativ se poate folosi \n, desi cele 2 nu sunt mereu echivalente
echo "Linia 1", "\n", "Linia 2";

TRUE, FALSE - constantele de tip boolean ce pot fi folosite la testele din instructiunea if

NULL - referinta nula, utila in "stergerea" unei variabile

PHP_OS - contine identificatorul sistemului de operare pe care ruleaza interpretorul PHP

PHP_VERSION - contine versiunea completa a interpretorului

DEFAULT_INCLUDE_PATH - contine locatiile unde sunt cautate scripturile atunci cand sunt
incluse cu include sau require; de obicei, aceasta constanta contine directorul curent si alte cateva
locatii
52
E_ERROR, E_WARNING si altele - contin codurile diverselor tipuri de erori ce pot sa apara

Exista si alte constante in distributia de baza a PHP, plus multe altele, definite cu fiecare extensie incarcata,
dar nu sunt atat de uzuale ca acestea.

Constante magice

Limbajul PHP dispune de o serie de expresii numite "constante magice" care au valori diferite in functie de
anumiti parametri (cum ar fi momentul si codul-sursa in care sunt folosite). Denumirea de 'constanta' este
improprie, pentru ca, asa cum stiti deja, o constanta nu-si poate schimba valoarea. Nici 'variabile' nu pot fi
numite deoarece nu au nevoie de declarare sau initializare, asa ca s-a recurs la un compromis: denumirea
'constante magice' (magic constants).

Cele mai uzuale sunt __LINE__, __FILE__, __FUNCTION__ si __CLASS__. Mai noile __DIR__, __METHOD__,
__NAMESPACE__ sau __TRAIT__ sunt mai rar folosite datorita faptului ca au nevoie de o versiune mai noua a
interpretorului PHP (cel putin versiunea 5.0 sau chiar 5.4)

Mai jos sunt explicate aceste constante.

LINE
Returneaza linia curenta a scriptului PHP.

Testeaza

<?php
# afiseaza numarul liniei pe care este scrisa instructiunea echo
echo __LINE__; // 187
?>

FILE
Contine calea completa catre scriptul PHP care se executa. Daca este folosita intr-un fisier inclus
atunci numele acestui fisier este returnat.

Testeaza

<?php
# afiseaza numele fisierului executat
echo __FILE__; // numescript.php
?>

FUNCTION
Returneaza numele functie din interiorul careia se foloseste constanta.

Testeaza

<?php
# declar o functie care contine o constanta magica
function spuneNumele() {
echo __FUNCTION__;
}

# apelez functia care va afisa valoarea constantei


spuneNumele(); // va afisa: spuneNumele
?>

53
CLASS
Returneaza numele clasei curente.

DIR
Contine numele directorului in case este salvat scriptul curent. Aceasta constanta este echivalenta cu
dirname(__FILE__).

METHOD
Contine numele metodei de clasa din care se foloseste constanta. Se poate folosi numai cu clase.

NAMESPACE
Contine numele spatiului de lucru curent (name-space).

TRAIT
Contine numele trasaturii curente (trait).

Formulare

Formularele sunt elementele prin intermediul carora utilizatorii trimit date catre server. Pe o pagina web pot
fi introduse diferite tipul de informatii (parole, comentarii, mesaje, etc). Toate aceste date sunt transmise
catre servere prin intermediul formularelor (in engleza "form").

Odata transmise, datele pot fi prelucrare folosind PHP. Astfel, ele pot fi salvate intr-o baza de date, in fisiere,
trimise prin email, sau doar afisate inapoi pe o pagina. In cele ce urmeaza vor fi prezentate elemente de baza
ale folosirii formularelor in PHP. Ca o nota, formularele sunt intalnite in orice aplicatie web (cele mai uzuale
sunt poate paginile de login, contact sau inregistrare). Cert este ca sunt esentiale in folosirea internetului si
este foarte important pentru un programator web sa stie sa foloseasca form-uri in PHP.

Pe scurt, pentru a putea fi introduse date pe o pagina web trebuie sa existe un formular. Acesta se defineste in
HTML prin tag-ul form. Un form trebuie sa aiba specificate obligatoriu 2 atribute: "action" si "method".
Action reprezinta locatia unde vor fi transmise datele, reprezentata prin numele fisierul ce va prelucra
requestul (de regula un fisier PHP). Acest atribut poate fi gol, specificand ca datele vor fi transmise catre
acelasi script ce afiseaza formularul (fisierul curent). Method specifica metoda de acces, dupa cum este
descrisa mai jos.

Formularele sunt strans legate de conceptul de "Metoda de acces" (Request Method). De fapt, in functie de
modul in care se face cerinta catre server, exista doua tipuri de formuri: formulare GET si POST.

Request Methods: GET, POST si altele

Metodele de acces reprezinta modul in care cerintele pentru o pagina web si alte informatii aferente sunt
transmise de la browser la serverul web. Exista 8 metode definite, in schimb doar 2 dintre ele sunt cel mai
des folosite in dezvoltarea paginilor web. Mai multe detalii pot fi citite pe pagina de Wikipedia.

GET
Este cea mai uzuala metoda, folosita implicit de browsere pentru a trimite cereri catre servere.
Majoritatea paginilor pe care le vizualizam pe internet sunt obtinute in urma unei cereri GET. De
exemplu, scrierea unui URL in bara de adrese a browserului sau accesarea unui link, sau a unei
imagini, toate sunt request-uri de tip GET.

Aceasta metoda este utilizata, asadar, pentru a "cere" o pagina de la server (in engleza "get data").
Totusi, odata cu cererea se pot transmite si mici bucati de informatii catre server. Aceste informatii

54
transmise la momentul cererii pot fi date introduse de utilizatori (intr-un form) si sunt adaugate la
finalul URL-ului sub forma "pagina.php?parametru=valoare".

POST
Opus metodei GET, POST este folosita pentru a transmite informatii catre server (in engleza "post
data"). Spre deosebire de GET care permite doar o cantitate limitata de date sa fie transmisa de la
client (browser) la serverul web, POST dispune de limite mai generoase, fiind standardul de
transmitere a datelor. Astfel, upload-ul unui fisier pe server, salvarea unui post pe blog, etc - toate
sunt requesturi de tip POST.

Mai jos sunt descrise cele 2 tipuri de formulare si cum pot fi accesate datele lor in PHP. Apoi, pe pagina
urmatoare, GET vs. POST puteti afla diferentele concrete dintre ele si cum puteti determina ce tip de form sa
folositi pe paginile voastre.

Formulare GET

Acest tip de formulare permite utilizatorilor sa transmita informatii aditionale atunci cand cer o pagina web.
Actiunea unui formular GET poate fi usor reprodusa specificand URL-ul si parametrii direct in browser
(vezi aplicatia de mai jos).

Datele transmise de utilizatori la un request de tip GET sunt disponibile pentru prelucrare in PHP folosind
variabila globala $_GET. Fiecare parametru al requestului reprezinta o componenta a variabilei $_GET.

Aplicatie: sa se preia numele utilizatorului (printr-un formular) si sa se afiseze pe


pagina.

Intr-o prima faza fisierul va cuprinde formularul:

<form id="afiseaza" action="" method="get">


Nume:
<input type="text" name="numele" />
<input type="submit" value="Trimite" />
</form>
Acesta da utilizatorilor posibilitatea sa scrie numele in caseta afisata si sa apese pe butonul "Trimite".

Urmatorul pas este definirea codului care va prelua numele si-l va afisa. Secventa de cod PHP se scrie in
acelasi fisier ca si codul HTML de mai sus. Daca s-ar pune intr-un fisier separat, atunci atributul action al
etichetei form ar trebui sa specifice numele acelui fisier.

<?php
if( isset( $_GET[ 'numele' ] ) && !empty( $_GET[ 'numele' ] ) ) {
print "Salut, {$_GET[ 'numele' ]}!";
}
?>

Formularul, asa cum apare in browser, este disponibil mai jos:

Nume:

Se observa ca atunci cand se foloseste metoda GET, toate elementele formularului (care au specificat un
nume!) apar in URL-ul paginii urmatoare sub forma

pagina.php?element1=valoare1&element2=valoare2

55
Astfel, acelasi efect ca si folosirea formularului s-ar obtine daca s-ar accesa direct pagina cu parametrul

numele=ceva (click pentru test)

Asta confirma faptul ca toate requesturile pe care le facem in mod obisnuit catre un server web sunt de tip
GET (de exemplu cand accesam direct in browser www.google.ro, sau cand facem click pe un link - toate
sunt cerinte GET catre server) - si ca sunt echivalente cu folosirea unui formular GET.

Asadar, fie ca folosim un formular cu metoda GET, fie ca scriem direct in bara de adrese a browserului,
rezultatul este acelasi: un request de tip GET ai carui parametrii ce sunt accesibili in PHP prin vectorul
asociativ $_GET. Dezavantajele metodei GET sunt: cantitatea mica de date ce pot fi transmise (de obicei
parametrii au valori mici, de cateva caractere) si restrictiile ce se impun valorilor parametrilor (acestia
trebuie sa formeze, impreuna cu numele serverului si calea ceruta, un URL valid).

Formulare de tip POST

Un alt tip de request folosit in practica este POST. Acesta permite transferul unei cantitati mult mai mari de
date (de ordinul gigaoctetilor), in timp de metoda GET este limitata la cativa octeti. Astfel, prin POST se pot
transfera fisiere catre web-servere si se pot transmite texte foarte lungi, fara a ne face griji de formatul
datelor transmise (care pot contine caractere speciale, pot fi in format binar).

Datele transmise de utilizator sunt disponibile in PHP prin intermediul variabilei globale $_POST. Astfel,
daca formularul contine 2 campuri numite "numele" si "textfl" (ca in aplicatia urmatoare), variabila $_POST
va avea doua componente ce pot fi accesate prin $_POST[ 'numele'] si $_POST[ 'textfl' ].

Aplicatie: sa se preia numele utilizatorului (printr-un formular) si un text foarte lung.


Sa se afiseze pe pagina numele si lungimea textului.

Continutul fisierului PHP este redat mai jos

<form id="afiseaza2" action="" method="post">


Nume: <br />
<input type="text" name="numele" /> <br />
Text foarte lung: <br />
<textarea name="textfl" rows="3" cols="20"></textarea> <br />
<input type="submit" value="Trimite" />
</form>

<?php
# mai intai verificam daca a fost trimis formularul
if( isset( $_POST ) && !empty( $_POST )) {
# da, a fost trimis; verificam fiecare componenta
if( isset( $_POST[ 'numele' ] ) && !empty( $_POST[ 'numele' ] ) ) {
print "Salut, {$_POST[ 'numele' ]}!<br />";
}
if( isset( $_POST[ 'textfl' ] ) && !empty( $_POST[ 'textfl' ] ) ) {
print "Ai trimis " . strlen( $_POST[ 'textfl' ] ) . " caractere";
}
}
?>

Formularul, asa cum apare in browser, este disponibil mai jos:

Nume:

Text foarte lung:


56
Se observa ca elementele formularului (numele si textfl) nu mai sunt transmise in URL, ci printr-un alt
mecanism. Daca pagina este re-afisata (cu Refresh/F5) browserul va afisa o notificare, cerand confirmarea ca
datele sa fie retrimise. Acest lucru confirma, totodata, ca pagina a fost afisata in urma unui request de tip
POST.

Formulare POST si GET

Asa cum am vazut in lectia anterioara exista 2 tipuri de formulare. Din punctul de vedere al utilizatorului
final (cel care foloseste browser-ul si completeaza formularul pentru a transmite date catre server) metoda
folosita (POST vs. GET) nu conteaza prea mult, in sensul ca modul de transmitere al datelor este transparent.
Din punctul de vedere al celui care construieste formularul si care prelucreaza datele primite pe server
(folosindu-se de un script PHP) exista diferente notabile ce trebuie luate in calcul.

Cum determin ce tip de formular trebuie sa folosesc (GET sau POST)?

Cele 2 tipuri de formulare prezinta fiecare avantaje si dezavantaje. Mai jos sunt prezentate cateva dintre
caracteristicile fiecarui tip. In general, avantajul formularelor POST este acela ca pot manipula cantitati mari
de date iar al formularelor GET ca sunt usor de folosit/retrimis.

GET

1. Datele transmise catre server prin GET apar la finalul URL-ului, asa cum au fost introduse; acest
lucru ar putea fi un dezavantaj cand este vorba de date senzitive, dar ajuta la modificarea usoara a
datelor pentru retrimitere

2. Cantitatea de date GET depinde de lungumea maxima permisa a URL-ului, care in Internet Explorer
este de 2 083 caractere. Asadar prin GET nu se pot transmite prea multe date

3. Rezultatul unui request GET poate fi preluat din cache-ul browser-ului sau al proxy-ului web.
Trebuie ca URL-ul sa fie diferit la fiecare request nou pentru a fi siguri ca datele reale sunt preluate

4. Caracterele speciale pot fi codificate folosind atributul enc-type al formularului; dezavantajul este
ca aceasta codificare va reduce cantitatea de date ce pot fi transmise (ex. 3 caractere japoneze sunt
reprezentate cu ajutorul a 42 caractere normale: %26%2312454%3B%26%2312455%3B
%26%2312502%3B)

5. In PHP, elementele formularului sunt disponibile prin intermediul variabilei globale $_GET (sau prin
$_REQUEST)

POST

1. Cantitatea de date ce poate fi transmisa prin POST poate fi restrictionata doar de catre serverul web,
desi nu exista o limitare reala

57
2. Datele transmise prin POST nu apar in URL si nu pot fi alterate usor, ceea ce ofera un oarecare grad
de securitate

3. In mod implicit, datele preluate prin POST nu sunt puse in cache-ul de la browser sau proxy-server;
astfel folosind aceasta metoda vor fi afisate intotdeauna datele reale

4. Codificarea caracterelor speciale se poate realiza ca si la GET folosind atributul enc-type al


formularului (application/x-www-form-urlencoded); avantajul este ca nu exista limitari de cantitate a
datelor

5. In PHP, elementele formularului sunt disponibile prin intermediul variabilei globale $_POST (sau
prin $_REQUEST)

Pe langa considerentele de mai sus, trebuie avuta in vedere si o recomandare generala: GET ar trebui folosit
pentru operatiile care nu modifica nimic pe server, in timp ce POST ar trebui folosit pentru operatiile
de modificare/actualizare/stergere.

Spre exemplu, atunci cand se face o cautare intr-o baza de date si (doar) se afiseaza niste rezultate, ar trebui
folosit un formular GET. De asemenea, cand se realizeaza verificari ce nu au ca efect modificarea bazei de
date sau a vreunui fisier de pe server, se poate folosi tot GET. Atunci cand, in schimb, trebuie facute
modificari se recomanda folosirea metodei POST.

Mai mult decat atat, pentru a evidentia tendinta de folosire a POST pentru modificari de date, browserele
afiseaza o avertizare cand se incearca reimprospatarea (refresh-ul) paginilor aceesate prin POST. Astfel, se
cere confirmarea utilizatorului ca datele introduse sa fie trimise din nou catre server. Aceasta confirmare este
necesara pentru a evita efectuarea unor tranzactii (cum ar fi plati on-line) de doua sau mai multe ori.

De ce conteaza tipul de formular?

Este important sa se aleaga metoda corecta (POST sau GET) atunci cand:

se realizeaza inserari in baza de date sau modificari pe server

se vor transmite cantitati mari de date

utilizatorii pot sa modifice usor datele transmise (cum ar fi un cuvant de cautat)

utilizatorii trebuie informati/atentionati atunci cand retrimit aceleasi date catre server (NB: la metoda
POST, browser-ul afiseaza o notificare atunci cand se incearca Refresh)

este important ca datele afisate sa nu fie preluate din cache (POST)

Fiecare situatie in care este necesar un formular ar trebui analizata pentru a determina tipul de metoda care
trebuie folosita. In practica metoda POST se foloseste la formulare de inregistrare/login, formulare de
contact sau de plati online, formulare de upload si altele, in timp ce metoda GET este folosita pentru
formulare simple de confirmare, de cautare, de abonare/dezabonare la un newsletter, s.a.

Formular simplu de login in PHP

Mai jos este un exemplu de formular ce poate fi folosit pentru autentificarea (logarea) utilizatorilor.
Deocamdata nu contine decat elementele de baza si verificari simple, tocmai pentru a evidentia modul de
lucru cu formulare in PHP. Codul contine comentarii in care sunt explicati pasii urmariti.

58
In mare, sunt executati urmatorii pasi:

se verifica daca a fost facut submit

Ar putea fi putin derutant faptul ca portiunea de cod PHP se afla in acelasi fisier cu formularul
HTML. Intrebarea fireasca ar fi: "nu se executa prelucrarea datelor cand de fapt trebuie doar sa
afiseze formularul?" sau altfel spus "cum stie serverul cand sa prelucreze datele din formular?".

Ideea este ca acea portiune de cod PHP se executa la fiecare afisare a paginii. De fapt nu toata, ci
doar prima parte. Cand se incarca pagina (in urma unui click sau refresh), pe langa codul HTML
static se returneaza si rezultatul codului PHP. In cazul nostru, codul PHP consta in 2 atribuiri de
variabile si un if mare. Atribuirile se executa mereu (la fiecare afisare), la fel si if-ul, doar ca
rezultatul comparatiilor este adevarat doar atunci cand datele din formular au fost trimise.

Cu alte cuvinte, acel if va fi evaluat true doar cand utilizatorul da submit la formular - deci
prelucrarea datelor se va face doar dupa ce utilizatorul face click pe "Login".

daca nu a fost facut submit, e simplu: pur si simplu afiseaza codul HTML static si ce mai este prin
script (rezultatul va fi un formular).

Dupa ce s-a incarcat pagina, utilizatorul va putea introduce datele in formular si va putea da submit.
Atunci cand se da submit, se face un request POST catre aceeasi pagina si se executa inca o data
codul PHP din cadrul fisierului, de aceasta data insa cu informatiile actualizate

cand se face submit, se intra pe ramura lui if unde se executa mai multe operatii (in cazul nostru
doar 2)

Nota: este foarte important sa se inteleaga mersul lucrurilor, cum este tratata pagina in fiecare situatie si cum
se ajunge sa se execute fiecare portiune de cod. Daca aceste aspecte nu sunt clare nu veti putea scrie
formulare de unii singuri.

Continuand cu explicarea codului, iata care sunt operatiile care se executa:

1. se valideaza datele (se verifica daca au fost introduse valori): if( !isset( $_POST[ 'user' ] ) ...

2. se verifica daca numele de utilizator si parola sunt corecte: if( $erori == 0 ) ...

Daca sunt corecte, atunci se face o redirectionare catre o pagina ce poate fi accesata dupa
autentificare. Redirectionarea se realizeaza folosind etichete HTML, desi exista o modalitate mai
eleganta de a o realiza (dupa cum veti vedea in lectia Headere).

Codul este expus mai jos. Aveti si posibilitatea sa descarcati scriptul (mai jos) si sa-l incercati pe serverul
vostru local.

<?php
# username si parola
$user_corect = 'admin';
$parola_corecta = 'ghiceste-Ma';

# verific daca se acceseaza pagina ca urmare a unui request POST


$mesaj = '';
if( isset( $_POST ) && !empty( $_POST[ 'trimite' ] ) ) {
# nota: se va intra pe ramura aceasta a lui if atunci cand utilizatorul
# face click pe butonul "Login"
# Atunci cand pagina este accesata normal (scriind adresa in browser)
# variabila $_POST este goala
59
$erori = 0;
# validam datele, presupunem ca nu sunt erori si verificam valoarile introduse
if( !isset( $_POST[ 'user' ] ) || strlen( $_POST[ 'user' ] ) == 0 ) {
$mesaj = 'Numele de utilizator nu a fost specificat';
$erori = 1;
} elseif( !isset( $_POST[ 'pass' ] ) || strlen( $_POST[ 'pass' ] ) == 0 ) {
$mesaj = 'Parola nu a fost specificata';
$erori = 1;
}

# daca nu au fost erori, atunci fac prelucrarile


if( $erori == 0 ) {
# pentru acum, vom face o verificare simpla
if( $_POST[ 'user' ] === $user_corect &&
$_POST[ 'pass' ] === $parola_corecta )
{
# login realizat, redirectionez
echo 'Ati fost autentificat. Veti fi redirectionat...';
exit; # nu mai afisez nimic altceva
} else {
# nu s-a facut login
$mesaj = 'Username-ul sau parola sunt gresite';
}
}
}
?>

<html>
<head>
<title>Aplicatie formular: pagina de login - Invata PHP</title>
</head>
<body style="font-family: verdana,sans-serif; font-size: small;">

<form action="" method="post" style="width: 30%">


<fieldset>
<legend>Date de autentificare</legend>
<input type="text" name="user" /> User<br />
<input type="password" name="pass" /> Pass<br />
</fieldset>

<fieldset>
<legend>Actiuni</legend>
<input type="submit" value="Login" name="trimite" />
<input type="reset" value="Curata formular" />
</fieldset>

</form>

<?php
# aici afisam mesajul de eroare, daca avem
if( strlen( $mesaj ) > 0 ) {
echo '<p style="color: red">', $mesaj, '</p>';
}
?>

</body>
</html>

Formularul este disponibil pentru testare aici (click pentru a accesa). Introduceti diferite valori pentru a
verifica functionalitatea, iar in final introduceti datele corecte (admin / ghiceste-Ma).

Descarcati fisierul PHP si incercati-l pe serverul vostru

60
Formulare "in real life" - exemple de site-uri care folosesc formulare

Mai jos sunt incluse o serie de formulare folosite in site-uri live. Veti fi surprinsi poate sa observati ca
majoritatea site-urilor folosesc formulare si ca o mare parte din activitatea de navigare pe internet presupune
folosirea formularelor.

La randul vostru, ca dezvoltatori web, voi insiva veti construi foarte des formulare si veti scrie codul de
prelucrare/manipulare a datelor provenite din formulare.

Exemplele de mai jos nu prezinta decat partea formala, codul HTML al formularelor. Partea de programare
(codul efectiv care face prelucrarea) nu este disponibila, fiind gazduita de fiecare site in parte. Rolul acestor
exemple este de a va da o idee despre cum sunt folosite formularele si cu ce ocazii, ce elemente sunt
intrebuintate si care este comportamentul browserului pentru fiecare tip de formular (GET/POST).

Formular de cautare folosind motorul Bing


<form id="form_bing" action="http://www.bing.com/search" method="get">
Expresie de cautat:<br />
<input type="text" name="q" value="" /> <input type="submit" value="Cauta pe
Bing" />
</form>

Analog se poate construi un formular pentru Google. Practic, trebuie schimbat decat atributul action din
formular (pus URL-ul specific Google: http://www.google.com/search), intrucat cele doua motoare de
cautare accepta acelasi parametru GET (numit simplu q) pentru textul de cautat.

Formularul de cautare este disponibil mai jos:

Expresie de cautat:

Formular de cautare in documentatia PHP


<form id="form_php" action="http://ro.php.net/manual-lookup.php" method="get">
Cauta functia PHP sau un cuvant:<br />
<input type="text" name="pattern" value="" /> <input type="submit"
value="Cauta" />
</form>

La fel ca mai sus, formularul foloseste metoda GET, ceea ce ofera o facilitate: utilizatorul poate introduce
singur, in URL, textul de cautat. Dati Cauta si verificati adresa paginii care se deschide.

Formularul de cautare este disponibil mai jos:

Cauta functia PHP sau un cuvant:

Formular de conversie valutara din EUR in RON


<form id="form_xe" action="http://www.xe.com/ucc/convert.cgi" method="get" >
<fieldset>
61
<legend>Suma de convertit</legend>
<input type="text" name="Amount" value="10" style="width: 100px" />
</fieldset>

<fieldset>
<legend>Moneda</legend>
<input type="text" name="From" value="EUR" style="width: 100px" />
- moneda sursa<br />
<input type="text" name="To" value="RON" style="width: 100px" />
- moneda in care se face conversia<br />
</fieldset>

<fieldset>
<input type="submit" name="image" value="Convertire" />
</fieldset>
</form>

Formularul de conversie este disponibil mai jos:

10 EUR
Suma de convertit Moneda - moneda sursa
RON
- moneda in care se face conversia

Formular de cautare locuri de munca pe site-ul ejobs.ro


<form action="http://www.ejobs.ro/user/searchjobs" id="searchjob" method="post" >
<input type="hidden" value="" name="refine"/>
<input type="hidden" value="" name="allof"/>
<input type="hidden" value="" name="categ"/>
<input type="hidden" value="" name="nivel_cariera"/>

<table cellspacing="0" cellpadding="0" border="0" >


<tr>
<td valign="middle" style="padding-left: 3px;"><span>Locuri de
munca:</span></td>
<td valign="middle" style="padding-left: 9px;" rowspan="5">
<input type="submit" value="Cauta Job >>" name="cauta_job" />
</td>
</tr>

<tr>
<td valign="middle" style="padding-left: 3px;">
<input onclick="if (this.value=='Cuvant cheie')
{this.value='';}"
style="width: 210px;" name="jobskeyword" value="Cuvant cheie"
/>
</td>
</tr>

<tr>
<td valign="middle" style="padding-left: 3px;">
<select style="width: 210px;" name="oras">
<option value="">Toate orasele</option>
</select>
</td>
</tr>

</table>
</form>

62
Acesta este un formular putin mai cuprinzator. Contine mai multe tipuri de elemente, inclusiv de tip ascuns
(hidden). Aceste sunt folosite pentru a transmite anumite informatii care nu trebuie in mod necesar sa fie
accesibile utilizatorilor. Elementele hidden sunt accesibile ca orice alt input, prin intermediul variabilei
$_POST.

Formularul de la eJobs foloseste metoda POST. Ca urmare datele introduse nu apar in URL si nu pot fi
modificate imediat. Mai mult, la refresh pe pagina de rezultate o sa apara acea avertizare care cere
confirmarea ca datele introduse sa fie trimise inca o data la server.

Formularul este disponibil mai jos:

Locuri de munca:
Cuvant cheie

Headere

Headerele sunt elemente prin care browser-ul si serverul web comunica in fundal pentru a afisa o pagina web
in bune conditii.

Exista 2 tipuri de headere: cele emise de browser (headere de request) si cele emise de server (headere de
raspuns).

Request headers

De fiecare data cand un utilizator acceseaza o pagina web, browserul trimite catre server cantitati mici de
date, sub forma request headers (sau, intr-o traducere destul de rar folosita la noi, antetelor de cerere). Aceste
antete cuprind detalii despre pagina care a fost solicitata, modul de transfer a ei, precum si informatii despre
capabilitatile browser-ului.

De exemplu, cand ati accesat aceasta pagina, browser-ul dvs a trimis catre server urmatoarele headere de
request:

GET /http/ HTTP/1.1


Host: php.punctsivirgula.ro
Connection: close
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ro; rv:1.9.1) Gecko/20090624
Firefox/3.5
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
Cache-Control: no
Accept-Language: de,en;q=0.7,en-us;q=0.3

Headerele sunt trimise de browser in mod implicit, utilizatorul nu trebuie sa faca ceva anume pentru asta. De
asemenea, headerele nu pot fi (usor) modificate inainte de a fi trimise.

Response headers

In raspuns la request headers primite de la browsere, serverele web trimit inapoi 2 tipuri de informatie:

63
headere de raspuns (response headers)

continutul efectiv al paginii solicitate (continut ce poate fi construit/modificat prin intermediul PHP)

Headerele de raspuns contin informatii despre pagina solicitata (cum ar fi: daca exista sau nu, dimensiunea
ei, tipul de continut, etc).

De exemplu, in urma solicitarii acestei pagini in browser, serverul nostru a trimis urmatorul raspuns:

HTTP/1.1 200 OK
Date: Fri, 17 Jul 2009 14:54:18 GMT
Server: Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.8b PHP/5.2.6 mod_scgi/1.12
X-Powered-By: PHP/5.2.6
Set-Cookie: PHPSESSID=h8144gj13180725c2aufkrd397; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Ghid PHP pentru incepatori - headere. cookies. modificarea requestului
HTTP</title>
....
</html>

Headerele reprezinta prima parte, separate de continut prin 2 linii goale (reprezentate prin caracterele
\r\n\r\n). Din acest raspuns, browserul "stie" sa interpreteze headerele si sa afiseze in pagina doar
continutul, astfel ca antetele nu vor fi niciodata vizibile utilizatorului final.

La fel ca in cazul antetelor de cerere, cele de raspuns sunt trimise in mod automat de catre server, inainte de
a trimite continutul si nu este nevoie ca programatorul sa intervina. Exista insa situatii cand trebuie ca
anumite antete sa fie modificate. Acest lucru este posibil cu ajutorul limbajului PHP.

PHP ofera posibilitatea modificarii headerelor de raspuns prin intermediul functiei header.

# trimiterea unui semnal (Not-Found, Status OK, etc)


header( 'HTTP/1.0 404 Not Found' ); // spune browserului sa afiseze un mesaj de eroare
header( 'HTTP/1.0 200 OK' ); // anunta ca pagina exista si va fi trimisa catre browser

# redirectionare - "spune" browserului sa "mearga" la alta adresa


header( 'Location: http://www.punctsivirgula.ro/' );

# specificarea tipului paginii ce se va afisa - in urma acestor apeluri, browser-ul va


# astepta alte tipuri de continut decat pagini HTML
header( 'Content-type: application/pdf' ); // browserul va astepta sa fie trimis un PDF
header( 'Content-type: text/css' ); // fisier css

Aplicatie: Sa se redirectioneze un utilizator la o anumita pagina


<?php
# daca este definit un site, fac redirectarea
if( isset( $_GET[ 'site' ] ) ) {

64
# folosesc instructiunea de selectie multiple
switch( $_GET[ 'site' ] ) {
case 'home':
header( 'Location: /');
break; # break este necesar dupa fiecare 'ramura' a lui switch
case 'search':
header( 'Location: http://www.google.ro' );
break;
default: # daca nici una din conditiile de mai sus nu a fost indeplinita
header( 'Location: http://www.punctsivirgula.ro' );
}
exit; # dupa header() trebuie oprita executia scriptului
}
?>

<a href="page.php?site=home">home</a>
<a href="page.php?site=search">home</a>
<a href="page.php?site=bla">other</a>

Important! Inainte de folosirea instructiunii header() nu trebuie sa fie afisat nimic (cu print, echo, sau
scriind cod HTML). Se intampla adesea ca si un spatiu ramas la sfarsitul unui fisier inclus cu include sau
require sa opreasca functia de la a functiona corect. De exemplu, urmatoarele secvente de cod nu sunt valide:

<?php
print "Nu mai pot trimite headere";
header( "Location: http://www.google.ro" );
exit;
?>
<html>
<body>
<?php
header( "Location: /" );
exit;
?>

Aplicatie: Sa se creeze o pagina care ofera spre download un document PDF, in loc sa-l
deschida in browser

Probabil ca multi dintre voi ati observat ca browserele afiseaza documentele PDF sau imaginile direct in
cadrul ferestrei, iar pentru a le descarca trebuie ales in mod explicit optiunea de Save din meniul
browserului. Acest comportament poate fi schimbat prin headere. Daca serverul web i-ar "spune"
browserului ca ceea ce se va transmite trebuie downloadat si nu afisat atunci problema ar fi rezolvata. Sa
creem asadar fisierul download.php

<?php
# pagina download.php va primi ca parametru numele fisierului
# forma unui link va fi urmatoarea: download.php?file=document.pdf

if( isset( $_GET[ 'file' ] ) ) {


# curat calea fisierului pentru a elimina riscurile de atacuri
$_GET[ 'file' ] = preg_replace( '/\.\.\//', '', $_GET[ 'file' ] );

# daca a fost trimis un fisier verific daca exista


if( !is_file( $_GET[ 'file' ] ) ) {
# daca fisierul nu exista, trimit un semnal corespunzator
header( "HTTP/1.0 404 Not Found" ); # timit un mesaj de eroare

print "<html><title>Document inexistent</head>


<body><h1>Documentul nu a fost gasit.</h1>Parametrul
<tt>file</tt> trebuie sa specifice un fisier existent in
folderul curent. Incercati din nou.</body></html>";

65
exit; # opresc executia aici
}

# daca s-a ajuns aici, inseamna ca fisierul exista

# preiau extensia pentru a-i determina tipul


$type = strrchr($_GET[ 'file' ], '.' ); # preiau textul de la ultimul punct la
final
# $type va fi acum ceva de genul ".pdf"
if( strlen( $type ) ) $type = substr( $type, 1 ); # elimin punctul

# in functie de tip, trimit browserului un anumit Content-Type


# este necesar pentru ca browserul sa stie ce tip de fisier va fi descarcat
switch( $type ) {
case 'pdf':
header( 'Content-type: application/pdf' ); // fisierul va fi PDF
break; # break este necesar dupa fiecare 'ramura' a lui switch
case 'gif':
header( 'Content-type: image/gif' );
break;
case 'jpg':
# daca nu specific un break se va executa instructiunea de la
urmatoarea
# ramura 'case'.
# Cu alte cuvinte pentru 'jpg' si 'jpeg' este aceeasi instructiune
case 'jpeg':
header( 'Content-type: image/jpeg' );
break;
case 'html': # fisierul HTML va fi oferit spre download in loc sa fie afisat
header( 'Content-type: text/html' );
break;
case 'php':
header( 'Content-type: application/x-httpd-php' );
break;
/*
aici pot fi definite oricate conditii
*/
default: # daca nici una din conditiile de mai sus nu a fost indeplinita
# afisez ca text
header( 'Content-type: text/plain' );
}

# trimitem headerul prin care "fortam" download-ul. Partea "filename" din


textul
# de mai jos specifica numele sub care va fi propus spre download fisierul
header("Content-Disposition: attachment; filename=\"download.$type\"");

# trimit continutul fisierului de descarcat


readfile( '.'.DIRECTORY_SEPARATOR.'resurse'.DIRECTORY_SEPARATOR.$_GET[ 'file' ]
);
# alternativ de poate folosi
// echo file_get_contents( './resurse/' . $_GET[ 'file' ] );
# nota: se pot specifica doar fisiere din folderul 'resurse', orice incercare
de
# a accessa alte fisiere este blocata

} else {
# nu a fost transmis parametrul file, fac redirect la pagina principala
header( "Location: /" );
}
exit; /* intrerup executia, desi nu e necesar in aceasta situatie fiind deja la
sfarsitul scriptului */
?>
Puteti testa "in actiune" acest cod urmand urmatoarele link-uri:

66
Imagine jpeg - link direct

Imagine jpeg - link de download

Document PDF - link direct

Document PDF - link de download

Descarcati fisierul PHP si incercati-l pe serverul vostru.

Ce sunt Cookies?

Cookies reprezinta portiuni de informatii (stocate sub forma de fisiere de mici dimensiuni) ce se afla pe
calculatorul utilizatorului si care sunt create si folosite de catre browser in comunicarea cu serverul web. De
obicei cookie-urile sunt folosite pentru a identifica utilizatorii sau a pastra urma vizitelor pe un site.
Cookie-urile pot fi sterse cu usurinta de catre utilizator, sau pot fi blocate de catre browser, deci folosirea lor
trebuie facuta cu grija si doar in cazuri de necesitate. Un cookie poate contine o cantitate limitata de
informatie iar durata de viata poate fi limitata (la un anumit numar de zile, la inchiderea sesiunii de lucru,
etc) sau nelimitata (pana la stergerea lor).

PHP dispune de 2 functii prin care se pot crea cookie-uri: setcookie si setrawcookie. Cookie-urile create
pe calculatorul utilizatorului pentru un site sunt transmise de catre browser inapoi la server si sunt
disponibile in variabila globala $_COOKIE.

Cum setez un cookie? Cum vad cookie-urile existente si cum le sterg?

Adaugarea unui cookie pe calculatorul vizitatorului se realizeaza cu ajutorul functiei setcookie. Aceasta va
trimite un header pe care browserul client il va interpreta si va crea cookie-ul. Fiind vorba de headere, se
aplica regula de a nu printa nimic intainte de apelarea functiei setcookie. In cazul in care o instructiune de
afisare a fost apelata inainte, cookie-ul nu va mai putea fi creat.

Pentru a vedea cookie-urile deja create in browser-ul vizitatorului se foloseste variabila predefinita
$_COOKIE. Aceasta este un vector asociativ ce contine un element pentru fiecare cookie existent. Popularea
acestuia se face in mod automat in functie de informatiile transmise de browser.

Nota: elemente de tip cookie se pot crea si la nivel de browser (folosind JavaScript sau un alt limbaj de
client-side scripting). Acestea vor fi disponibile in variabila $_COOKIE la urmatorul request (efectuat,
evident, dupa ce cookie-urile au fost create).

<?php
# crearea unui cookie de test care expira la sfarsitul sesiunii de lucru
setcookie("Test", 'acesta este un test');

# crearea unui cookie care expira intr-o ora


setcookie("Test2", 'o ora', time()+3600);

# vizualizarea cookie-urilor
if( isset( $_COOKIE[ 'Test' ] ) ) {
echo 'Test: ', $_COOKIE[ 'Test' ], '<br>';
}

if( isset( $_COOKIE[ 'Test2' ] ) ) {


echo 'Test2: ', $_COOKIE[ 'Test2' ], '<br>';
}
// Rezultat (e nevoie de refresh prima data)

67
// Test: acesta este un test
// Test2: o ora

# stergerea unui cookie se face printr-un truc: alegand o data de expirare din trecut
setcookie("Test2", 'o ora', time()-3600); // timpul de expirare a trecut, deci cookie-
ul
// nu va mai fi valid si va fi sters de catre browser

?>

Cum verific daca browser-ul utilizatorilor accepta cookie-uri?

Ideea de baza este urmatoarea: se incearca sa se creeze un cookie, apoi se face un redirect la aceeasi pagina
iar in urma redirectului (practic la a doua accesare a paginii) se verifica daca acel cookie a fost creat cu
succes.

Redirect-ul se face folosind headere, deci va fi transparent pentru utilizator, care probabil nici nu va observa
ca a fost redirectionat. Pentru a stii cand se face verificarea cookie-ului, se foloseste un parametru GET ce va
avea valoarea 1 dupa redirect.

<?php

function testCookie() {

# se foloseste variabila globala $_SERVER pentru a prelua numele


# scripului curent (folosit la redirect)
$paginaCurenta = $_SERVER[ 'PHP_SELF' ];

# testez mai intai daca am creat cookie-ul


if( empty( $_GET[ 'creat' ] ) ) {
# este prima data cand accesez pagina
# adaug un cookie de test
setcookie( 'ctest', 'verificare' );

# fac redirect la aceasi pagina si adaug parametrul "creat"


# pentru a putea semnala faptul ca s-a incercat deja crearea cookie-
ului
header( 'Location: ' . $paginaCurenta . '?creat=1' );
exit;
} else {
# se va executa asta atunci cand exista parametrul GET, deci dupa
# redirect, cand cookie-ul a fost deja creat
if( isset( $_COOKIE[ 'ctest' ] ) && !empty( $_COOKIE[ 'ctest' ] ) ) {
return true;
} else {
return false;
}
}

if (testCookie()) print 'Browserul dvs. accepta cookie-uri';


else print 'Ne pare rau dar browserul dvs. nu accepta cookies';

?>

Puteti verifica acest exemplu mergand la pagina cookietest.php. Ca idee de testare, dezactivati cookie-urile
din browser si accesati pagina. Apoi activati-le si face click din nou pe link (nu dati refresh la pagina deja
deschisa intrucat are deja parametrul "creat=1" ceea ce va impiedica scriptul sa creeze cookie-ul din nou).

Descarcati fisierul cookietest.php si incercati-l pe serverul vostru


68
Cum creez un tracking cookie (un cookie care sa retina numarul de vizite pe pagina)?
<?php

# verific daca cookie-ul exista deja si preiau numarul de vizite stocat


$vizite = 0;
if( isset( $_COOKIE[ 'visits' ] ) ) {
$vizite = $_COOKIE[ 'visits' ];
}

# cresc numarul vizitelor cu o unitate


$vizite++;

# actualizez (sau setez) cookie-ul ce va retine nr de vizite


setcookie( 'visits', $vizite, time() * 2 ); // va expira peste mult timp

# afisez un mesaj corespunzator


if( $vizite == 1 ) {
echo "Bun venit! Se pare ca nu ne-ai mai vizitat pana acum!";
} else {
echo "Bine ai revenit. E a $vizite-a oara cand ne vizitezi.";
}
// Rezultat: Bine ai revenit. E a 2-a oara cand ne vizitezi.
?>

Sesiuni in PHP

Sesiunile, reprezinta o functionalitate prin care anumite informatii sunt mentinute de la o pagina la alta. O
sesiune dureaza atat timp cat utilizatorul acceseaza un site si se incheie odata cu inchiderea browserului.

Requesturi stateless si necesitatea sesiunilor

Accesarea unei pagini web este o operatie de sine statatoare (stateless, sau fara stare). Asta inseamna ca orice
accesare ulterioara a aceleiasi pagini (spre exemplu un refresh) se va face fara ca serverul "sa stie" de
accesarile anterioare. La fel se intampla si atunci cand sunt accesate mai multe pagini diferite una dupa alta.

Spre exemplu, daca un utilizator acceseaza pagina a.php si apoi b.php, codul PHP din a doua pagina (b.php)
nu poate sti ce "s-a intamplat" in a.php. Sa luam urmatorul exemplu: in a.php se defineste o variabila ca mai
jos

$text = 'Mesaj din prima pagina';

In b.php exista o bucata de cod care afiseaza variabila $text

echo $text;

Datorita naturii stateless a requesturilor pagina b.php nu va afisa nimic, intrucat variabilele si toate
operatiunile executate in pagina a.php nu se pastreaza de la o cerinta la alta. In mod implicit nu exista nici o
modalitate de a face legatura intre cele doua accesari, si prin urmare informatiile de pe prima pagina
"traiesc" doar in cadrul accesarii paginii respective si se pierd cand executia scriptului din a.php se termina.

Acest design poate ridica probleme, in special in aplicatiile complexe, pentru ca informatiile nu persista de la
o pagina la alta. Este adevarat ca exista cateva moduri prin care mici cantitati de date pot fi transmise catre o
alta pagina - spre exemplu, prin formulare (vezi lectia Formulare in PHP), dar acestea nu sunt viabile pentru

69
aplicatii mari, cum ar fi o aplicatie de email, sau un site e-commerce. Din fericire, PHP ofera posibilitatea de
a persista informatiile pe parcursul navigarii, prin intermediul sesiunilor (sessions).

Sesiuni in PHP

In PHP o sesiune reprezinta perioada de timp in care mai multe scripturi PHP, accesate la momente diferite
de timp, pot stoca si folosi informatii comune. O sesiune incepe atunci cand un script apeleaza functia
session_start si se termina atunci cand utilizatorul inchide browserul (exista si alte modalitati de a porni o
sesiune, dar nu sunt prea uzuale - folosirea comenzii session_start este metoda recomandata).

O sesiune se intinde pe mai multe requesturi (pe parcursul a mai multor accesari ale diferitelor pagini), iar
pentru a identifica existenta unei sesiuni PHP poate folosi cookie-uri sau parametrii GET un URL-ul paginii.

Mecanismul de functionare a sesiunilor in PHP

In momentul in care un script apeleaza functia session_start pentru prima data intr-o sesiune de lucru, se
transmite un cookie catre browserul clientului (un header de tipul 'Set-Cookie', vezi lectia Cookie-uri). Fiind
vorba de un cookie, este necesar ca functia session_start sa fie apelata inaintea oricarei instructiuni ce
afiseaza ceva (print, echo, etc) si inaintea oricarui cod HTML. Cookie-ul transmis contine un identificator ce
poarta numele de Session ID, pe baza caruia se poate face distinctie intre sesiunea curenta si alte sesiuni ale
altor utilizatori ce acceseaza site-ul in acel moment.

In cazul in care browserul utilizatorului nu accepta cookie-uri, identificatorul de sesiune va fi transmis printr-
un parametru GET, in forma script.php?PHPSESSID=[session id] (se va face practic un redirect automat la
aceeasi pagina avand specificat parametrul in URL). Este apoi responsabilitatea programatorului sa includa
manual acest identificator in toate celelalte link-uri de pe pagina, asigurandu-se ca toate paginile vor fi
accesate cu acest parametru. Aceste situatii sunt insa rare, iar in exemplele ce urmeaza vom considera ca
browserele au mereu cookie-urile activate, astfel ca nu va trebui sa avem grija sa transmitem manual Session
ID-ul.

In momentul in care se acceseaza din nou aceeasi pagina, sau o alta din cadrul aceluiasi site, identificatorul
de sesiune este transmis de catre browser (ca orice cookie existent in browser). Astfel, orice script PHP are
acces la Session ID-ul creat initial, fiind capabil sa acceseze sesiunea corecta. Mai este nevoie de ceva insa:
pentru a putea avea acces la informatiile persistate, un script trebuie sa apeleze session_start. De aceasta
data, existand deja un Session ID disponibil, PHP va sti ca nu trebuie creata o sesiune noua ci continuata una
existenta. Asadar, session_start are doua functionalitati: sa porneasca o sesiune noua (atunci cand nu
exista un Session ID) sau sa continue o sesiune existenta, identificata printr-un Session ID.

Functiile principale de manipulare a sesiunii sunt prezentate mai jos. Exista o functie care returneaza Session
ID-ul curent: session_id. Aceasta este utila cand este nevoie ca identificatorul sa fie transmis in URL.
Alternativ se poate folosi constanta globala SID. De asemenea exista o functie pe permite inchiderea unei
sesiuni pe parcursul executiei scriptului curent. Inchiderea sesiunii inseamna oprirea posibilitatii de a
scrie/citi date, nu stergerea datelor salvate deja. Datele raman salvate si pot fi accesate din nou dupa apelarea
functiei session_start.

<?php
session_start();

echo session_id();

echo SID; // are acelasi efect ca instructiunea anterioara

70
session_write_close(); // permite inchiderea sesiunii in scriptul curent
?>

Accesarea datelor

Din momentul in care scriptul PHP apeleaza session_start, acesta poate incepe deja sa stocheze date ce
vor fi persistate. In limbajul programatorilor de PHP se foloseste expresia "sa pastreze date in sesiune" sau
"pe sesiune". Aceste date sunt gestionate de catre limbajul PHP (salvate, preluate, etc) si nu este esential
pentru programator sa cunoasca mecanismul intern de manipulare a acestora. Poate deveni important, totusi,
atunci cand se doreste definirea unui mecanism particularizat de gestionare a sesiunii, dar aceasta reprezinta
o facilitate avansata a limbajului PHP care depaseste nivelul acestor lectii.

Salvarea datelor pe sesiune se face prin intermediul vectorului super-global $_SESSION. Exista si o functie ce
permite inregistrarea datelor pe sesiune (nu si modificarea lor), dar folosirea acesteia nu este recomandata.
Functia se numeste session_register si a fost marcata ca invechita in versiunea 5.3 a limbajului PHP.
Citirea datelor persistate se poate realiza tot prin intermediul $_SESSION.

<?php
session_start();

// inregistrarea datelor in sesiune


$_SESSION[ 'text' ] = 'Mesaj persistat';

// citirea din sesiune


echo $_SESSION[ 'text' ];

// pe sesiune se pot inregistra aproape orice tipuri de date


$vector = array('a', 'b', 'c');
$_SESSION[ 'litere' ] = $vector;

// accesez o parte din vectorul stocat


echo $_SESSION[ 'litere' ][0]; // afiseaza a
echo $_SESSION[ 'litere' ][2]; // afiseaza c
?>

Scrierea si citirea datelor de sesiune se realizeaza practic la fel ca manipularea unui vector asociativ, ceea ce
face aceasta functionalitate usor de folosit.

Aplicatie: sa se transmita o informatie de la o pagina la alta folosind sesiunile PHP

Urmand exemplul de la inceputul paginii, sa construim cele doua fisiere a.php si b.php pentru a putea pastra
textul de la o accesare la alta.
In primul fisier stochez date pe sesiune, urmand ca acestea sa fie citite de pe sesiune in al doilea fisier.

<?php

// a.php
session_start(); // pornesc sesiunea pentru a putea stoca o variabila

$_SESSION[ 'text' ] = 'Mesaj de pe prima pagina';

echo '<a href="b.php">Mergeti la pagina urmatoare</a>';

?>

Dupa accesarea paginii a.php ar trebui sa existe deja o sesiune creata ce are stocata variabila text. Scriptul
din b.php va accesa aceasta sesiune, tot prin session_start si va citi datele inregistrate anterior.

71
<?php

// b.php
session_start(); // continuam o sesiune existenta

echo $_SESSION[ 'text' ]; // afisam informatia

?>

Fisiere in PHP

PHP, ca orice alt limbaj modern de programare, ofera facilitati avansate in lucrul cu fisierele. Astfel, folosind
cod PHP se pot crea, modifica, manipula si sterge fisiere.

Fisiere text si fisiere binare

Fisierele sunt colectii de informatii stocate pe un dispozitiv de stocare (hard-disk, CD, etc). In functie de
formatul datelor continute fisierele se impart in doua categorii: fisiere text si fisiere binare.

Fisierele text sunt cele care contin text simplu ce poate fi citit, reprezentat si modificat de catre oricine si de
catre orice secventa de cod. Spre exemplu, un fisier cu extensia .txt, creat cu un utilitar cum este Notepad,
este cel mai definitoriu tip de fisier text. Un alt exemplu este un cod-sursa PHP salvat intr-un fisier. Desi
codul sursa PHP are o anumita structura si poate fi interpretat intr-un anumit mod, el este la baza un fisier
text, ce poate fi citit de oricine (orice om). De asemenea continutul sau poate fi modificat oricand, fie de un
om, fie de un program.

Fisierele binare sunt acele fisiere ce contin secvente de text intr-un anumit format si cu o structura specifica
inteleasa doar de un calculator (de o anumita secventa de cod). Un exemplu de fisier binar este o imagine
(fisier cu extensia .jpg) sau o melodie (fisier cu extensia .mp3). Desi acestea pot fi vizualizate cu un editor de
texte, ca Notepad, continutul lor nu poate fi modificat de oricine (cel putin nu fara a corupe fisierul).
Fisierele binare sunt utile pentru ca pot contine orice tip de date, cu orice structura se doreste. Avantajul este
ca prin intermediul fisierelor binare si pot crea formate proprietare, care permit modificarea continutului
fisierelor doar de anumite programe. Spre exemplu, fisiere PDF pot fi create/vizualizate doar cu anumite
aplicatii, la fel si documentele Word, s.a.

PHP ofera suport pentru ambele tipuri de fisiere: text si binare. Atat timp cat se cunoaste structura fisierelor
binare (ce tipuri de informatii contin) acestea pot fi modificate din PHP. Cu toate acestea, in cele ce urmeaza
ne vom concentra asupra fisierelor text intrucat sunt cel mai des intalnite si mai usor de folosit.

Folosirea fisierelor in PHP

In orice limbaj de programare, si deci si in PHP, cand se lucreaza cu fisiere trebuie efectuate urmatoarele
operatiuni:

1. deschiderea fisierului

2. citirea din fisier/scrierea in fisier

3. inchiderea fisierului

72
Necesitatea fiecarei operatiuni este probabil usor de inteles. Un fisier trebuie deschis pentru a putea vedea ce
este in el - chiar si pentru o secventa de cod aceasta este o necesitate. Scrierea/citirea propriu-zisa reprezinta
operatia pentru care fisierul a fost deschis, prin care sunt preluate sau adaugate informatii in fisier. La finalul
folosirii fisierului acesta trebuie sa fie inchis, altfel este posibil ca informatiile continute sa se piarda.

Instructiunile PHP corespunzatoare operatiilor de mai sus sunt prezentate in cele ce urmeaza. De remarcat
este faptul ca trebuie specificat inca de la deschiderea fisierului ce fel de operatii vor avea loc: citire, scriere
sau ambele.

<?php

# deschiderea unui fisier si citirea din el


$id_fisier = fopen("c:\\folder\\fisier.txt", 'r'); // deschidere
fread( $id_fisier, 10 ); // citire 10 octeti din fisier
fclose($id_fisier); // inchidere

# deschiderea unui fisier, stergerea continutului si scrierea in el


$id_fisier = fopen("c:\\folder\\fisier.txt", 'w'); // deschidere
fwrite( $id_fisier, 'Text nou in fisier' );
fclose($id_fisier); // inchidere

# deschiderea unui fisier si scrierea la sfarsitul lui


$id_fisier = fopen("c:\\folder\\fisier.txt", 'a'); // deschidere
fwrite( $id_fisier, 'Text adaugat in fisier' );
fclose($id_fisier); // inchidere

?>

Asa cum s-a observat, un mod de deschidere pentru citire ('r') si 2 moduri de deschidere pentru scriere: cu
stergere a continutului vechi (modul 'w') si cu pastrare a continutului (modul 'a'), caz in care scrierea se face
la sfarsitul fisierului, imediat dupa continutul vechi. Depinde de specificul fiecarei situatii ce mod de scriere
trebuie ales.

Limbajul PHP dispune si de alte moduri de deschidere a fisierului, care sunt mici variatii ale celor prezentate
mai sus. Intrucat sunt folosite doar in anumite situatii nu vor fi prezentate aici. Pentru detalii puteti consulta
pagina de documentatie a functiei fopen.

Instructiunile de mai sus pot fi folosite cu orice tip de fisier, text sau binar si reprezinta baza in lucrul cu
fisierele. Exista o suita de alte functii pentru citirea sau scrierea anumitor tipuri de date specifice, ce pot fi
folosite cu ambele tipuri de fisiere. In practica insa, de cele mai multe ori se lucreaza cu instructiuni
"utilitare" de manipulare a fisierelor text - instructiuni care simplifica efortul programatorului in special in
situatii generale. Aceste functii sunt descrise in cele ce urmeaza.

Instructiuni pentru fisiere text

Pentru simplificarea codului de citire/scriere a unui fisier in situatii generale, PHP ofera cateva functii foarte
convenabile: file_get_contents, file_put_contents si file. Primele doua, dupa cum si numele spune,
permit preluarea intregului continut al unui fisier si punerea lui intr-o variabila string, printr-un singur apel,
respectiv crearea unui fisier care sa contina valoarea unei variabile (exemple mai jos). Cea de-a treia functie
permite crearea unui vector ce are ca elemente liniile fisierului specificat. De exemplu, un fisier cu 3 linii va
genera un vector cu 3 elemente, fiecare element reprezentant o linie din fisier.

Este important de mentinut ca odata citit continutul fisierului (cu file_get_contents si file) variabilele
se "deconecteaza" de fisier, adica orice modificare facuta asupra variabilei nu se reflecta si asupra fisierului,
cele 2 entitati fiind separate.
73
<?php

// pun tot continutul fisierului intr-o variabila


$continut = file_get_contents( 'fisier.txt' );

// in acest moment tot continutul este stocat in variabila $continut


// pot procesa continutul sau il pot modifica

// adaug ceva la final


// Nota: modificarea se face doar in variabila $continut, nu si in fisier
$continut = $continut . ' -- Text adaugat de PHP';

// la final salvez variabila $continut intr-un al doilea fisier


file_put_contents( 'fisier2.txt', $continut );

// creea un alt fisier care contine 2 cifre doar


file_put_contents( 'fisier3.txt', '11' );

// din continutul unui fisier creez un vector format din liniile fisierului
$linii = file( 'fisier4.txt' );

echo 'Linia a 3a din fisier este: ', $linii[ 2 ];

?>

Manipularea fisierelor in PHP

Pe langa functiile pentru preluarea/modificarea continutului fisierelor, PHP ofera si facilitati de gestionare a
fisierelor: creare, mutare, copiere, modificare atribute, etc. Cateva din acestea sunt prezentate mai jos.

<?php

// verificare daca un fisier exista


echo file_exists( 'fisier.txt' );

// copiere fisier
copy( 'sursa.txt', 'destinatie.txt' );

// stergere fisier
unlink( 'fisier.txt' );

// redenumire sau mutare


rename( 'vechi.txt', 'nou.txt' );

// afisarea numelui unui fisier


echo basename( "c:\\cale\\catre\\fisier.txt" ); // afiseaza fisier.txt

// afisarea folderului unui fisier


echo dirname( "c:\\cale\\catre\\fisier.txt" ); // afiseaza c:\cale\catre

// afisarea dimensiunii unui fisier in octeti


echo filesize( 'fisier.txt' );

// verificare daca numele specificat este un fisier


echo is_file( "c:\\cale\\catre\\fisier.txt" ); // afiseaza true

// verificare daca un fisier poate fi citit


echo is_readable( 'fisier.txt' );

// verificare daca un fisier poate fi scris/modificat


echo is_writable( 'fisier.txt' );

74
?>

Directoare in PHP

Manipularea directoarelor (folderelor) folosind PHP se face la fel de usor ca in cazul fisierelor. Majoritatea
functiilor folosite pentru fisiere se pot aplica si la foldere (de exemplu copy, rename, is_file, etc), dar
exista o serie de alte instructiuni specifice dosarelor.

<?php

// afiseaza directorul curent (current working directory)


// de obicei este folderul in care se afla scriptul ce se executa
echo getcwd(); // ex. c:\scripturi

// schimba directorul curent


chdir( 'exemple' ); // ex. c:\scripturi\exemple

// returneaza un vector ce contine numele fisierelor si directoarelor dintr-un folder


$vector = scandir( getcwd() );
print_r( $vector );

// verifica daca un element este director (folder)


echo is_dir( "c:\\cale\\fisier.txt" ); // afiseaza false

?>

Limbajul PHP dispune de o serie de functii ce permit citire continutului unui folder intr-un mod similar cu
preluarea continutului unui fisier. Astfel, exista functii pentru deschiderea unui director (opendir), citirea
continutului, adica a fisierelor sau folderelor existente in acel director (readdir) si inchiderea lui
(closedir). O situatie in care aceste functii pot fi folosite este aceea cand se doreste afisarea unei liste a
elementelor continute intr-un folder si se doreste efectuarea unor calcule sau procesari pe baza fiecaruia
dintre aceste elemente.

<?php

$folder = getcwd(); // va lista folderul curent


$handle = opendir( $folder ); // deschid folderul

if ( !empty( $handle ) ) {
echo "Fisiere si directoare:\n";

$terminat = false;
while ($terminat == false) {
$file = readdir($handle); // citesc urmatorul fisier
if( $file === false ) {
// atentie la operatorul de exactitate ===
// daca nu mai sunt alte fisiere/foldere trebuie sa ies din bucla
$terminat = true;
} else {
// aici pot face orice procesare, de exemplu sa redenumesc
fisierul/subdirectorul
// doar afisez numele fisierului/subdirectorului
echo "$file\n";
echo "<br />";
}
}

closedir($handle); // inchei citirea din folder


}
?>

75
Istoricul cautarilor pe un site PHP

In cele ce urmeaza va fi realizata o aplicatie simpla care pastreaza istoricul cautarilor efectuate de utilizatori.
Ideea poate fi extinsa la alte aplicatii similare, de exemplu pentru a pastra istoricul ultimelor pagini vizitate,
al comentariilor recente efectuate, etc. In toate aceste situatii mecanismul de functionare este acelasi, difera
doar ce anume este persistat.

Aplicatia este una simpla si consta intr-un singur fisier PHP. Are la baza formularele, intrucat necesita
transmiterea unor date de la utilizatori catre serverul web. Pentru mai multe informatii despre formulare,
accesati lectia Formulare in PHP.

Mecanismul de functionare

Pentru a persista datele pe parcursul navigarii (de la o afisare a paginii la alta) aceasta aplicatie foloseste
mecanismul de sesiuni.

In PHP, variabilele sunt ne-persistente (stateless). Asta inseamna ca ele exista si au o valoare doar cat timp se
proceseaza scriptul in care sunt definite. La terminarea executiei, valorile se pierd.

Astfel, la o noua procesare a aceluiasi script (spre exemplu la un refresh al paginii, cand codul-sursa se
executa din nou) toate variabilele se reinitializeaza si nu "tin minte" valorile de dinainte. Asta inseamna ca o
navigare printr-un site cu mai multe pagini PHP consta, de fapt, intr-o serie de executii independente ale
scripturilor si, in mod normal, o pagina "nu stie" ce variabile s-au definit la executiile anterioare sau pe alte
pagini accesate.

Acesta este comportamentul implicit. Exista totusi si un mecanism de a persista date de-a lungul navigarii de
la o pagina la alta, iar acest mecanism poarta numele de sesiune. Pentru mai multe informatii despre sesiuni,
accesati lectia Sesiuni in PHP.

In aplicatia noastra, la fiecare accesare a paginii se porneste mecanismul de sesiuni PHP. Atunci cand un
utilizator face submit la formularul de cautare, datele transmise vor fi stocate in sesiune (in vectorul
$_SESSION care este administrat in mod automat de catre interpretorul PHP). Astfel, la o accesare a paginii,
vectorul $_SESSION va contine toate datele adaugate anterior.

In continuare sunt incluse partile mai importante ale aplicatiei.

Formularul de cautare
<form method="post" action="">
Cuvant cheie <input type="text" name="keyword" value="" />
<input type="submit" name="trimite" value="Cauta" />
<input type="reset" value="Curata" />
</form>

Codul PHP de persistare a unei cautari


# pornesc o sesiune

76
session_start();

// ...

# preiau datele existente din sesiune


if( isset( $_SESSION['cautari'] ) ) {
$istoric = $_SESSION['cautari']; // istoric exista
} else {
$istoric = array(); // initializez un vector gol
}

# verific daca a fost facut submit la formular


if( isset($_POST) && !empty($_POST['keyword']) ) {
// adaug termenul cautat
array_push($istoric, $_POST['keyword']);

// stochez totul inapoi pe sesiune


$_SESSION['cautari'] = $istoric;

// e posibil sa fac alte procesari aici


// de exemplu sa afisez lista de rezultate
}

Codul PHP de afisare a istoricului cautarilor


# verific daca exista istoric salvat
if( empty( $istoric ) ) {
echo 'Nu ati cautat nimic pana acum';

} else {

# cum exista deja un istoric, il afisez


echo '<ul>';

# folosesc o structura repetitiva care parcurge vectorul si afiseaza datele lui


foreach($istoric as $termen) {
echo "<li>$termen</li>";
}

# afisez cate elemente exista


echo '</ul><p>', 'Cautari efectuate: ', count( $istoric ), '</p>';
}

Aplicatia este disponibila pentru testare aici (click pentru a accesa). De asemenea, puteti descarca fisierul
PHP si sa il incercati pe serverul vostru local: istoric.php

Incarcarea (copierea) unui fisier de pe calculatorul personal pe server (upload de


fisiere)

Incarcarea unui fisier pe server se face prin intermediul formularelor. Pentru aceasta facilitate se foloseste un
formular putin diferit: are un atribut special (enc-type) si metoda POST. De asemenea, trebuie sa contina un
element input de tip file pentru fiecare fisier incarcat (spre exemplu, daca se incarca 2 fisiere, va fi nevoie
de 2 elemente input).

Pentru ca functionalitatea de upload sa fie functioneze, trebuie indeplinite urmatoarele conditii:

directiva file_uploads din fisierul de configurari al PHP (php.ini) trebuie sa fie 'on'
77
directiva upload_tmp_dir din php.ini trebuie sa se refere la o cale existenta pe server si cu permisiuni
suficiente pentru ca web-serverul sa poata crea fisiere

directivele upload_max_filesize si post_max_size din php.ini specifica marimea maxima a fisierului


si respectiv a datelor ce pot fi transmise prin intermediul formularului; este recomandat ca aceste
valori sa fie revizuite

atributul enctype="multipart/form-data" NU TREBUIE omis, altfel uploadul nu va functiona

Nota: de obicei, interpretorul PHP este configurat deja pentru upload de fisiere, deci primele 3 conditii de
mai sus sunt aproape intotdeauna indeplinite fara a fi nevoie de alte configurari. Acesta este si cazul
pachetului EasyPHP la care incarcarea de fisiere este activata si configurata implicit.

Un exemplu de formular pentru upload de fisiere este mai jos:

<!-- Encoding type, exprimat de atributul enctype, TREBUIE specificat ca mai jos -->
<form enctype="multipart/form-data" action="upload.php" method="POST">
Incarca un fisier: <input name="fisier" type="file" />
<input type="submit" value="Trimite fisier" />
</form>

Nota asupra mecanismului de upload:

atunci cand se face submit la formular, browser-ul web transmite catre server continutul fisierului

serverul web copiaza fisierul transmis intr-o locatie temporara (specificata de directiva
upload_tmp_dir)

interpretorul PHP este invocat, avand variabila $_FILES populata cu informatii despre upload

programatorul este responsabil cu prelucrarea fisierului incarcat pe server (mutare intr-o alta locatie,
citire, copiere, etc); prelucrarea ce se face cu ajutorul functiilor puse la dispozitie de PHP. Daca
fisierul incarcat nu este mutat (sau redenumit) din locatia temporara, acesta va fi sters automat la
terminarea executiei scriptului (la finalul requestului, mai exact).

Fisierul PHP (upload.php) ce va prelucra uploadul contiune urmatoarea secventa de cod (include si validare).

<?php
# se verifica daca fisierul incarcat a depasit dimensiunea maxima acceptata
# daca acest lucru se intampla, variabilele $_POST si $_FILES se golesc automat
if( empty( $_POST ) && empty( $_FILES ) ) {
# a fost facut un POST sau nu?
if( isset( $_SERVER['CONTENT_LENGTH'] ) ) {
# atunci cand se trimit date prin post variabila
$_SERVER['CONTENT_LENGTH']
# contine valoarea dimensiunii datelor
$POST_MAX_SIZE = ini_get('post_max_size');
if( !empty( $POST_MAX_SIZE ) ) {
# determin limita maxima (care poate fi in KB, MB sau GB
$mul = substr($POST_MAX_SIZE, -1);
$mul = ($mul == 'M' ? 1048576 :(
$mul == 'K' ? 1024 :($mul == 'G' ? 1073741824 : 1)));
if ( $_SERVER['CONTENT_LENGTH'] > $mul*(int)$POST_MAX_SIZE &&
$POST_MAX_SIZE ) {
print "Fisier prea mare! Ati depasit limita maxima
permisa";
}
} else {
78
print "Eroare nespecificata (probabil fisierul este prea mare)";
}
} else {
# nu s-a facut inca submit la fisier, afisez un mesaj
print "Apasati pe 'Trimite fisier' pentru a face upload!";
}
} else {
# $_POST si $_FILES sunt setate; verific alte erori ce pot sa apara
if( $_FILES['fisier']['error'] > 0 ) {
print "A intervenit o eroare (#{$_FILES['fisier']['error']})";
} else {
# fisierul uploadat va fi pus in subfolderul 'upload' (care trebuie sa
# existe deja in aceeasi locatie ca si fisierul upload.php
$uploaddir = dirname( __FILE__ ). DIRECTORY_SEPARATOR .
'upload' . DIRECTORY_SEPARATOR;
$uploadfile = $uploaddir . basename($_FILES['fisier']['name']);

if (move_uploaded_file($_FILES['fisier']['tmp_name'], $uploadfile)) {
print "Fisier incarcat cu succes!";
} else {
print "Nu s-a putut incarca fisierul";
}
}
}
?>

Incarcarea mai multor fisiere pe server in acelasi timp (upload de fisiere multiple)

Cand este nevoie sa se incarce mai multe fisiere in acelasi timp, formularul va contine mai multe elemente
de tip INPUT FILE, denumite sub forma unui vector (array):

<form action="" method="post" enctype="multipart/form-data">


<p>Fisiere:
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="submit" value="Incarca" />
</p>
</form>

Codul PHP pentru prelucrarea uploadului trebuie scris in acelasi fisier ca si formularul (intrucat atributul
action nu specifica in mod explicit un fisier PHP).

Nota: acesta este o varianta cu validari minimale.

<?php
# pentru fiecare fisier incarcat, fac o verificare dupa status code
if( !empty( $_FILES ) )
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error > 0) { # echivalent cu ( $_FILES["pictures"]["error"][$key] > 0 )
print "Eroare cu fisierul {$_FILES["pictures"]["tmp_name"][$key]}!";
} else {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
$name = $_FILES["pictures"]["name"][$key];
# mut fisierul din locatia temporara in directorul curent (acelasi
# director in care se afla scriptul PHP)
move_uploaded_file($tmp_name, "$name");
}
}
?>

Site de administrare anunturi


79
In cele ce urmeaza va fi explicat mecanismul de functionare a unei aplicatii in care se pot adauga si vizualiza
anunturi. Aceasta aplicatie are la baza formularele, intrucat necesita transmiterea unor date de la utilizatori
catre serverul web. Pentru mai multe informatii despre formulare, accesati lectia Formulare in PHP.

Pentru a face codul usor de inteles, sunt incluse doar operatiile de baza, fara validari sau prelucrari
aditionale.

In acest exemplu, vom folosi si formularul de login descris in lectia Exemple de formulare. Astfel, in urma
unei autentificari reusite, utilizatorul va fi redirectionat catre pagina principala de anunturi, numita
anunturi.php. Aceasta cuprinde 2 sectiuni: "anunturi existente" si "adaugare anunt".

Sectiunea "Anunturi existente"

In acesta aplicatie simpla, citirea anunturilor existente se face prin intermediul unei functii (citireDate)
definite intr-un fisier separat. Pentru acest exemplu, am ales ca datele sa fie stocate temporar in memorie,
urmand ca mai tarziu sa vedem cum le putem stoca in fisiere sau intr-o baza de date. Pentru scopul acestui
exemplu nu este relevant modul de salvare/citire a datelor, deci nu se va insista asupra acestui aspect.

<?php
// anunturi.php - prima parte

$anunturi = citireDate();

# verific daca exista anunturi salvate


if( !is_array( $anunturi ) || count( $anunturi ) == 0 ) {
echo '<strong style="color: orange">Nu exista anunturi</strong>';

} else {

# cum exista deja anunturi, le afisez


echo '<table width="75%" cellspacing="0" border="1">';

# folosesc o structura repetitiva care parcurge vectorul si afiseaza datele lui


foreach($anunturi as $anunt) {
echo '<tr>';
echo '<td>', $anunt[ 'nume' ], '</td>';
echo '<td>', $anunt[ 'telefon' ], '</td>';
echo '<td>', $anunt[ 'email' ], '</td>';
echo '<td>', $anunt[ 'oras' ], '</td>';
echo '<td width="45%">', $anunt[ 'continut' ], '</td>';
echo '</tr>';
}

# afisez cate anunturi exista


echo '</table><p>', 'Anunturi salvate: ', count( $anunturi ), '</p>';
}
?>

Asa cum se poate observa, se verifica mai intai daca exista date ( count( $anunturi ) == 0 verifica
numarul de elemente din vector). Daca nu exista anunturi, se afiseaza un mesaj specific.
In caz contrar, atunci cand exista anunturi salvate, acestea sunt afisate cu ajutorul structurii repetitive
foreach. Pentru detalii consultati sectiunea de structuri repetitive a site-ului.
In cadrul structurii, este afisat cate un rand de tabel ce contine datele anuntului. La final, sub tabel este afisat
un mesaj cu numarul total de inregistrari gasite.

80
Sectiunea "Adaugare anunt"

Sub lista de anunturi, pe aceeasi pagina este afisat si formularul pentru adaugarea de noi inregistrari. Acesta
este de tip POST, care trimite datele catre fisierul anunturi-post.php. Prin apasarea pe butonul "Salveaza
anuntul", datele introduse vor fi transmise catre fisierul PHP de pe server si vor fi disponibile prin
intermediul variabilei $_POST.

<!-- anunturi.php - a doua parte -->

<form method="post" action="anunturi-post.php">


<input type="text" name="nume" value="" /> Nume contact<br />
<input type="text" name="telefon" value="" /> Telefon contact<br />
<input type="text" name="email" value="" /> Email<br />
<input type="text" name="oras" value="" /> Oras<br />
Continut: <br />
<textarea name="continut" rows="10" cols="50"></textarea><br />

<input type="submit" name="trimite" value="Salveaza anuntul" />


<input type="reset" value="Curata" />
</form>

Fisierul anunturi-post.php

Fisierul PHP care proceseaza datele este inclus mai jos. Ca si in exemplul de login, se fac verificari pentru a
fi siguri ca a fost facut un submit. Daca datele sunt disponibile in variabila $_POST atunci acestea sunt
salvate cu ajutorul functiei scriereDate. Functia de salvare a datelor va returna intotdeauna true (in
aceasta mica aplicatie), deci va fi mereu afisat mesajul de succes.

<?php
// anunturi-post.php

# verific daca a fost facut submit


if( isset( $_POST ) && !empty( $_POST[ 'trimite' ] ) ) {

# salvez datele, apelez functia din anunturi-acces-date-sesiune.php


$rezultat = scriereDate( $_POST );

if( $rezultat ) $mesaj = '<strong>Date salvate cu succes!</strong>';


else $mesaj = '<strong style="color: red">Datele nu au putut fi
salvate</strong>';

} else {

# nu a fost facut post, poate cineva a intrat direct din browser pe aceasta
pagina?
$mesaj = 'Nimic de afisat aici.';
}
?>

Testarea aplicatiei

Aplicatia este disponibila pentru testare aici (click pentru a accesa). Datele de login sunt aceleasi (admin /
ghiceste-Ma).

Puteti descarca fisierele PHP si sa le incercati pe serverul vostru local.

index.php (pagina de login)


81
anunturi.php (fisierul principal)

anunturi-post.php (fisierul de prelucrare a datelor din form)

acces-date.php (fisierul de citire/salvare a datelor)

Descarcati o arhiva cu toate fisierele

Atentie! codul foloseste un mod simplist de verificare a autentificarii, util doar pentru intelegerea codului.
Nu folositi acest tip de verificare intr-o aplicatie reala. Un exemplu de autentificare corect gasiti pe pagina
Formular de login in PHP. Integrarea acestuia cu aplicatia de anunturi ramane ca exercitiu pentru cititori.

Formular complet de login in PHP

In lectia Exemple de formulare a fost prezentat un formular de login simplificat, ce nu poate fi folosit intr-o
aplicatie web reala. Scopul sau a fost de a prezenta pasii executati de interpretorul PHP in cadrul procesului
de login. In cele ce urmeaza va fi prezentat un formular complet de login, cu toate operatiile necesare pentru
a asigura o securitate sporita.

Acest exemplu este unul complex (nivelul de complexitate este mediu-avansat) si reuneste mai multe notiuni
prezentate pe site. Daca nu stapaniti bine urmatoarele lectii, este indicat sa le recititi pentru a va asigura ca
intelegeti codul prezentat.

Formulare

Headere

Cookies

Sesiuni

Mecanismul de functionare

Procedeul de login este acelasi cu cel prezentat in lectia Exemple de formulare; difera doar operatiile
adiacente efectuate dupa login si modul de marcare a utilizatorului ca autentificat.

Astfel, avem un formular simplu ce permite utilizatorilor transmiterea datelor de autentificare si avem o
secventa de cod PHP care verifica datele trimise. Lucrurile se complica atunci cand marcam utilizatorul ca
autentificat si cand verificam accesul, intrucat acest formular permite si pastrarea utilizatorului logat pentru
mai multe zile. In plus, se incearca si respectarea unor norme minime de securitate.

Codul este impartit in mai multe fisiere, prezentate mai jos. Pentru moment, numele de utilizator si parola
sunt aceleasi ca in exemplele precedente. Intrucat scopul acestui exemplu este de a prezenta mecanismul de
functionare a unui formular de login, nu se va insista asupra modului efectiv de verificare a numelui si a
parolei. De aceea, si in acest caz numele de utilizator si parola sunt verificate prin comparatie directa cu
valori specificate direct in cod. Ramane ca exercitiu pentru cititori implementarea unei metode de verificare
a datelor prin consultarea unei baze de date.

82
Formularul de login (login.php)

Asa cum am mentionat, mecanismul general de functionare este acelasi ca la orice formular simplu:

daca datele au fost trimise (daca exista $_POST['...']), se continua cu executarea codului PHP (din
primul if), altfel se afiseaza codul HTML (formularul) de la sfarsitul fisierului;

se fac validari (in cazul acesta concret trebuie doar ca numele si parola sa fie nenule); daca sunt
probleme cu datele trimise se seteaza un mesaj de eroare si se afiseaza codul HTML;

altfel, daca nu sunt probleme cu datele, se cauta un utilizator cu acel nume si acea parola
(checkUserPass);

daca utilizatorul nu a putut fi gasit, se afiseaza codul HTML cu un mesaj de eroare; in caz contrar se
marcheaza utilizatorul ca fiind autentificat (markLoggedIn).

Pe langa acest flux se mai fac alte cateva verificari specifice unei aplicatii de login: se verifica daca
utilizatorul este deja autentificat, se verifica daca utilizatorul a solicitat sa fie deconectat (logout), si altele.
Intrucat acestea nu prezinta interes, nu vor fi discutate, dar le puteti vedea, alaturi de comentariile aferente,
in fisierele sursa ale exemplului (vedeti mai jos).

<?php
/* ... */

// verific daca a fost facut submit


if( isset($_POST['trimite']) ) {

// validez datele
if( empty($_POST['user']) || empty($_POST['pass']) ) {
// setez un mesaj de eroare
$error = getError(ERR_INVALID_DATA);

} else {
// caut user-ul si verific parola
if( checkUserPass($_POST['user'], $_POST['pass']) == null ) {
// setez un mesaj de eroare
$error = getError(ERR_LOGIN_FAILED);
} else {
// daca s-a ajuns aici inseamna ca se poate loga
markLoggedIn();
}
}
}

/* ... */
?>

<html>
<body>

<?php
if(!empty($error)) {
echo '<p class="error">', $error, '</p>';
}
?>

<form action="" method="post" style="width: 30%">


<fieldset>
<legend>Date de autentificare</legend>
<input type="text" name="user" /> User<br />

83
<input type="password" name="pass" /> Pass<br />
<input type="checkbox" name="keep" id="kp" value="1" />
<label for="kp">Pastreaza-ma logat</label><br />
</fieldset>

<fieldset>
<legend>Actiuni</legend>
<input type="submit" value="Login" name="trimite" value="1" />
<input type="reset" value="Curata formular" />
</fieldset>

</form>

</body>
</html>

Portiunea de cod cea mai importanta din acest proces este apelul functiei markLoggedIn care se executa
dupa ce utilizatorul este validat.

Functia markLoggedIn (functii.php)

Aceasta functie este esentiala intrucat ea salveaza pe sesiune informatii despre utilizator: user-ul, IP-ul,
timpul la care s-a logat, ultima accesare a unei pagini, etc. Folosind mecanismul sesiunilor oferit de PHP,
datele raman persistente si disponibile altor pagini, astfel ca se poate verifica la orice accesare daca
utilizatorul este autentificat sau nu.

Mai mult decat atat, este posibila si salvarea unui cookie care sa permita autentificarea automata chiar si
dupa incheierea unei sesiuni PHP (dupa inchiderea browser-ului). Cookie-ul este salvat doar daca utilizatorul
solicita acest lucru.

De mentionat este ca se poate spune in orice moment cum s-a logat un utilizator, in functie de valoarea
elementului 'via' ($_SESSION['LOGIN']['via']). Initial acesta are valoarea 'form', intrucat prima logare va
fi prin intermediul formularului, dar la autentificarea automata prin cookie acesta va avea o alta valoare. De
ce este util acest lucru? In functie de specificul aplicatiei, se pot implementa masuri de siguranta aditionale,
cum ar fi solicitarea utilizatorilor logati prin cookie sa introduca parola atunci cand fac operatiuni senzitive.

Corpul functiei este prezentat mai jos.

# definesc functia care marcheaza utilizatorul ca autentificat


function markLoggedIn() {
$username = $_POST['user']; // user-ul din formular
$keep = $_POST['keep']; // checkbox-ul din formular
$ip = $_SERVER[ 'REMOTE_ADDR' ]; // ip-ul vizitatorului
$via = 'form'; // s-a logat prin formular, nu prin cookie

// creez o structura de date


$data = array();
$data[ 'loggedIn' ] = true;
$data[ 'username' ] = $username;
$data[ 'loginDate' ] = time();
$data[ 'lastAccess' ] = time();
$data[ 'keepLoggedIn' ] = $keep;
$data[ 'ip' ] = $ip;
$data[ 'via' ] = $via;

// pastrez in sesiune
$_SESSION[ 'LOGIN' ] = $data;

84
// daca trebuie sa tin minte loginul, creez un cookie
if( $keep == 1 ) {
/* setez un cookie ce contine structura creata mai sus si care
* va expira in 30 de zile; structura de date este serializata
* adica transformata intr-un format ce poate fi stocat ca text
* dupa serializare, textul returnat este encodat cu algoritmul
* base64 la care se adauga caracterul '1' pentru a ingreuna
* decodificarea continutului */
setcookie( 'logindata', '1' . base64_encode( serialize( $data ) ),
time() + 2592000, '/' );

} else {
// sterg cookie-ul prin setarea valabilitatii la o data din trecut
setcookie( 'logindata', "", time() - 36000, '/' );
}

// acum ca am salvat datele pe sesiune (si posibil in cookies), redirectionez


header('Location: index.php');

// opresc executia scriptului curent


exit;
}

Se observa ca, odata ce datele au fost puse pe sesiune, se face o redirectionare catre o alta pagina. Acest
lucru este lesne de inteles - logarea tocmai s-a realizat cu succes, deci nu are nici un rost sa mai fie afisat
formularul de login. Redirectionarea se face prin transmiterea unui header si oprirea executiei scriptului
PHP.

Pagina protejata (index.php)

Fisierul index.php, cel care este afisat imediat dupa login, ca de altfel orice alta pagina ce poate fi accesata
doar dupa autentificare, trebuie sa verifice starea utilizatorului. Astfel, o pagina protejata va verifica daca
utilizatorul este autentificat, inainte de a afisa orice informatie. In exemplul nostru, verificarea se face
apeland functia checkLogin, ca mai jos.

<?php
# aceasta este o pagina protejata, deci inainte sa afisez orice, vom
# verifica daca vizita provine de la un utilizator logat
checkLogin();
?>

<!-- continutul paginii trebuie pus dupa verificare -->

Functia checkLogin (functii.php)

Aceasta functie verifica daca utilizatorul care acceseaza pagina este deja autentificat sau se poate loga
automat prin intermediul cookie-urilor. Verificarea se face cu ajutorul unei functii utilitare, getAuthCode, iar
in cazul in care rezultatul este negativ se va redirectiona catre pagina de login. In acest mod, utilizatorii
neautentificati nu vor putea accesa o pagina protejata.

Functia getAuthCode este cea care face verificarea propriu-zisa. Aceasta cauta mai intai date pe sesiune
pentru a vedea daca utilizatorul este deja logat, apoi verifica daca exista un cookie valid ce poate permite
autentificarea. Codul complet este prezentat mai jos.

# definesc o functie ajutatoare care face redirect la pagina de login


function checkLogin() {
// daca nu e logat il redirectionez la pagina de login
if(getAuthCode() != 0) {
// nu este autentificat, fac redirect specificand codul erorii
85
header('Location: login.php?error=' . ERR_MUST_LOGIN);

// opresc executia scriptului curent


exit;
}
}

# definesc functia care verifica daca utilizatorul este autentificat


function getAuthCode() {
$error = 0;

// mai intai verific daca in sesiunea curenta utilizatorul e logat


if( isset($_SESSION[ 'LOGIN' ]) ) {
$data = $_SESSION[ 'LOGIN' ];

// exista date pe sesiune, le verific


if( empty($data) || empty($data['loggedIn']) ) {
// datele sunt goale
$error = ERR_MUST_LOGIN;

} else {
// verific ip-ul
if( $data['ip'] != $_SERVER[ 'REMOTE_ADDR' ] ) {
// ip-ul e diferit, probabil e un atac
// in orice caz, marchez ca nelogat
$error = ERR_MUST_LOGIN;

} else {
// daca nu este marcat ca 'pastreaza-ma logat' verific
timpul
// ultimului acces si il deloghez daca a fost inactiv
prea mult
$elapsed = time() - $data['lastAccess'];

if( empty($data['keepLoggedIn']) && $elapsed >


LOGIN_TIMEOUT ) {
// il deloghez cu un mesaj de eroare
markLoggedOut(ERR_TIMEOUT);
}

// daca am ajuns aici inseamna ca este logat


$error = 0;

}
}

} else if( isset($_COOKIE['logindata']) ) {

// nu exista date pe sesiune, dar exista un cookie


// din textul cookie-ului elimin primul caracter de control
// apoi decodific folosind algoritmul base64
$formaSerializata = base64_decode(substr($_COOKIE['logindata'], 1));

if( $formaSerializata === false ) {


// continutul cookie-ului e invalid
$error = ERR_MUST_LOGIN;

} else {
// reconstruiesc structura de date plecand de la forma
serializata
$data = unserialize( $formaSerializata );

if( empty($data) || !is_array($data)) {


// datele sunt invalide
$error = ERR_MUST_LOGIN;
86
} else if( $data['ip'] != $_SERVER[ 'REMOTE_ADDR' ] ) {
// ip-ul e diferit, probabil e un atac
// in orice caz, marchez ca nelogat
$error = ERR_MUST_LOGIN;

} else {
// daca am ajuns aici inseamna ca este logat
$error = 0;

// marchez ca este logat prin cookie


$data['via'] = 'cookie';

// pun datele pe sesiune


$_SESSION[ 'LOGIN' ] = $data;
}
}

} else {
// nu sunt logat, marchez sesiunea ca fiind not-logged-in
$_SESSION[ 'LOGIN' ] = array('loggedIn' => false);
$error = ERR_MUST_LOGIN;
}

// daca este logat, actualizez data ultimei accesari


if( $error == 0 ) {
$_SESSION[ 'LOGIN' ]['lastAccess'] = time();
}

return $error;
}

Este foarte important ca toate paginile protejate sa apeleze functia checkLogin (si, implicit, getAuthCode),
atat penru a proteja continutul de utilizatori neautentificati, cat si pentru a actualiza componenta 'lastAccess'
salvata pe sesiune. Atunci cand un utilizator logat nu solicita sa ramana autentificat (deci nu se salveaza
cookie-ul), la fiecare noua accesare a unei pagini, se verifica daca intervalul de timp dintre ultimele doua
accesari a depasit o limita stabilita, caz in care este deconectat pentru inactivitate. Trebuie, asadar, ca ora
ultimei accesari sa fie actualizata de-a lungul navigarii utilizatorului, iar acest lucru se face in functia
getAuthCode.

Functia markLoggedOut este care care face deconectarea; concret, sterge toate datele de pe sesiune si cookie-
ul de login (continutul functiei se gaseste in fisierul functii.php disponibil pentru download mai jos).

Testarea formularului de login

Aplicatia este disponibila pentru testare aici (click pentru a accesa). Datele corecte de login sunt aceleasi ca
la celelalte exemple de pe site: admin / ghiceste-Ma.

Daca doriti sa incercati fisierele pe serverul vostru local, le puteti descarca de mai jos.

index.php (pagina de pornire)

index-home.php (pagina personala)

login.php (pagina de login)

config.php (fisier de configurari)


87
functii.php (fisierul ce contine diverse functii ajutatoare)

Descarcati o arhiva cu toate fisierele

Editoare PHP

Intrucat sintaxa limbajului PHP este relativ simpla, iar structura codului sursa nu este una impusa, codul PHP
poate fi scris cu orice editor text, cum ar fi Notepad. In realitate, acest lucru este posibil doar pentru
scripturile de cateva linii de cod; pentru fisiere mari si complexe, un editor PHP specializat este aproape
indispensabil.

Exista mai multe editoare de cod-sursa ce pot fi folosite pentru PHP, de la IDE-uri complexe pana la editoare
simple. Toate ofera highlight pentru cuvintele cheie, completare automata a instructiunilor, facilitati avansate
de cautare si altele. Puteti folosi pe oricare dintre ele, in functie de nevoile voastre.

Eclipse pentru PHP

Eclipse este o platforma integrata de dezvoltare (IDE) extensibila, ce dispune de o multitudine de


functionalitati. Folosita initial pentru dezvoltarea in limbajul Java, a fost ulterior extinsa si la alte limbaje de
programare.

Eclipse PDT (Eclipse PHP Development Tools) reprezinta la ora actuala cel mai avansat editor PHP. Este
gratuit si poate rula pe orice sistem de operare. Mai multe informatii pot fi gasite pe site-ul proiectului
Eclipse PDT.

Instructiuni de instalare Eclipse PDT

Instalati Java pe calculatorul personal, daca nu il aveti deja. Platforma Java este necesara pentru a
rula Eclipse.

Descarcati pachetul Eclipse pentru PHP de la pagina


http://www.zend.com/en/community/pdt/downloads si dezarhivati-l in locatia dorita.

Rulati executabilul Eclipse.

La pornire alegeti o locatie unde vor fi salvate toate fisierele PHP. Este indicat ca aceasta locatie sa
fie in Document Root-ul serverului web (de exemplu C:\Program Files\EasyPHP-xx\www).

Dupa pornirea editorului Eclipse, alegeti din meniul Window optiunea Open Perspective, apoi Other.
Selectati PHP.

Dupa aparitia interfetei pentru PHP puteti incepe sa creati scripturile PHP.

Editorul Eclipse este centrat pe ideea de proiect. Un proiect reprezinta o suita de mai multe fisiere PHP,
grupate in acelasi director. Este indicat sa creati un proiect nou pentru fiecare lectie de PHP de pe site, in
care puteti salva mai multe scripturi diferite.

88
Pentru a crea un proiect nou, alegeti din meniul File optiunea New, apoi Other. Din categoria PHP alegeti
PHP Project si completati detaliile. Odata creat proiectul, puteti adauga scripturi noi (din File, New, PHP
File). Puteti vedea unde este salvat pe disc un fisier accesand proprietatile lui (click-dreapta, Properties).

Nota: pentru a putea accesa prin localhost scripturile create cu Eclipse, este necesar ca acestea sa fie salvate
in document root.

Netbeans

Netbeans vine din aceeasi zona a programarii in Java. Este un IDE complet ce a fost extins recent pentru
lucrul in PHP. Ca si Eclipse poate fi folosit pe orice sistem de operare intrucat ruleaza pe platforma Java.
Poate fi descarcat gratuit de la http://netbeans.org/downloads/ (alegeti pachetul PHP).

Modul de lucru in Netbeans este similar cu cel din Eclipse. Avem si aici conceptul de proiect iar pentru a
putea crea scripturi PHP este nevoie sa creati in prealabil un proiect de tip PHP. Toate celelalte observatii
facute la editorul Eclipse raman valabile si aici.

Zend Studio si Adobe Dreamweaver

Zend Studio si Adobe Dreamweaver sunt doua IDE-uri comerciale pentru programarea in PHP. Zend Studio
este bazat pe Eclipse PDT si specializat doar pe dezvoltarea in PHP, pe cand Adobe Dreamweaver poate fi
folosit si pentru web-design. Ambele editoare pot fi descarcate pentru teste (trial version), dar pentru a
continua folosirea lor trebuie achizitonata o licenta.

Editoare simple

Pe langa IDE-urile de mai sus, exista o suita de editoare text simple, gratuite, ce ofera suport pentru
programarea in PHP. Nu sunt la fel de avansate ca Eclipse sau Netbeans, dar au suficiente facilitati pentru a
putea fi folosite cu succes zi de zi pentru a scrie cod-sursa in PHP.

Cele mai cunoscute dintre acestea sunt:

Notepad++ (Windows)

PsPad (Windows)

SciTE (Windows si Linux)

Crimson Editor (Windows)

Pentru incepatori un editor PHP simplu este de cele mai multe ori alegerea ideala, datorita simplitatii
modului de lucru si a interfetei grafice. Un IDE avansat poate avea mai multe facilitati, dar deprinderea cu
folosirea lui poate lua ceva timp. In schimb, la majoritatea editoarelor simple nu exista conceptul de proiect
si se lucreaza direct cu fisiere simple ce pot fi grupate manual in directoare.

89
Codul PHP, ca de altfel orice cod-sursa scris in alte limbaje de programare, poate fi avea o multitudine de
forme, in functie de stilul de programare al fiecaruia. Pentru a face acest cod usor de citit si de inteles, este
foarte important sa se respecte o serie de conventii.

Scrierea de cod clar si care sa respecte standarde bine-cunoscute este benefica atat pentru autorul codului (in
special atunci cand va trebui sa opereze modificari), cat si pentru alti programatori care vor avea acces la cod
(programatorii noi vor intelege mai usor un cod-sursa scris bine).

Mai jos sunt prezentate cateva din cele mai uzuale conventii respectate de o mare parte a programatorilor.

Organizarea codului PHP

Este general acceptat ca organizarea codului in mai multe fisiere si directoare este primul pas in a avea un
proiect usor de mentinut si de modificat. Unele limbaje de programare, cum este Java, impun reguli stricte
referitoare la plasarea fisierelor sursa in directoare. In PHP insa, nu exista restrictii iar programatorii sunt
liberi sa-si organizeze codul cum vor. Aceasta libertate poate avea insa si dezavantaje: permite anumitor
programatori sa construiasca proiecte neingrijite.

De aceea este nevoie sa fie respectate cateva reguli legate de organizarea codului.

Mai multe fisiere sursa

Separati codul PHP in mai multe fisiere, in functie de ceea ce face fiecare portiune de cod. Folositi cat de
multe fisiere auxiliare aveti nevoie - este mai bine ca un fisier sa fie concis, sa contina cod putin si usor de
citit, decat sa aiba sute de linii de cod greu de urmarit. Mai mult, numele fisierelor trebuie sa fie sugestive si
conforme cu destinatia acestora.

Exemplu de fisiere ce pot exista intr-un proiect:

config.php - contine configurari, definiri de constante sau variabile globale

auth.php - verificari de acces, autentificare si altele

db.php - ofera acces la baza de date

util.php - defineste functii utilitare

search.php - defineste functii de cautare

log.php - defineste functii pentru loguri

index.php - fisier principal ce le include pe toate celelalte

Aceasta lista nu este nici completa, nici restrictiva; in functie de proiect, fiecare isi poate defini oricate
fisiere crede de cuviinta. Important este ca ele sa fie justificate iar codul continut sa aiba legatura cu
destinatia lor (spre exemplu, nu ar fi tocmai potrivit ca o functie de cautare in baza de date sa fie scrisa in
fisierul config.php).

90
Gruparea in directoare

Odata cu crearea mai multor fisiere apare si nevoia de a le grupa in mai multe foldere in functie de destinatia
lor. Este mai usor de gasit un fisier si de inteles destinatia acestuia atunci cand face parte dintr-un director cu
un nume sugestiv.

Exemplu de structura a directoarelor dintr-un proiect PHP:

config/
|- site.php
|- db.php
utils/
|- auth.pgp
|- db.php
|- util.php
|- log.php
|- search.php
pages/
|- about.php
|- portfolio.php
|- contact.php
|- search.php
admin/
|- users.php
|- posts.php
data/
|- portfolio.xml
|- products.xml
resources/
|- site.css
|- logo.png
|- favicon.png
index.php

Separarea fisierelor PHP de alte resurse

In exemplul de mai sus se poate vedea ca exista foldere separate pentru fisiere non-PHP. Este important ca
toate aceste fisiere sa nu fie puse in aceleasi directoare cu fisierele PHP din mai multe considerente:
organizare, securitate, flexibilitate in configurarea serverului web, etc. Incercati pe cat posibil sa tineti
fisierele sursa separate de alte resurse statice.

Formatarea codului sursa

Un factor decisiv care poate face diferenta intre un cod-sursa clar si un cod-sursa greu de inteles il reprezinta
stilul de programare. Este adevarat ca fiecare programator are propriul stil de a scrie cod, dar respectand
regulile general-acceptate de formatare a codului, atunci riscul de a scrie cod prost si chiar de a face greseli
scade considerabil.

Exista mai multe conventii referitoare la forma codului sursa, iar cele mai intalnite sunt prezentate mai jos.

Identificatori

Identificatorii se refera la numele variabilelor, constantelor, functiilor si alt altor elemente definite de
utilizator. Folosirea unei strategii consecvente de alegere a numelor face codul mai lizibil si reduce riscul de
a introduce erori, de aceea este de evitat folosirea diferitelor tipare in cadrul aceluiasi proiect.

In functie de tipul de identificator, exista conventii diferite.


91
Variabilele. Identificatorii de variabile vor incepe intotdeauna cu litera mica si vor fi reprezentativi
pentru ceea ce reprezinta variabila (de exemplu: $varsta, $total, $suma si nu $v, $t sau $s).
Numele scurte, de o litera, sunt acceptate doar in cazul iteratiilor ($i, $j, $k), doar ca variabila
temporara ce reprezinta lungimea unui sir ($n, $m) si doar pentru a exprima exceptiile ($e). In cazul
in care numele variabilei este format din mai multe cuvinte, este indicat ca aceasta sa adopte forma
"Camel case": $sumaMaxima, $numeleUtilizatoruluiLogat, $fisierulCeVaFiSters, etc. Sunt
intalnite si formele de separare prin underscore, dar nu sunt indicate deoarece fac numele sa fie mai
lungi: $numar_de_copii, $versiune_browser, etc.

Constantele. Identificatorii constantelor sunt scrisi doar cu majuscule iar partile componente se
separa prin underscore: MARIME_FISIER, NUMAR_MAXIM_PERMIS, NUME_SITE, etc.

Functiile. Identificatorii de functii urmeaza aceleasi reguli ca cei de variabile.

Clasele si interfetele. Identificatorii de clase urmeaza aceleasi reguli ca cei de variabile, cu diferenta
ca prima litera este tot timpul majuscula. Exemple de nume de clase: Categorie, Produs,
FacturaProforma, etc.

Identare

Toate liniile din interiorul unui bloc trebuie identate cu un tab in plus fata de identarea curenta. Acest lucru
ajuta la identificarea usoara a instructiunilor care fac parte din blocul respectiv si fac codul mai lizibil.

Exemplu de cod-sursa cu identare (recomandat):

if($conditie) {
echo "Tutorial PHP in limba romana";
$var = 1;
if($altaConditie) {
echo "Tutorial PHP";
} else {
echo "Ghid PHP";
}
} else {
exit;
}

Exemplu de cod-sursa fara identare (nerecomandat):

if($conditie) {
echo "Tutorial PHP in limba romana";
$var = 1;
if($altaConditie) {
echo "Tutorial PHP";
} else {
echo "Ghid PHP";
}
} else {
exit;
}

Paranteze

Exista situatii cand folosirea parantezelor nu este obligatorie, dar cu toate acestea, este recomandat ca
acestea sa fie folosite chiar si acolo unde nu sunt necesare, pentru a spori lizibilitatea. Mai mult decat atat,

92
folosirea acoladelor la instructiunea if elimina confuziile legate de ce instructiuni se executa pe fiecare
ramura.

Exemplu de situatie unde folosirea parantezelor rotunde ajuta la marirea lizibilitatii codului:

// recomandat
$a = ($b = 2);
$x = (isset($varsta) ? ($varsta + 18) : 18);
if( ($a > 1) && ($b > 2) && ($c == 3) ) {
echo "Tutorial PHP";
}

// nerecomandat
$a = $b = 2;
$x = isset($varsta) ? $varsta + 18 : 18;
if( $a > 1 && $b > 2 && $c == 3 ) {
echo "Tutorial PHP";
}

Spatii albe si linii noi

In limbajul PHP spatiile albe si randurile libere nu influenteaza evaluarea codului. Astfel pot fi inserate
oricate spatii sau linii noi in codul sursa pentru a-l face mai usor de urmarit si inteles. Folosirea lor tine de
fiecare programator, dar o recomandare uzuala este ca elementele unei expresii compuse sa fie separate
printr-un spatiu alb, iar instructiunile care fac lucruri diferite sa fie separate prin randuri noi.

Exemplu de folosire a spatiilor in expresii:

// recomandat
$a = $n - 1;
if( ($a > 1) && ($b > 2) && ($c == 3) ) {
echo "Tutorial PHP";
}

// nerecomandat
$a=$n-1;
if(($a>1)&&($b>2)&&($c==3)){
echo "Tutorial PHP";
}

Exemplu de folosire a liniilor noi:

echo "php.punctsivirgula.ro - "


echo "Tutorial PHP"

// randul nou separa instructiunile echo de instructiunea if


if( isset($limba) ) {
echo " in limba romana";
}

Lungimea liniilor

Pentru a mentine codul sursa vizibil pe toate tipurile de monitoare este indicat ca liniile sa nu depaseasca 80
de caractere. Orice linie mai lunga de aceasta limita va deveni greu de urmarit.

93
Instructiuni de control

Partile componente ale instructiunilor de control if-else, while si do-while, trebuie scrise pe linii
diferite, chiar si atunci cand contin doar o instructiune. De asemenea folosirea acoladelor este incurajata
pentru ca reduce riscul de a introduce erori in cod.

// recomandat
if($conditie) {
echo 'True';
} else {
echo 'False';
}

while($i > 0) {
echo $i++;
}

// nerecomandat
if($conditie) echo 'True'; else echo 'False';

while($i>0) echo $i++;

Comentarii

Comentariile ce contin explicatii scurte si care se intind pe cel mult o linie sau doua pot fi delimitate de //
sau #. Acestea sunt de obicei folosite pentru a descrie destinatia unei variabile sau actiunea instructiunilor
imediat urmatoare. Comentariile mai elaborate ce descrie un algoritm sau o procedura trebuie delimitate de
/* si */.

Este recomandat ca toate comentariile sa fie scrise, pe cat posibil, pe randuri noi si nu la sfarsitul
instructiunilor sau in interiorul lor.

// recomandat

// datele din formular


$date = $_POST['email'];

// validam datele introduce se utilizator


if( !empty($date) ) {
echo 'Valid';
}

// nerecomandat

$date = $_POST['email']; // datele din formular


if( !empty($date) ) { // validam datele introduce se utilizator
echo 'Valid';
}

Comentariile sunt utile in orice portiune a codului sursa si este chiar indicat sa fie folosite ori de cate ori este
nevoie. Trebuie evitate insa comentariile inutile ce nu aduc nici o informatie noua sau care sunt folosite
pentru a descrie o constructie evidenta.

Exemple de comentarii inutile:

// initializam variabila
$a = 1;

94
// verificam daca $a este definita
if(isset($a)) {
// afisam $a
echo $a
}

Practici de programare web

Mai jos sunt prezentate cateva practici utile oricarui programator sau dezvoltator web.

Descrierea codului

Scrieti cat mai multe comentarii in care sa explicati ce anume va executa codul sursa. O practica utila este ca
la inceputul fiecarui fisier sa fie descris succint continutul si functionalitatea fisierului. De asemenea, toate
functiile a caror functionalitate nu este evidenta trebuie descrise printr-un comentariu.

Separarea ideilor

Impartiti problemele mari in parti mai mici ce pot fi implementate prin functii. Daca o functie devine prea
mare (codul sursa se intinde pe cateva zeci sau sute de linii) atunci inseamna ca este prea complexa si ca este
un candidat bun la impartirea in mai multe functii mai simple.

De asemenea, este bine ca functionalitatile asemanatoare sa fie separate, fizic, in fisiere diferite.

Separarea design-ului de logica de business

O practica des intalnita in programarea web consta in separarea codului de prelucrare a datelor de cel
responsabil cu afisarea lui. Acest lucru ofera o flexibilitate mai mare, in special in situatia in care trebuie
aplicate schimbari in oricare din cele doua parti. De asemenea, permite programatorilor web sa lucreze
oarecum independent de designerii web.

Exista mai multe modalitati prin care se poate realiza efectiv aceasta separare: fie folosind un sistem de
sablonare (ce foloseste template-uri), fie separand pur si simplu instructiunile de afisare de restul codului
sursa. Prima varianta implica o complexitate mai mare si devine utila doar pentru proiectele de mari
dimensiuni, in timp ce varianta a doua poate fi aplicata in orice proiect de orice dimensiuni.

Un exemplu de separare este ilustrat mai jos:

<?php

// cod de business
$data = date( 'd.m.Y H.i.s' );
$nume = 'Utilizator'
$t = localtime( time(), true ); // returneaza un vector cu elementele datei si orei
locale
$h = $t[ 'tm_hour' ]; // preiau ora
$mesaj = '';

if( $h <= 11 ) {
95
$mesaj = "Buna dimineata";
} elseif( $h > 11 && $h < 18 ) {
$mesaj = "Buna ziua";
} elseif( $h >= 18 ) {
$mesaj = "Buna seara";
}

// cod de afisare
print <<<TXT
<html>
<title>Tutorial PHP - php.punctsivirgula.ro</title>
<body>
$mesaj, $nume! <br />
Azi este: $data
</body>
</html>
TXT;
?>

Aplicatii si utilitare

Mai jos sunt prezentate o serie de aplicatii sau extensii ce pot fi utile oricarui programator PHP, fie el
incepator sau avansat.

Eclipse Remote System Explorer

Remote System Explorer este o extensie a editorului Eclipse ce ofera posibilitatea de conectare si transfer de
date/fisiere la distanta prin diferite protocoale web: FTP, SFTP, SSH, etc. Este util cand este nevoie sa
transferati scripturile voastre PHP pe un server de hosting.

RSE se poate instala direct din Eclipse, din meniul Help -> Install New Software. Mai multe detalii despre
aceasta extensie la http://wiki.eclipse.org/TM_and_RSE_FAQ

Color Picker

Pixie este un color-picker ce afiseaza culoarea obiectului sau ferestrei deasupra carora se afla cursorul
mouse-ului. Este foarte util in alegerea schemei de culori pentru orice element al unei pagini web. Poate fi
descarcat de la http://nattyware.com/pixie.php.

O alternativa online, ce foloseste un set predefinit de culori, este disponibila pe site-ul w3schools.com.

Web Developer Tools

Majoriatatea browserlor moderne dispun de utilitare pentru inspectarea, depanarea si analizarea paginilor
web si chiar pentru modificarea lor temporara. Aceste facilitati sunt utile atat pentru web-designeri cat si
pentru programatori web.

In functie de browserul folosit, utilitarele se numesc diferit, desi toate sunt similare ca si functionalitate. De
obicei pot fi accesate din browser apasand F12 dupa ce o pagina s-a incarcat complet. Acestea sunt: Firebug
96
pentru Firefox (extensie separata), Developer Tools pentru Chrome sau Internet Explorer (preinstalat),
DragonFly pentru Opera (preinstalat).

GIT

Git reprezinta un sistem de management al codului (SCM) si de control al versiunii (VCS) ce permite
inregistrarea tuturor modificarilor facute fisierelor. Git ofera multe alte facilitati si este util in special atunci
cand sunt mai mult programatori care lucreaza la acelasi proiect. Mai multe detalii despre Git la git-
scm.com.

Ca alternativa la Git se poate folosi Bazaar, Mercurial sau mai vechiul Subversion.

Servicii

Partajarea codului PHP

In momentul in care lucrati la un proiect mai complex si vreti sa-l partajati cu alte persoane, aveti nevoie ca
fisierele sursa sa fie stocate intr-o locatie usor accesibila pentru toata lumea. Ideal, asta inseamna undeva in
internet.

Din fericire, exista site-uri ce ofera gratuit servicii de stocare a codului sursa, astfel incat acesta sa poata fi
accesat din internet. Un astfel de site este bitbucket.com, care permite un numar nelimitat de proiecte, atat
publice cat si personale (private). Administrarea codului sursa se face exclusiv folosind o aplicatie de tip
SCM (Git sau Mercurial), ceea ce permite o evidenta clara a tuturor modificarilor facute asupra fisierelor
dintr-un proiect. Inregistrarea pe site-ul BitBucket este gratuita, la fel ca si crearea proiectelor. Singura
limitare o reprezinta numarul de persoane cu care se poate partaja codul-sursa privat (5 persoane pentru
conturile gratuite).

Ca alternative la serviciile bitbucket.com se poate folosi:

github.com - varianta gratuita permite doar proiecte publice (open source); contra cost se pot crea si
proiecte private; administrarea codului se face doar prin Git

launchpad.net - varianta gratuita permite doar proiecte publice (open source); contra cost se pot crea
si proiecte private; administrarea codului se face doar prin Bazaar

code.google.com - permite doar proiecte publice (open source); administrarea codului se poate face
prin Git, Mercurial sau Subversion

sourceforge.net - permite doar proiecte publice (open source); administrarea codului se poate face
prin Git, Mercurial, Bazaar, Subversion sau CVS

In cazul in care nu doriti sa gestionati codul folosind un SCM (ca Git sau Subversion), puteti opta pentru
servicii clasice de web-hosting de la diverse companii, unde puteti incarca scripturile PHP direct folosind
FTP. Aceste servicii sunt insa, de cele mai multe ori, contra cost.

Testarea online a codului PHP


97
Site-ul ideone.com ofera posibilitatea testarii secventelor de cod PHP direct online, fara a fi nevoie sa
instalati PHP local. Dispune de o multitudine de alte limbaje de programare.

98