Sunteți pe pagina 1din 217

PHP

1. Unelte de baza - ce aveti nevoie pentru un site profesionist.


2. Despre PHP - ce este şi instrucţiuni pentru începători.
3. Variabile în PHP - ce sunt şi cum se folosesc.
4. Variabile predefinite
5. Domeniul de vizibilitate al variabilelor - Cum se pot accesa variabilele.
6. Tipuri de variabile
7. Afişarea mesajelor în PHP
8. Construieşte un site cu php
9. Câteva informaţii despre documentarea şi depanarea unui script.
10. Operatori PHP
11. Câteva idei utile pentru securitatea paginilor web
12. Structuri de control în PHP
13. Despre funcţii în PHP
14. Clase şi obiecte în PHP
15. Crearea imaginilor thumbnails
16. Autentificarea în paginile restricţionate şi câteva informaţii despre cookie, uploadul
fişierelor şi includerea lor în pagini, precum şi informaţii despre starea conexiunii.
17. Descrierea funcţiilor care pot fi utilizate la manipularea tablourilor
18. Lucrul cu fişiere şi directoare
19. Descrierea funcţiilor de prelucrare a fişierelor
20. Funcţii care faciliteaza lucrul cu directoare
21. Valori scalare şi tablouri
22. Lucrul cu formulare
23. Conversia tipurilor de variabile
24. Scrierea instrucţiunilor swich, break şi default
25. Scrierea instrucţiunilor for
26. Scrierea instrucţiunilor while şi do while
27. Introducere în Clase PHP
28. Sesiuni în PHP
29. Crearea şi utilizarea funcţiilor
30. Utilizarea fişierelor incluse
31. Funcţii PHP pentru expresii regulate
32. Utilizarea referinţelor în PHP
33. Lucrul cu funcţii listă
34. Interoperabilitate PHP-Java
35. Transmiterea mesajelor prin e-mail folosind PHP şi PEAR
36. Informaţii despre clasele încărcate
37. Prelucrarea dinamică a imaginilor
38. Funcţii PHP utilizate pentru accesarea şi interogarea bazelor de date MySQL
39. Utilizarea şirurilor
40. Manipularea şirurilor şi scrierea expresiilor regulate
41. Utilizarea variabilelor cookie
42. Expedierea mesajelor de poştă electronică
43. Stocarea unor date ierarhice într-o bază de date
44. PHP 5, Factory
45. PHP 5, SQLite în Factory?

Unelte de baza - ce aveti nevoie pentru un site profesionist.


De ce să folosiţi PHP în loc de HTML sau ASP sau PERL? Pentru că, faţă de alte limbaje, PHP
este gratuit.
Să spunem că aveţi de făcut un site care va conţine peste 150 de pagini. Dacă ar fi să îl faceţi
în HTML, ar dura ceva vreme. Ok. Să zicem că site-ul este gata, dar acum vreţi să schimbaţi
fontul şi culorile textului şi ale link-urilor în toate cele 150 de pagini. Vă apucă durerea de cap
doar când vă gândiţi ce aveţi de făcut. În schimb, în PHP, acest lucru şi multe altele sunt foarte
simple. Dacă site-ul respectiv ar fi fost făcut în PHP pe module, tot ce ar fi trebuit să faceţi este
ca în partea care conţine informaţiile despre text să schimbaţi informaţile despre text şi link
aşa cum doriţi şi modificarea este aceeaşi pentru toate paginile. Simplu nu?
Pentru a rula exemplele şi scripturile existente pe acest site pe calculatorul dvs. de acasă sau
pe pagina proprie trebuie să aveţi instalate şi configurate câteva aplicaţii de care o sa vorbim în
continuare. Nu trebuie să aveţi cunoştinţe preliminare de baze de date sau programare. Simpla
studiere a codului sursa şi aplicarea exemplelor vă poate lămurii ce poate face php. Deci, dacă
vă credeţi pregătiţi cititi în continuare...

Unelte de bază

Crearea unor pagini dinamice la un nivel performant, precum şi punerea lor în funcţiune, nu
poate fi făcută fără anumite programe. Iată cam de ce aveţi nevoie:

Browsere - Pentru testarea paginilor este nevoie de mai multe browsere pentru că nu toate
afişează acelaşi rezultat şi este neprofesional să obligaţi vizitatorul să folosească un anumit
browser doar pentru că pagina făcută de voi arată şi merge mai bine cu acel browser. Deci vă
recomand să instalati 2-3 browsere pentru teste. Dintre cele mai folosite în prezent vă
recomand Internet Explorer (folosit pe calculatoare cu sistem de operare Windows), Firefox (se
foloseste din ce în ce mai des datorită extensiilor şi faptului că se poate instala atât pe sisteme
de operare Windows cât şi pe Mac OS X sau Linux) şi Opera (care are suport pentru mai multe
sisteme de operare).

Serverul web pentru teste - Dacă lucraţi cu PHP-MySQL sub Windows, sigur aveţi nevoie de
triada Apache - PHP - MySQL să fie instalată pe calculatorul local. Pentru aceasta aveţi două
posibilităţi: prima ar fi să descărcaţi de pe pagina producătorului fiecare aplicaţie în parte şi să
o instalaţi manual, urmând apoi să faceţi configurarea serverelor manual (lucru nerecomandat
începătorilor) şi a doua variantă să descărcaţi un program care instalează toate acestea gata
configurate pe calculator, urmând ca voi doar să vă apucaţi de lucru. Astfel de aplicaţii sunt
EasyPHP de exemplu (pentru Windows 95-98 dar merge şi pe Windows 2000 şi XP) sau
recomandarea mea WAMP5 care merge doar pe Windows NT (adica 2000, XP, 2003, Longhorn,
etc) dar care are multe alte facilităţi în plus faţă de EasyPHP pe care cu timpul când veţi învăţa
mai multe despre PHP si MySQL o să le consideraţi foarte utile (cum ar fi posibilitatea de
testare a scripturilor PHP atât pentru versiunea 4 cât si 5). Ultima recomandare, atât pentru cei
care folosesc sistemul de operare Windows cât şi Linux, ar fi XAMP care conţine toate pachetele
necesare instalării şi configurării unui server de web profesional (inclusiv server de FTP, SSI,
DNS şi MAIL), dar pe care nu îl recomand începătorilor pentru că mulţimea de facilităţi oferite
vă poate încurca.

Editoare web - După ce aţi instalat serverul web şi browserele acum vă mai trebuie un editor
bun pentru a scrie cod şi a vizualiza paginile create. Pentru aceasta recomandarea mea este
suita Macromedia (Dreamweaver, FLASH şi FreeHAND). Puteţi descărca Dreamweaver (pentru
a scrie cod şi a vedea/rula paginile în timp real) de la ei de pe site şi tot de la ei vă mai
recomand Fireworks (dacă vă ocupaţi şi cu design-ul paginilor aceasta aplicaţie vă este utilă
împreună cu Adobe Photosop sau Corel Draw) şi Flash (dacă doriţi să faceţi animaţie pentru
site). Desigur sunt o mulţime de programe care fac aceleaşi lucruri cu ce vă recomand eu, dar
dacă doriţi să lucraţi la nivel profesional recomand să lucraţi cu unelte de profesionişti.
Bineânţeles că puteţi scrie cod şi în Notepad şi desena în Paint dar aplicaţiile pe care vi le-am
recomandat vă uşurează extraordinar de mult munca şi vă semnalează rapid erorile din pagini.
Alte editoare pe care vi le recomand să le testaţi sunt: PSPad (un bun înlocuitor al Notepad-
ului, mai ales că este freeware), Zend Studio (destinat profesioniştilor).
După ce aţi făcut rost de tot ce vă trebuie ca să începeţi treaba, vă recomand să citiţi în
continuare celelalte articole, eventual să vizitaţi şi pagina de download, sigur găsiţi ceva util
acolo pentru început, apoi pagina de link-uri, unde găsiti resurse gratuite şi să discutăm pe
forum eventualele probleme pe care le întâmpinaţi.

Despre PHP - ce este şi instrucţiuni pentru începători.

Despre PHP

PHP este limbajul ideal pentru construirea de pagini web dinamice. Este usor de învăţat, open-
source, poate fi rulat pe mai multe platforme şi se poate conecta la mai multe tipuri de baze de
date. Cel mai important aspect al limbajului este însa posibilitatea de a fi îmbricat cu cod
HTML. Putem astfel crea pagini HTML statice şi din loc în loc, acolo unde este nevoie, să
introducem dinamism cu ajutorul PHP.
Limbajul PHP s-a "născut" în 1994 din nevoia lui Rasmus Lerdorf de a afla câte persoane îi
vizitează CV-ul online. El a denumit setul de scripturi create PHP, acronimul pentru Personal
Home Page. Pe parcursul următorilor trei ani limbajul a evoluat dar adevăratul succes a început
să îl cunoască de când Zeev Suraski si Andi Gutmans au rescris motorul PHP de la cap la
coadă, motor care poartă din versiunea 4 a PHP numele Zend, o combinaţie de litere din
prenumele creatorilor săi: Zeev şi Andi.
Fiind open-source, PHP beneficiază de suport activ din partea comunităţii online, acesta fiind şi
motivul creşterii explozive a numărului site-urilor bazate pe PHP.
Interpretorul PHP este cel mai cunoscut limbaj de scripting folosit în acest moment pentru
crearea site-urilor Web interactive. Denumirea este un "acronim recursiv" pentru Hypertext
PreProcessor. Diferenţa esenţială faţă de alte limbaje de scripting (gen JavaScript) este faptul
că PHP este un interpretor server-side (operaţiile sunt executate de către server şi nu pe
calculatorul utilizatorului). Pentru a putea testa pagini PHP aveţi nevoie de un server de web
(Apache) şi de pachetul PHP instalat.
PHP permite folosirea unor elemente specifice limbajelor de programare. Ieşirea standard a
script-ului PHP devine intrarea standard pentru programul de navigare care vizualizează
pagina. Aşadar, la iesirea standard poate fi scris (de exemplu, prin intermediul comenzii echo)
orice tip de cod HTML, acesta fiind interpretat de către browser.
Pe lângă manipularea conţinutului paginilor de web, PHP poate trimite headere HTTP pentru
autentificare, seta cookie-uri sau redirecţiona utilizatorii. Mai mult, cu ajutorul bibliotecilor
externe de funcţii poate parsa fisiere XML, crea şi manipula imagini, animaţii Shokwave Flash,
PDF-uri sau se poate conecta la un server de mail, iar acestea sunt doar câteva din funcţiile pe
care le poate îndeplini.
Interpretorul PHP parcurge documentul accesat până în momentul în care întâlneşte un marcaj
de deschidere care indică faptul că textul care urmează trebuie interpretat ca fiind cod PHP. În
continuare, textul este interpretat ca fiind cod PHP până în momentul în care este întâlnit
marcajul de inchidere. Întreg textul care nu este interpretat ca fiind cod PHP este furnizat la
iesire în forma în care a fost primit ca intrare de catre interpretor. Există mai multe marcaje
care indică începerea unei secvenţe de cod PHP, dar doar două dintre ele sunt folosite de obicei
(aceste marcaje depind şi de configurarea serverului de web). Dacă dorim ca documentul să
respecte specificaţiile XML, atunci singura posibilitate de inserare a codului PHP este folosirea
unei secvente de tipul:

Cod:

<?php
//cod PHP
?>

Cea de-a doua posibilitate este utilizarea marcajului <SCRIPT> într-o maniera asemănătoare
celei folosite pentru includerea de script-uri JavaScript. Sintaxa este urmatoarea:

Cod:

<SCRIPT language = "php">


//cod PHP
</SCRIPT>

Există alte două posibilităţi, dar acestea sunt folosite rar, în situaţii particulare şi depinde în
mare măsură de setările serverului de web.
Este permisă "iesirea" şi "intrarea" în "modul PHP" de oricâte ori este necesar în pagină.
Aceasta este util când se lucrează cu texte de mari dimensiuni.
Pentru ca instrucţiunile PHP să fie interpretate corect, acestea trebuie separate prin caracterul
';'.
În PHP, comentariile pot fi inserate folosind sintaxele din C, C++ şi shell-urile Unix. Apariţia
secventei de caractere '//' sau a caracterului '#' indică faptul că restul liniei reprezintă un
comentariu. Pentru a insera comentarii pe mai multe linii, acestea trebuie delimitate de
secventa '/*' la început şi de secventa '*/' la sfârşit.

Variabile în PHP - ce sunt şi cum se folosesc.

Variabile în PHP

Programarea de orice fel, nu doar PHP, are două elemente de bază: datele şi instrucţiunile.
Pentru a lucra cu datele trebuie să înţelegem ce sunt variabilele şi tipurile, iar pentru a lucra cu
instrucţiuni trebuie să aflăm ce sunt structurile de control şi funcţiile.
O variabilă este o zonă de memorie căruia i se dă un nume pentru a putea fi recunoscută
ulterior şi pentru a ne putea referi mai târziu la ea.
În PHP, o variabilă este reprezentată de semnul '$', urmat de numele variabilei. La fel ca în
limbajele C/C++ sau Java, pentru denumirea variabilelor se face distincţia între literele mari şi
literele mici.
Numele unei variabile poate începe cu o liniuţă de subliniere '_' sau o literă. Restul caracterelor
care formează numele variabilei pot fi litere, cifre sau liniuţe de subliniere. În PHP, sunt
considerate litere toate caracterele cuprinse între 'a' şi 'z', cele cuprinse între 'A' şi 'Z', precum
şi cele care au codul ASCII cuprins între 127 şi 255.
Începând cu versiunea 4, au fost introduse referinţele; astfel, o variabilă poate referi o alta,
astfel încât modificarea valorii uneia duce la modificarea automată a valorii celeilalte. O
referinţă la o variabilă este reprezentată de caracterul '&'. Iată un scurt exemplu:

Cod:
<?php
$a = "PHP4 e slab";
$b = &$a;
$b = "PHP4 e foarte bun";
echo $a;
echo "<br>";
echo $b;
?>

După cum se vede, modificarea valorii variabilei $b a dus automat la modificarea automată a
valorii variabilei $a.
Să disecăm codul pentru a învăţa câteva lucruri:
- toate instrucţiunile PHP se termină cu punct şi virgulă. Omiterea semnului ";" este cea mai
frecventă greşeală pe care o fac programatorii începători.
- codul PHP începe întotdeauna cu "<?php" şi se termină cu "?>". El poate fi îmbricat cu cod
HTML după cum puteţi vedea în exemplul de mai sus. Puteţi chiar crea pagini HTML fără pic de
cod PHP în ele şi să le daţi extensia php. Atâta vreme cât parser-ul PHP nu "vede" tagurile "<?
php ...?> ", el va trimite pagina neschimbată către server.
- putem pune diacritice în cadrul unui string însă pentru ca browserul să le afişeze corect va
trebui să specificăm în <head> setul de caractere folosit, la fel ca într-un document HTML.
- valoarea unei variabile poate fi schimbată după necesităţi (aşa cum am schimbat valoarea lui
$a) sau ea va fi schimbată automat în funcţie de celelalte variabile de care depinde.

Variabile predefinite

Începand de la versiunea 4.1.0 metodele predefinite pentru preluarea variabilelor externe


depind de setarea din php.ini a variabilelor globale (register_globals). Astfel dacă pe server
este setată register_globals=ON (nerecomandat) se pot prelua de exemplu variabilele trimise
prin GET şi POST apelând direct variabila.
Exemplu:

Cod:

<?php
// sa spunem ca avem un formular in care exita un camp numit "camp1" si
care se trimite prin metoda POST:
// cu register_globals=ON
$camp1 = "valoarea campului";
// cu register_globals=OFF
$_POST['camp1'] = "valoarea campului";
$camp1 = $_POST['camp1'];
?>

Variabile globale:
$GLOBALS - pot fi accesate toate variabilele globale care sunt accesibile script-ului PHP
curent; acest vector este indexat chiar prin numele variabilelor globale. Această variabilă
superglobală este accesibilă începând cu versiunea 3.0.0

$_SERVER - conţine o serie de variabile ale căror valori sunt setate de server-ul web;
majoritatea valorilor variabilelor din acest vector depind de mediul de execuţie al script-ului
curent. A fost introdusă începând de la versiunea 4.1.0. În versiunile anterioare se folosea
$HTTP_SERVER_VAR .
Este o variabilă care conţine informaţii cum ar fi headere, locaţia scriptului, sau informaţii
despre vizitator şi browser. Este posibil ca în funcţie de setările fiecărui server şi browser să nu
fie active toate informaţiile specificate de această variabilă. Această variabilă este de
asemenea globală, adică se poate folosi oriunde în script, fără apelarea ei ca funcţie globală
(adică nu trebuie să o cereţi cu global $_SERVER în funcţiile dvs.) În schimb
$HTTP_SERVER_VARS conţine aceleaşi informaţii dar nu este o funcţie globală (atenţie
$HTTP_SERVER_VARSşi $_SERVER sunt două variabile diferite, chiar dacă aparent fac
aceleaşi lucruri) Dacă directiva register_globals este ON atunci aceste variabile vor deveni la
rândul lor variabile globale în cadrul scriptului.
Elementele acestor variabile sunt cele de mai jos (atenţie: în funcţie de setările serverului şi
browserului unele elemente pot lipsi)

' PHP_SELF ' - conţine numele fişierului unde se execută scriptul curent, relativ la rădacină
(document root) De exemplu, $_SERVER['PHP_SELF'] într-un script la adresa
http://example.com/test.php/foo.bar va fi /test.php/foo.bar . Constanta __FILE__ conţine
toată calea şi numele fişierului curent.

' argv ' - Un array al argumentului trimis către script. Când scriptul rulează în linie de
comandă, va da acces C-style la parametrii liniei de comanda. Când este accesat prin metoda
GET, acesta va conţine un sir de interogare.

' argc ' - Conţine un număr al parametrilor liniei de comandă trimise către script (daca este
rulat în linie de comanda).

' GATEWAY_INTERFACE ' - Returneaza versiunea CGI utilizată pe server (exemplu ' CGI/1.1
').

' SERVER_NAME ' - Numele server-ului de hosting unde se execută scriptul curent. Dacă
scriptul rulează pe un host virtual, aceasta va conţine valoarea definită pentru acel host
virtual.

' SERVER_SOFTWARE ' - Returnează un şir de identificare al server-ului dat în header ca


raspuns la cerere.

' SERVER_PROTOCOL ' - Numele şi versiunea protocolului prin care este cerută pagina
(exemplu ' HTTP/1.0 ')

' REQUEST_METHOD ' - returnează metoda utilizată pentru accesarea paginii (exemplu ' GET
', ' HEAD ', ' POST ', ' PUT ')

' REQUEST_TIME ' - Valoarea timestamp dată la pornirea cererii. Este valabilă începând de la
versiunea PHP 5.1.0.

' QUERY_STRING ' - Sirul de interogare, dacă este, de la pagina care a fost accesată.

' DOCUMENT_ROOT ' - Directorul radăcină unde este rulat scriptul curent, aşa cum este
definit în fişierul de configuraţie al serverului.

' HTTP_ACCEPT ' - Conţinutul header-ului acceptat de la cererea curentă, dacă este unul.

' HTTP_ACCEPT_CHARSET ' - Conţine setul de caractere acceptate şi care este trimis de
header-ul cererii respective, dacă există. Exemplu: ' iso-8859-1,*,utf-8 '.

' HTTP_ACCEPT_ENCODING ' - Conţine tipul de encodare trimis de cerera curentă prin
header, dacă există.. Exemplu: ' gzip '.

' HTTP_ACCEPT_LANGUAGE ' - Conţine limbajul trimis de cererea curentă prin header, dacă
exista. Exemplu: ' en '.

' HTTP_CONNECTION ' - Conţine informaţii despre conecsiiunea trimisă de cererea curentă
prin header, dacă există. Exemplu: ' Keep-Alive '.
' HTTP_HOST ' - Conţine informaţii despre host, header-ul de la cererea curentă, dacă există.

' HTTP_REFERER ' - Adresa paginii (dacă este) de unde a venit userul în pagina curentă.
Aceasta este setată de către browser. Nu toate browserele setează această valoare, şi chiar
unele au posibilitatea de a modifica HTTP_REFERER aşa cum vor. Pe scurt, nu este de
încredere.

' HTTP_USER_AGENT ' - Conţine semnătura browser-ului trimisă prin header la cererea
curentă, dacă există. Un exemplu tipic este: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586) . În
afară de asta, puteţi utiliza get_browser() pentru a vedea ce capabilitaţi are browserul
folosit de user şi astfel să returnaţi pagina specifică pentru acel browser.

' HTTPS ' - Setează o valoare dacă scriptul a fost cerut printr-un protocol securizat HTTPS

' REMOTE_ADDR ' - Adresa de IP a userului care accesează pagina curentă.

' REMOTE_HOST ' - Numele hostului userului care vede pagina curentă. Este inversul DNS-
ului userului bazat pe REMOTE_ADDR. Atenţie: Serverul web trebuie configurat pentru a crea
această variabila. De exemplu în Apache va trebui HostnameLookups On în fişierul de
configurare httpd.conf. Pentru alte detalii vedeţi şi funcţia gethostbyaddr() .

' REMOTE_PORT ' - Portul prin care userul comunică cu serverul web.

' SCRIPT_FILENAME ' - Calea absolută unde se execută scriptul curent. Atenţie: Dacă
scriptul este rulat cu CLI, ca şi cale relativă, cum ar fi file.php sau ../file.php ,
$_SERVER['SCRIPT_FILENAME'] va conţine calea relativă specificată de către user.

' SERVER_ADMIN ' - Valoarea dată de directiva SERVER_ADMIN (pentru Apache) în fişierul
de configurare al web serverului. Dacă scriptul rulează pe un host virtual, acesta va conţine
valoarea definită pentru acel host virtual.

' SERVER_PORT ' - Portul de pe server care este folosit pentru comunicare pe web. Pentru
setările standard, acesta este ' 80 '; pentru SSL, de exemplu, se va schimba cu oricare port
definit în transmisia securizată HTTP.

' SERVER_SIGNATURE ' - Conţine un şir care cuprinde versiunea serverului şi numele
hostului virtual dacă este.

' PATH_TRANSLATED ' - Calea de bază a sistemul de fişiere (nu rădacina documentului) de
la scriptul curent, după ce serverul a terminat maparea oricăror cai ( virtual-to-real mapping)
Atenţie: Începând de la PHP 4.3.2, PATH_TRANSLATED nu mai este setat implicit în Apache
2 SAPI în contrast cu situaţia din Apache 1, unde este setată aceeaşi valoare ca şi la
SCRIPT_FILENAME. Această schimbare a fost făcută pentru a fi compatibilă cu specificaţiile
CGI în care PATH_TRANSLATED trebuie să existe doar dacă PATH_INFO este definit.
Utilizatorii Apache 2 pot utiliza AcceptPathInfo = On în fişierul de configuraţie httpd.conf
pentru a defini PATH_INFO .

' SCRIPT_NAME ' - Conţine calea către scriptul curent. Acesta este util pentru pagini care
trebuiesc definite către ele însuşi. Constanta __FILE__ conţine calea completă şi numele de
fişier al scriptului curent.

' REQUEST_URI ' - URI care este dat pentru accesarea paginii curente, de exemplu '
/index.html '.

' PHP_AUTH_DIGEST ' - Când rulaţi sub Apache ca modul, acţiunea Digest HTTP, valoarea
acestei variabile este setată în 'Authorization' header trimis către client (care ar trebui utilizat
pentru a face o validare corespunzătoare).

' PHP_AUTH_USER ' - Când este rulat sub Apache sau IIS (ISAPI pe PHP 5) ca modul,
actiunea HTTP authentication, această variabilă conţine numele userului trimis de către user.

' PHP_AUTH_PW ' - Când este rulat sub Apache sau IIS (ISAPI pe PHP 5) ca modul, actiunea
HTTP authentication, această variabilă conţine parola userului trimisă de către user.

' AUTH_TYPE ' - Când este rulat sub Apache ca modul acţiunea HTTP authenticated , această
variabilă seteaza tipul de autentificare.

Variabilele pentru trimiterea datelor:


$_GET este o variabilă array globală. A fost introdusă în versiunea 4.1.0. Pentru versiunile
anterioare se foloseşte $HTTP_GET_VARS care nu este variabilă globală. Puteţi folosi $_GET
pentru a trimite variabile cu valori prin intermediul linkurilor.
$_POST este de asemenea o variabilă array globală. A fost introdusa în versiunea 4.1.0.
Pentru versiunile anterioare se foloseşte $HTTP_POST_VARS care nu este variabilă globală.
Puteţi folosi $_POST pentru a trimite variabile cu valori prin intermediul formularelor.
$_GETşi $_POST conţin variabile primite de script prin intermediul unor transferuri care
folosesc metodele HTTP get, respectiv post. De exemplu, prin intermediul acestor vectori pot fi
accesate valorile câmpurilor dintr-un formular care a fost completat şi transmis folosind una
dintre cele doua metode.

Variabilele HTTP coockies:


$_COOKIE conţine valorile variabilelor care conţin informaţii referitoare la cookie-urile
păstrate pe calculatorul utilizatorului care accesează pagina web. A fost introdus în versiunea
4.1.0. În versiunile anterioare, utilizaţi $HTTP_COOKIE_VARS .

Variabile pentru uploadul fisierelor:


$_FILES conţine variabile primite de script prin intermediul încărcărilor de fişiere prin metoda
post. A fost introdus în versiunea 4.1.0. În versiunile anterioare se foloseşte
$HTTP_POST_FILES care nu este variabilă globală.

Variabilele de mediu $_ENV


$_ENV conţine variabile disponibile prin intermediul mediului în care este executat. A fost
introdus în versiunea 4.1.0. În versiunile anterioare, utilizaţi $HTTP_ENV_VARS .

Variabilele pentru cereri:


$_REQUEST conţine variabile disponibile prin intermediul oricărui tip de mecanism cu ajutorul
căruia utilizatorul poate introduce date. Este de tip array şi conţine valorile variabilelor
$_GET , $_POST , şi $_COOKIE. A fost introdusă în versiunea 4.1.0. Începând de la
versiunea 4.3.0, informaţiile din $_FILES au fost de asemenea incluse în $_REQUEST

Variabile de sesiune:
$_SESSION conţine variabile care corespund sesiunii curente a script-ului, sub formă de array.
A fost introdusă în versiunea 4.1.0 şi este de asemenea globală. În versiunile anterioare
folosiţi $HTTP_SESSION_VARS.

Variabile de mesaje de eroare:


$php_errormsg - este o variabilă ce conţine ultimul mesaj generat de către PHP Această
variabilă este folosită în scopul de a vedea ce eroare apare şi doar dacă opţiunile de
configurare a erorilor track_errors este pornita (standard este pe OFF)

Constante predefinite:
PHP conţine un mare număr de constante predefinite pentru fiecare script care rulează. Totuşi,
sunt 5 constante "magice" pe care le prezint în continuare:
__LINE__ - Conţine numărul curent al liniei din fisier.
__FILE__ - toată calea şi numele fişierului curent. Dacă este folosit în interiorul unui fişier
inclus, va returna numele fişierului inclus. Începând de la versiunea 4.0.2 conţine întotdeauna
calea absolută la fişier, pe când în versiunile anterioare conţine calea relativă, în afară de
câteva cazuri.
__FUNCTION__ - Numele funcţiei (adăugat în versiunea 4.3.0) În PHP 5 această constantă
returnează numele funcţiei care a fost declarată (case-sensitive). În PHP 4 această valoare
este întotdeauna lowercased (cu litere mici)
__CLASS__ - Numele clasei (adaugată în versiunea 4.3.0) În PHP 5 această constantă
returnează numele clasei care a fost declarată (case-sensitive). În PHP 4 această valoare este
întotdeauna lowercased (cu litere mici)
__METHOD__ - Numele metodei clasei (adaugată în versiunea 5.0.0.) Numele metodei este
returnat asa cum este declarat (case-sensitive)

Domeniul de vizibilitate al variabilelor - Cum se pot accesa variabilele.

În PHP o variabilă poate fi accesată doar în contextul în care a fost definită. De exemplu, o
variabilă definită în interiorul unei funcţii nu va putea fi accesată decât de instrucţiunile din
interiorul acelei funcţii. Mai mult, în mod implicit, o variabilă definită în exteriorul unei funcţii
nu va putea fi accesată în interiorul funcţiei chiar dacă ea nu este redefinită în cadrul funcţiei.
Pentru ca o funcţie să aibă acces la o variabilă definită în afara ei, variabila trebuie redeclarată
ca variabilă globală în interiorul funcţiei.
Să considerăm următorul exemplu:

Cod:
<?php
$a = 1;
function test ()
{
echo $a;
}
test ();
?>

Observăm că nu se afişează valoarea 1 deoarece instrucţiunea echo $a se referă la variabila


locală $a care nu este definită, deci nu are nici o valoare. În continuare, este o versiune în
care instrucţiunea echo $a va accesa variabila $a definită în afara funcţiei test():

Cod:
<?php
$a = 1;
function test ()
{
global $a;
echo $a;
}
test ();
?>

O a doua posibilitate de a accesa o variabilă definită în afara funcţiei este folosirea vectorului
$GLOBALS:
Cod:
<?php
$a = 1;
function test ()
{
echo $GLOBALS ["a"];
}
test ();
?>

Tipuri de variabile

Variabilele pot fi de mai multe tipuri, nu doar numere. PHP are opt tipuri de variabile. Patru
dintre acestea sunt tipuri scalare (boolean, integer, float şi string), două sunt tipuri compuse
(array şi object), iar alte două sunt tipuri speciale (resource şi null). De asemenea, din motive
de lizibilitate, au fost introduse trei pseudotipuri: mixed, number şi callback. Mai exista şi tipul
double, dar semnificaţia acestuia este aceeaşi cu cea a tipului float. Cele două denumiri
coexistă doar din motive "istorice". În PHP, de obicei, tipul unei variabile nu este specificat de
către programator, ci este stabilit în timpul execuţiei în funcţie de contextul în care este
folosită variabila.

Tipul boolean: Variabilele de acest tip pot avea doar două valori: ADEVARAT sau FALS.
Aceste valori pot fi indicate prin cuvintele cheie TRUE sau FALSE (pentru ambele nu se face
distincţie între literele mari şi literele mici). Există posibilitatea de a converti o variabilă de
orice tip la tipul boolean. În momentul efectuării unei conversii, sunt convertite la valoarea
FALSE următoarele valori:
- numărul întreg 0;
- numărul real 0.0;
- sirul vid;
- sirul "0";
- un vector fără nici un element;
- un obiect fără nici o variabilă membru;
- o variabilă de tipul NULL;
- o variabilă nedefinită.
Orice altă valoare este convertită la valoarea TRUE (inclusiv resursele).
Acest tip se poate folosi de exemplu pentru verificarea logării într-o pagină de administrare.
După ce se fac verificările, dacă utilizatorul este logat ca administrator, funcţia noastră va
returna o valoare de adevar: TRUE dacă este logat, sau FALSE dacă nu este, şi astfel vom şti
dacă să îi acordăm sau nu acces în secţiunea de administrare.

Tipul integer: O variabilă de tip integer reprezintă o valoare din mulţimea numerelor întregi.
Aceste numere pot fi specificate în baza 10, în baza 16 sau în baza 8, convenţiile fiind aceleaşi
ca şi în limbajele C/C++ sau Java. Modul de reprezentare depinde de platforma utilizată; de
obicei se foloseşte reprezentarea pe 32 de biti. Interpretorul PHP nu oferă suport pentru
numerele întregi fară semn. Trebuie remarcat faptul că în PHP nu există nici un operator
pentru efectuarea de împărţiri întregi. De exemplu, rezultatul operaţiei 3/2 nu va fi numărul
întreg 1 (ca în C/C++ sau Java), ci numărul real (float) 1.5
Şi pentru numerele întregi există posibilitatea efectuării de conversii:
- valoarea logică TRUE este convertită la valoarea întreagă 1;
- valoarea logică FALSE este convertită la valoarea întreagă 0;
- un număr real este convertit prin "rotunjire înspre 0"; asadar, valoarea reală 2.5 va fi
convertită la valoarea întreagă 2, în timp ce valoarea reală -2.5 va fi convertită la valoarea
întreagă -2;
- un sir de caractere este convertit luând în considerare doar primele caractere care conţin
informaţii numerice; aşadar şirul "10" va fi convertit la valoarea întreagă 10; de asemenea
şirul "10 ani" va fi convertit tot la valoarea 10; dacă primele caractere nu conţin informaţii
numerice, rezultatul conversiei va fi valoarea 0.

Tipul float: O variabilă de tip float poate fi specificată folosind fie forma zecimala, fie cea
ştiinţifică (cu exponent). La fel ca şi în cazul tipului integer, precizia variabilelor de tipul float
este dependentă de platforma utilizată. De obicei se foloseşte standardul IEEE 64. Există
posibilitatea de a converti o variabilă de orice tip la tipul float. Pentru numerele reale se pot
efectua următoarele conversii:
- un şir de caractere este convertit luând în considerare doar primele caractere care conţin
informaţii numerice; aşadar şirul "10.2" va fi convertit la valoarea reală 10.2; şirul "1.23E1
ani" va fi convertit la valoarea 12.3;
- în toate celelalte cazuri se realizează conversii la numere întregi care apoi sunt convertite la
valorile reale corespunzătoare.

Tipul string: O variabilă de tip string reprezintă un şir de caractere. Un caracter se reprezintă
pe un octet, deci sunt 256 de caractere distincte. Acest lucru implică faptul că interpretorul
PHP nu oferă suport nativ pentru setul de caractere Unicode. Lungimea variabilelor de tip
string nu este limitată de către interpretor. Literalii de tip şir de caractere pot fi specificaţi în
trei moduri diferite:
- prin folosirea ghilimelelor simple (exemplu $a='acesta este un sir de caractere'). Pentru a
avea în cadrul şirului simbolul "`", atunci înaintea acestuia trebuie scris caracterul "\", iar
pentru a putea specifica simbolul "\" acesta trebuie dublat.
- prin folosirea ghilimelelor duble. Folosind această notaţie pot fi specificate mai multe
caractere speciale, pe lângă caracterele de la varianta anterioara, printre care: sfârşit de linie
("\r"), rând nou ("\n"), tab orizontal ("\t"), semnul dolar ("\$"), ghilimelele duble ("\""),
secvenţe de caractere pentru specificarea faptului că o expresie regulară este în notaţie octală
("\[0-7]{1,3}") şi secvenţele de caractere pentru specificarea faptului că o expresie regulară
este în notaţie hexazecimală ("\x[0-9A-Fa-f]{1,2}"). Cel mai important lucru este acela că,
folosind acest mod de specificare a literalilor de acest tip, numerele de variabile care apar în
interior vor fi transformate în valoarea lor. De exemplu dacă $a este o variabilă de tipul
integer şi are valoarea 2, atunci sirul de caractere "Variabila a are valoarea $a." va fi
transformat în şirul "Variabila a are valoarea 2".
- notaţia heredoc. Acest tip de notaţie a fost introdus la versiunea 4 a interpretorului PHP.
Pentru a specifica un sir de caractere folosind această notaţie trebuie utilizat operatorul "<<<"
urmat de un identificator ales de utilizator. Toate caracterele care se află între operatorul
"<<<" urmat de un identificator pe o singură linie, şi acelaşi identificator pe o altă linie vor
constitui valoarea sirului de caractere. De exemplu, instrucţiunea:

Cod:
$str=<<<SF

Acesta este un exemplu

de utilizare a sintaxei

heredoc

SF;

va avea ca rezultat un şir de caractere format din trei linii de text.


Pentru a accesa un anumit caracter din şirul de caractere se foloseşte, după numele variabilei
de tip string, indicile caracterului care trebuie accesat scris între acolade. De exemplu, $str{0}
returnează primul caracter din şirul de caractere $str.
În cazul în care dorim să concaternăm două şiruri de caractere vom folosi operatorul "."
Folosirea operatorului "+" nu va concaterna cele două şiruri.
Există posibilitatea de a converti o variabilă de orice tip la tipul string. Pentru şirurile de
caractere se pot efectua următoarele conversii:
- valoarea logică TRUE va fi convertită la şirul "1", iar valoarea logică FALSE va fi convertită la
şirul vid ("");
- un număr întreg va fi convertit la un şir de caractere care reprezintă valoarea numărului în
baza 10;
- un număr real va fi convertit la un şir de caractere care reprezintă notaţia ştiinţifică a
acestuia;
- obiectele sunt întotdeauna convertite la şirul "Object";
- variabilele de tipul resource sunt convertite la şirul "Resource id #n", unde n reprezintă un
număr unic ataşat resursei respective de către interpretorul PHP;
- valoarea NULL este convertită la şirul vid ("").

Tipul array - Vectorii în PHP sunt nişte mulţimi formate din chei. Fiecarei chei din vector i se
ataşează o valoare. Acest tip de date este optimizat astfel încât să poată fi folosit în locul
următoarelor structuri de date: liste, tabele de dispersie, dicţionare, colecţii, stive, cozi şi
altele. Datorită faptului că o valoare poate fi reprezentată de un alt vector, se pot simula
foarte uşor arborii n-dimensionali sau tablourile n-dimensionale. Valoarea unei variabile de tip
vector se poate specifica folosind construcţia
array (cheie => valoare, cheie => valoare, ...)
De exemplu, următoarea înstrucţiune PHP va construi un vector cu două elemente, dintre care
unul este de tip string, iar celălalt de tip boolean:
$a = array ("ch" => "string", 12 => TRUE);
Variabila $a reprezinta un vector, $a ["ch"] are valoarea string, iar $a [12] are valoarea TRUE.
În cazul în care nu se specifică o cheie pentru o valoare, atunci acea valoare va fi ataşată unei
chei care va fi cheia maximă de tip integer folosită anterior, la care se adaugă valoarea 1.
Cheile pot avea şi valori negative. Dacă nu există chei de tip integer, atunci valoarea va fi
ataşata cheii 0. De exemplu, următoarele două instrucţiuni sunt echivalente:
array (5 => 43, 32, 56, "b" => 12);
array (5 => 43, 6 => 32, 7 => 56, "b" => 12);
Dacă se foloseşte valoarea logică TRUE ca şi cheie, atunci aceasta va fi convertită la cheia de
tip întreg 1, iar valoarea FALSE va fi convertită la numărul întreg 0. Nu se pot folosi pentru
chei variabile de tipul array sau object.
O variabilă de tip array se poate modifica prin setarea explicită de valori. De exemplu
instrucţiunea $a ["x"] = 42; adaugă în vectorul $a valoarea 42 ataşată cheii "x". Dacă se
foloseşte un vector care nu a fost definit anterior, atunci acesta este creat automat. Aşadar
printr-o instrucţiune de forma $a [5] = 42, în cazul în care vectorul $a nu există, atunci se va
crea un vector cu un singur element. Cheia acestuia va fi numărul întreg 5, iar valoarea sa va
fi 42.
De asemenea, există posibilitatea de a crea un element nou fără a-i preciza cheia. Sintaxa are
forma $vector [] = valoare; această instrucţiune are ca efect adăugarea unui element a cărui
cheie este un numar întreg mai mare cu 1 decât cel mai mare număr întreg care este cheie a
unui alt element al vectorului. Dacă nu există nici o astfel de cheie, atunci noul element va
avea cheia 0. De exemplu, următoarele două secvente sunt echivalente:
$a [5] = 1; ............................ $a [5] = 1;
$a [6] = 2; ............................ $a [] = 2;
Prin conversia la un vector a unei variabile de tip scalar (boolean, integer, float, string) sau
resource se creează un vector cu un singur element; cheia acestui element este numărul
întreg 0, iar valoarea este cea a variabilei convertite.
Dacă se converteşte un obiect (variabila de tip object), atunci vectorul rezultat va conţine câte
un element pentru fiecare variabilă membru a obiectului. Cheile elementelor vor fi date de
denumirile proprietăţilor obiectului (variabilele membru ale obiectului), iar valorile elementelor
vor fi valorile proprietăţilor obiectului.
Dacă realizăm o conversie a unei variabile de tip NULL, atunci rezultatul va fi un vector vid
(care nu conţine nici un element).
În continuare sunt prezentate câteva exemple care descriu mai detaliat posibilităţile oferite de
folosirea vectorilor în PHP. Pentru început, prezint un vector al cărui elemente reprezintă
caracteristicile unei portocale:
Cod:
$a = array ('denumire' => 'portocala',
'familie' => 'citrice',

'culoare' => 'portocaliu',

'forma' => 'rotunda',

'gust' => 'dulce'

);
Putem adăuga şi alte elemente care să reprezinte diferite alte proprietăţi. De exemplu, am
putea avea nevoie de o valoare suplimentară căreia nu dorim să îi atribuim nici un nume de
identificare (cheie). Pentru ca vectorul să conţina un element suplimentar cu valoarea 4, vom
putea defini vectorul astfel:
Cod:
$a = array ('denumire' => 'portocala',

'familie' => 'citrice',

'culoare' => 'portocaliu',

'forma' => 'rotunda',

'gust' => 'dulce',

4);
Cheia elementului cu valoarea 4 va fi numărul întreg 0 deoarece nu există nici o altă cheie
care este număr întreg. O alternativă de construire a acestui vector este următoarea:
Cod:
$v['denumire'] = 'portocala';

$v['familie'] = 'citrice';

$v['culoare'] = 'portocaliu';

$v['forma'] = 'rotunda';

$v['gust'] = 'dulce';

$v[] = 4;
Exemplul următor ilustrează cum puteţi folosi vectorii la afişarea unei pagini cu text colorat:
Cod:
$colors = array (`red`,
`green`,
`blue`,
`silver` );

foreach ($colors as $color)


{
echo "<FONT size = 4 color = $color>";
echo "<b>Acest text este <i>$color!</i>";
echo "</b></FONT><br>";
}

Tipul object: Pentru a defini un obiect care poate fi folosit pentru afişarea mesajului
SALUTARE LUME! se scrie următoarea secvenţă:

Cod:
class salutare
{
function Displaysalutare ()
{
echo "SALUTARE LUME!";
}
}
Pentru a utiliza o variabilă de tip obiect va trebui să realizăm o instanţiere prin intermediul
instrucţiunii new. Sintaxa este:
$a = new salutare;
Astfel, variabila $a devine un obiect ale cărui metode pot fi utilizate. Pentru afişarea propriu-
zisă a mesajului va trebui să executăm metoda Displaysalutare() printr-o instrucţiune de tipul
$a -> Displaysalutare();
Orice variabilă de un anumit tip poate fi convertită într-un obiect. Dacă variabila respectivă
este un obiect, atunci ea nu va fi modificată. În caz contrar, efectul conversiei este crearea
unei noi instanţe a clasei stdClass. Dacă variabila are tipul NULL, atunci noua instanţă va fi
vidă. În toate celelalte cazuri instanţa va conţine o variabilă membru numită scalar a cărei
valoare va fi cea a variabilei convertite. Pentru conversii vom folosi instrucţiuni de tipul
$obiect = (object) "SALUTARE LUME!"
După realizarea conversiei vom putea tipări mesajul SALUTARE LUME! folosind instrucţiunea
echo $obiect->scalar;

Tipul resource: Variabilele de tip resource sunt folosite pentru păstrarea unor referinţe către
anumite resurse externe cum ar fi conexiuni la baze de date, fişiere, etc. Resursele sunt create
şi utilizate de anumite funcţii speciale. Datorită specificului acestui tip de date valoarea nici
unei variabile de alt tip nu poate fi convertită la tipul resource.

Tipul NULL: Valoarea specială NULL este atribuită oricărei variabile care nu a fost iniţializată.
Această valoare este singura pe care o pot avea variabilele de tip NULL. Se consideră că o
variabilă are tipul NULL dacă:
- i s-a atribuit constanta NULL;
- nu a fost iniţializată;
- a fost deziniţializată (prin intermediul funcţiei unset() ).

Afişarea mesajelor în PHP

Limbajul PHP oferă mai multe variante de a trimite la browser mesaje şi şiruri de caractere sau
chiar cod HTML. Cea mai folosită funcţie este echo(). Sintaxa corectă este:

<?php

echo("sir de caractere");

?>

Instrucţiunea de mai sus va afişa în browser mesajul introdus între ghilimele. Funcţia echo, la
fel ca şi print, nu este chiar o funcţie, ci mai degrabă un constructor al limbajului şi nu este
nevoie să folosiţi parantezele ca pentru o funcţie. De fapt, dacă doriţi să trimiteţi mai mulţi
parametri către echo, nu trebuie să includeţi aceşti parametrii între paranteze. Există chiar şi o
variantă mai scurtă a lui echo, dar aceasta funcţionează doar dacă este setat în configuraţia
php.ini directiva short_open_tag pe ON. Sintaxa pentru varianta scurtă este:

<?=$foo?>

În cazul de mai sus, imediat după deschiderea tagului php se va afişa valoarea variabilei $foo.
Nu recomand această abordare, deoarece nu toate serverele au setată în configuraţia lor
short_open_tag pe ON şi nu va funcţiona.
O funcţie asemănătoare cu echo este print. La fel ca şi echo, nici aceasta nu este chiar o
funcţie ci un constructor al limbajului, şi nu trebuie să utilizaţi parantezele. Textul ce urmează
a fi afişat trebuie introdus între ghilimele simple sau duble, rezultatul fiind uşor diferit.
Folosind ghilimelele duble, orice variabilă din cadrul stringului este parsată. Astfel, dacă am
avea de exemplu:

<?php

$x = 1;

$rezultat = $x*1;

print "Rezultatul inmultirii lui $x cu 1 este $rezultat";

?>

afişează în browser:

Rezultatul inmultirii lui 1 cu 1 este 2

Dacă am folosi ghilimelele simple (print '...'), variabilele $x şi $rezultat nu ar fi fost parsate şi
output-ul ar fi fost:

Rezultatul inmultirii lui $x cu 1 este $rezultat

Putem afişa variabilele şi dacă folosim ghilimelele simple, "rupând" stringul şi intercalându-l cu
variabile, în forma urmatoăre, folosind operatorul "."(punct) de concaternare a stringurilor
(şirurilor):

<?php

print 'Rezultatul inmultirii lui '.$x.' cu 1 este '.$rezultat;

?>

Pentru a afişa caracterele speciale folosite de PHP (ghilimelele simple ', ghilimelele duble ",
backslash-ul \, semnul $) trebuie să le precedaţi cu semnul \, astfel:

<?php

echo "Semnul dolar \$, back-slash \\";

?>

Ghilimelele trebuie precedate de semnul \ doar dacă sunt de acelaşi tip cu cele care încadrează
string-ul. În plus, într-un string puteţi folosi celelalte ghilimele normal. Dacă doriţi să afişaţi
doar valoarea unei variabile, puteţi să nu o încadraţi între ghilimele. Exemplu:

<?php

echo $x;

?>

Alte informaţii despre aceste funcţii, precum şi altele asemănătoare cu acestea, de genul
printf(), şi flush() puteţi găsi în manualul oficial pe care îl puteţi lua gratuit de pe site-ul oficial
al PHP - www.php.net.
Construieşte un site cu php

În continuare, o să încerc să vă prezint cum se poate construi un site cu ajutorul limbajului


PHP. Exemplul prezentat nu este un standard, este doar o modalitate de a vedea cum se poate
construi un site şi cum se preiau sau trimite variabilele prin intermediul site-ului. Puteţi, pe
baza acestui exemplu, să vă construiţi propriul site, în forma preferată de dvs. şi adaptând
modelul acesta la necesitaţile voastre.
În exemplul meu, am preferat să am o singură pagină, anume index.php, în care să includ
dinamic conţinutul şi meniul, în funcţie de ce link accesează vizitatorul. Puteţi vedea acest
model într-un fel modular, fiecare script fiind de fapt un modul care execută anumite operaţii
specifice. Astfel, în pagina index.php se includ mai multe module (scripturi) care luate separat,
fiecare fac anumite lucruri, dar puse împreună, formează pagina de web generată dinamic. În
acest exemplu, nu am folosit o bază de date, dar pe acelaşi principiu se poate adapta ideea la
un site care preia datele din baza de date.

Partea de sus a paginii (head) După cum puteţi vedea alăturat, am despărţit
Partea cu meniul orizontal generat dinamic fiecare parte a unei pagini în bucăţi, fiecare
(partea de body) bucată este colorată diferit pentru o mai bună
aici se pot vizualizare. Puteţi introduce în fiecare bucată
partea in care se afiseaza pune alte câte un script php care să genereze respectiva
meniul
continutul paginilor, si alte informatii bucată dinamic. Astel, în cazul unei modificări,
lateral
informatii generate va fi mult mai uşor să modificaţi doar scriptul
dinamic care se ocupa de o anumită parte a paginii, pe
partea de incheiere a paginii (footer) când daca tot site-ul ar fi fost facut static în
HTML, la un site cu 100-200 de pagini chiar şi
cea mai mică modificare ar fi însemnat un chin.

Am numit fiecare script care se ocupă de o anumită parte a site-ului astfe:


head.php - conţine partea dintre tagurile HTML <head> şi </head>
body.php - conţine partea dintre tagurile HTML <body> şi conţinutul paginii
footer.php - conţine partea de jos a paginii

În continuare, o să vă prezint fiecare modul în parte.


index.php -
- head.php -
- css.php -
- js.php -
- body.php -
- meniu_orizontal.php -
- meniu_vertical.php -
- continut.php -
- contact.php -
- module.php -
- /module/data_ora.php -
- footer.php -

index.php - în care se setează nivelul de raportare al erorilor (dacă nu doriţi ca vizitatorii să


vada eventualele erori raportate de către php, puteţi stabili nivelul 0).Apoi, se verifică dacă
există fisierul head.php şi body.php şi se încarcă sau se opreşte cu un mesaj de eroare.
head.php - în acest fişier se afisează codul html pentru începutul paginii, şi dacă există, se
încarcă şi fişierele cu cod CSS şi JavaScript folosite în pagină.
css.php - acest fişier conţine codul CSS folosit pentru formatarea şi afişarea paginii HTML.
js.php - dacă se foloseşte cod JavaScript în pagini, este de preferat să se salveze codul în
acest fişier, pentru a putea avea acces rapid la el în cazul în care doriti să faceţi modificări.
body.php - conţine codul HTML existent între tagurile <body> şi </body> Dacă există, se
încarcă şi fişierele care conţin meniul orizontal şi/sau vertical, precum şi fişierul care afişează
conţinutul paginii cerute. Pe langă acestea, dacă doriţi să bagaţi alte scripturi în pagini, se
include şi fisierul module.php
meniu_orizontal.php - conţine codul HTML pentru meniul orizontal.
meniu_vertical.php - conşine codul HTML pentru meniul vertical
continut.php - afişează conşinutul paginilor, în funcţie de linkul cerut. Dacă se cer pagini
externe, se verifică daca acea pagină există şi se încarcă pentru afişare.
contact.php - poate fi o pagina externă, cu conţinut HTML sau PHP, precum şi formulare de
contact.
module.php - este un fişier care atunci când este accesat, verifică ce fişiere există în
directorul MODULE şi le încarcă pe fiecare.
data_ora.php - este un fişier extern, care afişează câteva informaţii despre vizitator.
footer.php - este fişierul care afişează în josul paginii numele curent al paginii

Acest exemplu îl puteţi descărca de aici şi îl puteţi testa şi modifica pe serverul dvs.

Câteva informaţii despre documentarea şi depanarea unui script.

În afară de a furniza nume descriptive fişierelor care conţin scripturile dvs. PHP, trebuie să
includeţi în fiecare script atât comentarii care să permită unui cititor să determine cu uşurinţă
utilitatea scriptului, cât şi alte informaţii referitoare la script. De exemplu, puteţi include un
comentariu care precizează numele fişierului care conţine scriptul, astfel încât acesta să apară
în versiunile tipărite ale scriptului. Iată un model sintactic pentru comentariile PHP:

// Scrieti aici comentariul dvs.

După cum se poate vedea, un comentariu începe cu două caractere slash, urmate de un
spatiu. În continuare, linia conţine comentariul, care poate include orice caractere doriţi,
inclusiv caractere speciale.
O modalitate de a crea un comentariu pe mai multe linii este de a începe fiecare linie cu
ajutorul caracterelor //. Totuşi, puteţi crea un comentariu din mai multe linii şi în alte moduri,
dacă preferaţi. Iată un exemplu:

/*
Acesta este un comentariu pe mai multe linii.
Poate fi alcatuit dintr-un numar oricat de mare de linii.
*/

Pentru a începe un comentariu alcătuit din mai multe linii, scrieţi caracterele /*, iar pentru a
încheia comentariul, scrieţi caracterele */
Între cele două perechi de caractere, puteţi scrie orice text doriţi, folosind oricâte linii doriţi.

Uneori, în locul datelor de ieşire ale scriptului, puteţi vedea unul din următoarele:
- Textul scriptului, în loc de datele de ieşire ale acestuia
- O casetă de dialog, prin care sunteţi întrebat dacă doriţi să descărcaţi fişierul care conţine
scriptul.
- Un mesaj în care se spune că scriptul nu există
- Un mesaj în care se spune că browserul web nu are permisiunea de a obţine accesul la script
- Un mesaj în care se spune că scriptul conţine o eroare

La vizualizarea rezultatelor unui script PHP se pot produce numeroase erori, chiar dacă scriptul
în sine e corect. Dacă vedeţi textul scriptului sau o casetă de dialog prin care sunteţi întrebat
dacă doriţi să descărcaţi fişierul care conţine scriptul, este posibil ca extensia fişierului script
să fie incorectă sau ca serverul PHP să nu funcţioneze. Deşi fişierele script PHP trebuie să aibă,
în general, extensia .php, este posibil ca un administrator de sistem să configureze un server
PHP astfel încât acesta să impună o altă extensie de fişier.
Dacă vedeti un mesaj în care se spune că scriptul nu există, este posibil ca să fi tastat incorect
adresa URL. Verificaţi dacă aţi tastat corect adresa URL precum şi dacă aţi ataşat corect la
aceasta numele fişierului care conţine scriptul, folosind un slash numai dacă adresa URL nu se
încheie cu un atare caracter.
Dacă vedeţi un mesaj în care se arată că browserul web nu are permisiunea de a obţine
accesul la script, poate că este necesar să modificaţi permisiunile fişierului script (cmod).
Dacă vedeţi un mesaj în care se spune că scriptul conţine o eroare, verificaţi dacă nu au
apărut următoarele probleme:
- O eroare de tastare, cum ar fi scrierea greşită a cuvântului echo
- O eroare de punctuaţie, cum ar fi paranteze, ghilimele duble sau punct şi virgulă lipsă sau
inserate greşit.
- Neincluderea sau includerea eronată a liniilor de delimitare a scriptului, în speţă <?php şi ?>
- Un marcaj de comentariu (//) care lipseşte sau a fost introdus gresit.

Şirurile şi caracterele speciale

Spre deosebire de numere întregi şi de numere duble, care conţin cu precădere cifre, şirurile
pot conţine orice caracter. Ca atare, şirurile sunt utile pentru stocarea datelor care nu pot fi
calculate, precum nume şi adrese. De asemenea, şirurile pot fi utilizate pentru stocarea
datelor numerice. Pentru a specifica un şir în PHP, caracterele care alcătuiesc şirul sunt incluse
între ghilimele duble; de exemplu, şirul reprezentând numele "Albert Einstein". Aşa cum am
mai spus, un şir poate conţine date numerice; de exemplu , "3.141516". PHP facilitează
includerea în şiruri a unor caractere speciale, precum caracterele de salt la linie nouă sau retur
de car, prin furnizarea de secvenţe escape care reprezintă caractere speciale. Iată secvenţele
escape folosite în PHP:

\n - salt la linie noua


\r - retur de car
\t - caracter de tabulare pe orizontală
\\ - backslash
\$ - simbolul dolarului
\" - ghilimele duble

Ca exemplu, iată un şir care include un retur de car, urmat de un salt la linie nouă:

"Salut! \r\n".

Reţineţi că fiecare secvenţă escape începe cu un backslash (\). Pentru a include un backslash
într-un şir, trebuie să folosiţi secvenţa escape adecvată, care este alcătuită din două caractere
backslash. Pentru a introduce ghilimele duble în cadrul unui şir fără a folosi secventa escape,
puteţi include şirul între ghilimele simple astfel:

'Pe ea o cheama "Nikita"'

Aceasta este util când doriţi să introduceţi într-un şir taguri HTML, astfel:

$sir = '<a href="index.php" target="_blank">Prima pagină</a>';

După cum observaţi deoarece standardul HTML necesită folosirea ghilimelelor pentru a nu se
încurca cu codul php am folosit pentru acest sir ghilimele simple. Sigur, acest cod se poate
scrie şi asa:

$sir = "<a href=\"index.php\" target=\"_blank\">Prima pagină</a>";


dar personal mi se pare greu inteligibil acest cod şi la un volum mare de date pot apare multe
erori datorate scrierii incorecte a codului html în interiorul codului php.

Operatori PHP

Interpretorul PHP permite folosirea a nouă tipuri diferite de operatori. Aceştia operează asupra
unor expresii (una, doua sau trei) şi furnizează ca rezultat o altă expresie (rezultatul operaţiei
corespunzătoare).

Operatori aritmetici:
Toţi operatorii aritmetici operează asupra a două expresii (operanzi). Există cinci astfel de
operatori:
- adunare ('+');
- scădere ('-');
- înmulţire ('*');
- împarţire ('/');
- rest ('%').
Aceste operaţii se aplică asupra unor valori care reprezintă tipuri numerice. Dacă unul dintre
operanzi nu are tip numeric, atunci el va fi convertit automat la o valoare întreagă. Dacă cel
puţin unul dintre operanzi (după efectuarea eventualelor conversii necesare) este un număr
real, atunci rezultatul operaţiei va fi tot un număr real, cu excepţia operatorului rest; rezultatul
operaţiei de determinare a restului este întotdeauna un număr întreg. Dacă ambii operanzi
sunt numere întregi, atunci rezultatul va fi un număr întreg, cu excepţia împărţirii al cărei
rezultat este întotdeauna un număr real. Dacă operatorul rest este aplicat asupra unor numere
reale, atunci rezultatul este un număr întreg. Nu este permisă împărţirea la valoarea 0. Dacă
al doilea operand asupra căruia se aplică unul dintre operatorii '/' sau '%' are valoarea 0, va fi
semnalată o eroare.

Operatori de comparare:
Interpretorul PHP pune la dispozitie mai mulţi operatori care pot fi folosiţi pentru compararea a
două valori. Expresiile în care apar astfel de operatori au ca rezultat valori logice (true sau
false).
Cel mai des întâlnit operator este cel de atribuire, definit prin semnul =
Dacă scriem $x = 1 nu înseamnă că $x este egal cu 1 ci că i s-a acordat valoarea 1. Dacă
scriem $rezultat = $x + $y nu înseamnă că $rezultat este egal cu suma celor două, ci că i-am
atribuit (acordat) valoarea sumei celor două.
Operatorul de egalitate este == si se foloseşte cel mai des în propoziţii condiţionale, pentru a
testa egalitatea. Opusul său, !=, este operatorul de inegalitate şi se foloseşte în acelaşi scop.
Operatorul de egalitate se foloseşte pentru a compara egalitatea a două valori. Pentru a vă
lămuri cum stă treaba cu egalitatea şi atribuirea, testaţi următorul cod:

Cod:

<?php
$x = 1;
$y = 7;
if ($x == $y)
{
print "$x este egal cu $y";
}
if ($x != $y)
{
print "$x este diferit de $y";
}
?>

Alţi operatori folosiţi pentru compararea valorilor variabilelor sunt:


'>' mai mare
'>=' mai mare sau egal
'<' mai mic
'<=' mai mic sau egal

Exemplu:

Cod:

<?php
$x = 5;
$y = 4;
if ($x > $y)
{
print "$x este mai mare ca $y";
}
if ($x <= $y)
{
print "$x este mai mic sau egal cu $y";
}
?>

'==' - rezultatul este true dacă cele două expresii au aceeaşi valoare;
'===' - rezultatul este true dacă cele două expresii au aceeaşi valoare şi au acelaşi tip;
'!=' sau '<>' - rezultatul este true dacă cele două expresii au valori diferite;
'!==' - rezultatul este true dacă cele două expresii au valori diferite sau au tipuri diferite;
'<' - rezultatul este true dacă valoarea primei expresii este mai mică decât valoarea celei de-
a doua expresii;
'>' - rezultatul este true dacă valoarea primei expresii este mai mare decât valoarea celei de-
a doua expresii;
'<=' - rezultatul este true dacă valoarea primei expresii este mai mică sau egală cu valoarea
celei de-a doua expresii;
'>=' - rezultatul este true dacă valoarea primei expresii este mai mare sau egală cu valoarea
celei de-a doua expresii.

Pe lângă acestea există şi operatorul condiţional '?' care are forma expresie1?
expresie2:expresie3 şi are ca rezultat valoarea expresiei expresie2 dacă valoarea expresiei
expresie1 este true (eventual după conversia la tipul boolean) sau valoarea expresiei
expresie3 în caz contrar.

Operatori pentru şiruri de caractere:


Operatorii pentru stringuri sunt '.' (punct) pentru concaternare şi '.=' (punct şi egal) pentru
atribuirea concaternării. Aceşti operatori sunt folosiţi pentru a unii stringuri, în felul urmator:

Cod:

<?php
// concaternarea stringurilor
$test = 'Am scris un '.'text'.'oarecare';
print $test;
// pe ecran va fi afisat "Am scris un text oarecare"

// concaternarea stringurilor cu variabile


$nr = 5;
print 'Am scris numarul '.$nr.' si un text '.' oarecare';
// pe ecran va fi afisat "Am scris numarul 5 si un text oarecare"

// atribuirea concaternarii
$nr = 6;
$text = "Un text ";
$text .= "oarecare ";
$text .= "si numarul ".$nr;
print $text;
// pe ecran va fi afisat "Un text oarecare si numarul 6"
?>

Operatori pe biţi şi operatori logici:


Interpretorul PHP pune la dispoziţie şase operatori care operează asupra biţilor unui număr
întreg sau ai unui şir de caractere. Aceştia sunt:
- conjuncţie ('&') - SI (AND);
- disjuncţie ('|') - SAU (OR);
- disjuncţie exclusivă ('^') - SAU exclusiv (XOR);
- negaţie ('~') - NU (NOT);
- deplasare la stânga ('<<');
- deplasare la dreapta ('>>').

Operatorii logici vă vor veni la îndemână în execuţia scriptului atunci când aveţi nevoie să
lucraţi cu valori de adevăr. Să presupunem că la intrarea în secţiunea de administrare avem
un formular care cere numele şi parola de acces în secţiune. Pentru contruirea expresiilor
logice operanzii trebuie să aibă tipul boolean; dacă operatorii au alt tip, valoarea este
convertită la o valoare booleană. Scriptul PHP ar putea verifica aceste informaţii pentru a
autoriza accesul în secţiune folosind operatorii logici astfel:
- operatorul 'xor' (SAU exclusiv)
Expresia în care apare operatorul 'xor' va avea valoarea true dacă exact unul dintre operanzi
are valuarea true

- operatorul '!' (NOT)


if (!parola_e_buna) ... parola nu este bună, accesul este interzis
if (!parola_nu_e_buna) ... parola e bună, accesul este permis
Operatorul '!' returneaza TRUE dacă valoarea iniţială de adevăr e FALSE şi FALSE dacă
valoarea iniţială este TRUE.

- operatorul '||' (OR)


if (numele_este_valid) || parola_este_buna) ...
verifică dacă numele sau parola sunt valide şi dacă oricare dintre ele este, returnează valoarea
de adevăr TRUE. În acest exemplu de pseudocod dacă numele ar fi valid dar parola nu, i-am
acorda utilizatorului acces mai departe, ceea ce nu este de dorit. Trebuie să fim siguri că şi
numele şi parola sunt valide. Operatorul '||' returnează TRUE dacă oricare din valorile
verificate e TRUE. Returnează FALSE doar dacă amândouă sunt FALSE.

- operatorul '&&' (AND)


if (numele_este_valid && parola_este_buna) ...
dacă atât numele cât şi parola sunt valide putem acorda utilizatorului acces în secţiunea de
administrare. Operatorul '&&' returnează TRUE doar dacă ambele valori verificate sunt TRUE.
El returnează FALSE dacă oricare dintre ele este FALSE (sau dacă amândouă sunt FALSE).

Operatori de atribuire:
Primul operand asupra căruia este aplicat un astfel de operator de atribuire trebuie să fie o
variabilă, iar al doilea poate fi o expresie.
Operaţia Varianta scurtă Varianta standard
adunare ('+=') $a += 2 $a = $a + 2
scădere ('-=') $a -= 2 $a = $a -2
înmulţire ('*=') $a *= 2 $a = $a *2
împărţire ('/=') $a /= 2 $a = $a /2
rest ('%=') $a %= 2 $a = $a %2
conjuncţie ('&=') $a &= 2 $a = $a &2
disjuncţie ('|=') $a |= 2 $a = $a |2
disjuncţie exclusivă ('^=') $a ^= 2 $a = $a ^2
deplasare la stânga ('<<=') $a <<= 2 $a = $a << 2
deplasare la dreapta ('>>=') $a >>= 2 $a = $a >> 2
concaternare ('.=') $a .= "2" $a = $a . "2"

Exemplu:

Cod:

<?php
$b = 2;
$a = 1;
echo "<TT>$a += $b = ";
echo $a += $b;

$b = 2;
$a = 1;
echo "<br>$a -= $b = ";
echo $a -= $b;

$b = 2;
$a = 1;
echo "<br>$a *= $b = ";
echo $a *= $b;

$b = 2;
$a = 1;
echo "<br>$a /= $b = ";
echo $a /= $b;

$b = 2;
$a = 1;
echo "<br>$a %= $b = ";
echo $a %= $b;

$b = 2;
$a = 1;
echo "<br>$a &= $b = ";
echo $a &= $b;

$b = 2;
$a = 1;
echo "<br>$a |= $b = ";
echo $a |= $b;

$b = 2;
$a = 1;
echo "<br>$a ^= $b = ";
echo $a ^= $b;

$b = 2;
$a = 1;
echo "<br>$a <<= $b = ";
echo $a <<= $b;

$b = 2;
$a = 1;
echo "<br>$a >>= $b = ";
echo $a >>= $b;

$b = 2;
$a = 1;
echo "<br>$a .= $b = ";
echo $a .= $b;
echo "</TT>";
?>

Rezultatul codului de mai sus este:

1 += 2 = 3
1 -= 2 = -1
1 *= 2 = 2
1 /= 2 = 0.5
1 %= 2 = 1
1 &= 2 = 0
1 |= 2 = 3
1 ^= 2 = 3
1 <<= 2 = 4
1 >>= 2 = 0
1 .= 2 = 12

Operatori de incrementare şi decrementare:


Operatorul de incrementare (++) are ca efect creşterea cu 1 a valorii unei variabile, iar cel de
decrementare (--) are ca efect scăderea cu 1 a valorii variabilei. Tipul variabilei poate fi întreg
sau real. Dacă operatorul precede variabila, atunci rezultatul expresiei este valoarea obţinută
după incrementare sau decrementare. Dacă variabila precede operatorul, atunci rezultatul
expresiei este valoarea variabilei înaintea incrementării sau decrementării. Cu alte cuvinte,
dacă operatorul precede variabila, atunci valoarea variabilei este mai întâi modificată şi apoi
utilizată, iar dacă variabila precede operatorul, atunci valoarea ei este mai întâi utilizată şi apoi
modificată.
Aceşti operatori pot fi utilizaţi şi pentru variabile care conţin şiruri de caractere. Operatorul de
incrementare duce la creşterea cu 1 a codului ASCII a ultimului caracter din şir dacă acesta
este o litera sau cifră. În cazul în care litera este 'z', respectiv 'Z', sau cifra este '9', atunci ea
devine 'a', respectiv 'A', sau cifra '0' şi se încearcă incrementarea penultimului caracter. Dacă
aceasta este tot '9', 'z' sau 'Z' se aplică acelaşi procedeu şi se trece la antepenultimul
caracter. Procedeul continuă până în momentul în care se ajunge la un caracter care nu este
'9', 'z' sau 'Z' sau se ajunge la începutul şirului. În acest ultim caz, la începutul şirului se
adaugă caracterul '1', 'a' sau 'A'. Incrementarea nu are nici un efect pentru caracterele care
nu sunt cifre sau litere.
Decrementarea şirurilor de caractere nu are nici un efect, valorile variabilelor rămânând
nemodificate. Există o singură excepţie şi anume şirurile care reprezintă numere întregi sau
reale. Acestea sunt incrementate sau decrementate potrivit regulilor pentru valorile numerice.

Exemplu:
Cod:

<?php
$a = 7;
echo "<tt>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>a++</tt><i> este </i><tt>
";
echo $a++;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>++a</tt><i> este </i><tt>
";
echo ++$a;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>a--</tt><i> este </i><tt>
";
echo $a--;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>--a</tt><i> este </i><tt>
";
echo --$a;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
$a = 7.5;
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>a++</tt><i> este </i><tt>
";
echo $a++;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>++a</tt><i> este </i><tt>
";
echo ++$a;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>a--</tt><i> este </i><tt>
";
echo $a--;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>--a</tt><i> este </i><tt>
";
echo --$a;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
$a = "PHP";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>a++</tt><i> este </i><tt>
";
echo $a++;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>++a</tt><i> este </i><tt>
";
echo ++$a;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>a--</tt><i> este </i><tt>
";
echo $a--;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "<br>a = $a";
echo ": </tt><i>Rezultatul operatiei </i><tt>--a</tt><i> este </i><tt>
";
echo --$a;
echo "</tt>. <i>Noua valoare a variabilei </i><tt>a</tt><i> este </i><t
t>$a.";
echo "</tt>";
?>

Rezultatul codului de mai sus este:

a = 7: Rezultatul operatiei a++ este 7. Noua valoare a variabilei a este 8.


a = 8: Rezultatul operatiei ++a este 9. Noua valoare a variabilei a este 9.
a = 9: Rezultatul operatiei a-- este 9. Noua valoare a variabilei a este 8.
a = 8: Rezultatul operatiei --a este 7. Noua valoare a variabilei a este 7.
a = 7.5: Rezultatul operatiei a++ este 7.5. Noua valoare a variabilei a este 8.5.
a = 8.5: Rezultatul operatiei ++a este 9.5. Noua valoare a variabilei a este 9.5.
a = 9.5: Rezultatul operatiei a-- este 9.5. Noua valoare a variabilei a este 8.5.
a = 8.5: Rezultatul operatiei --a este 7.5. Noua valoare a variabilei a este 7.5.
a = PHP: Rezultatul operatiei a++ este PHP. Noua valoare a variabilei a este PHQ.
a = PHQ: Rezultatul operatiei ++a este PHR. Noua valoare a variabilei a este PHR.
a = PHR: Rezultatul operatiei a-- este PHR. Noua valoare a variabilei a este PHR.
a = PHR: Rezultatul operatiei --a este PHR. Noua valoare a variabilei a este PHR.

Aceşti operatori sunt utili de exemplu pentru monitorizarea unui download, dacă doriţi să ştiţi
de câte ori a fost descărcat un fişier dintr-o anumită pagină. La fiecare accesare a fişierului,
scriptul incrementează cu 1 şi afişează valoarea. (scriptul îl gândiţi voi, doar nu vreţi totul la
tavă)

Operatori pentru controlul erorilor:


În PHP există un operator (@) care permite ignorarea erorilor. Dacă este aplicat asupra unei
expresii care ar duce la afişarea unui mesaj de eroare, atunci mesajul respectiv nu va fi afişat.

Operatori de execuţie:
Interpretorul PHP permite executarea unor comenzi sistem prin intermediul operatorului (` `)
. Comanda respectivă este cuprinsă între apostroafele inverse (tasta de lângă 1 deasupra
tastei tab), iar rezultatul acestei comenzi este un şir de caractere care reprezintă şi rezultatul
expresiei.
Urmatorul script PHP determină execuţia pe server a comenzii help /? şi afişarea rezultatului
în fereastra programului de navigare.
Cod:

<?php
echo "<PRE>".`help /?`."</PRE>";
?>

Atenţie!
Pe unele configuraţii de server nu se permite executarea de comenzi prin intermediul PHP (ca
măsură de siguranţă, altfel oricine ar putea da un format sau reboot la server prin intermediul
unui script PHP).

Operatori pentru vectori:


Singurul operator care poate fi aplicat asupra vectorilor este cel de concaternare (+)
Rezultatul concaternării a doi vectori este un vector care conţine elementele din cei doi vectori.
Dacă cei doi vectori conţin elemente cu aceeaşi cheie, atunci este păstrat doar elementul din
vectorul care reprezintă primul operand.

Exemplu:

Cod:

<?php
$x[2] = 2;
$x[4] = 4;
$x[5] = 5;
$x[7] = 7;
$y[1] = 100;
$y[2] = 200;
$y[3] = 300;
$y[4] = 400;
$y[5] = 500;
$z = $x + $y;
echo "$z[1] $z[2] $z[3] $z[4] $z[5] $z[7]";
?>

Rezultatul codului de mai sus este:

100 2 300 4 5 7

Ordinea operaţiilor:
Evident, o expresie poate conţine mai mulţi operatori, din categorii diferite. Pentru a indica
ordinea în care trebuie efectuate calculele, trebuie stabilită o ordine a operaţiilor. Pentru
aceasta a fost definită precedenta şi asociativitatea operaţiilor.
Valoarea expresiilor corespunzătoare operatorilor cu precedenta mai mare va fi calculată
înaintea valorilor expresiilor cu o precedentă mai mică. De exemplu, pentru expresia 1 + 2 *
3 va fi efectuată mai întâi înmulţirea 2 * 3, datorită faptului că operatorul '*' are precedenta
mai mare decât cea a operatorului '+'.
Dacă o expresie sau o subexpresie conţine numai operatori cu aceeaşi precedentă, atunci
operaţiile se vor efectua în ordinea determinată de asociativitatea acestor operatori care poate
fi de la dreapta la stânga sau de la stânga la dreapta. Toţi operatorii cu aceeaţi precedentă au
aceeaşi tip de asociativitate.
Evident, pentru a modifica ordinea implicită de efectuare a operaţiilor pot fi folosite paranteze
pentru a indica faptul că o anumită operaţie trebuie efectuată înaintea altora, chiar dacă
acestea din urmă au o precedentă mai mare.
Trebuie observat faptul că, datorită asociativităţii de la dreapta spre stânga a operatorilor de
atribuire, expresiile de tipul $a = $b = 1 sunt valide. Mai întâi se va efectua atribuirea $b =
1; variabila $b va primi valoarea 1 şi, datorită faptului că rezultatul unei operaţii de atribuire
este valoarea atribuită variabilei care reprezintă primul operand, în continuare se va efectua
atribuirea $a = 1, deci şi variabila $a va primi tot valoarea 1. Tabelul de mai jos conţine o
listă cu majoritatea operatorilor din PHP. Liniile tabelului indică precedenta, în sensul că un
operator are aceeaşi precedentă cu operatorii de pe linie în care apare şi o precedentă mai
mare decât oricare operator aflat pe o linie anterioară. În acest tabel se observă faptul că, deşi
operatorii '&&' şi 'and', respectiv '||' şi 'or' realizează aceeaşi operaţie, ei au precedente
diferite, deci nu sunt echivalenţi din toate punctele de vedere.

Tip asociativitate Tip Operanzi


de la stânga la dreapta unar . (selectare)
de la stânga la dreapta binar or
de la stânga la dreapta binar xor
de la stânga la dreapta binar and
de la stânga la dreapta binar print
=
+=
-=
*=
/=
.=
de la stânga la dreapta binar %=
&=
|=
^=
~=
<<=
>>=
de la stânga la dreapta ternar ?:
de la stânga la dreapta binar ||
de la stânga la dreapta binar &&
de la stânga la dreapta binar |
de la stânga la dreapta binar ^
de la stânga la dreapta binar &
==
!=
fără asociativitate binar
===
!==
<
<=
fără asociativitate binar
>
>=
<<
de la stânga la dreapta binar
>>
+
de la stânga la dreapta binar -
. (concaternare)
*
de la stânga la dreapta binar /
%
de la stânga la dreapta unar !
~
++
--
(int)
(float)
(string)
(array)
(object)
@
de la stânga la dreapta unar [
fără asociativitate unar new

În tabel este prezentat şi numărul expresiilor asupra cărora acţionează un operand. Operatorii
unari acţionează asupra unei singure expresii, cei binari asupra a două expresii şi singurul
operator ternar asupra a trei expresii.

În continuare sunt câţiva operatori care execută operaţii utile:

- abs(x) - returnează valoarea absolută a lui x;


- ceil(x) - returnează valoarea x, rotunjită la întregul imediat superior;
- floor(x) - returnează valoarea x, rotunjită la întregul imediat inferior;
- max(x, y, ...) - returnează valoarea maximă a unui set de valori;
- min(x, y, ...) - returnează valoarea minimă a unui set de valori;
- pow(x, n) - returnează numărul x, ridicat la puterea specificată n;
- strftime(f) - returnează data curentă, formatată conform conţinutului parametrului f;
- sqrt(x) - returnează rădăcina pătrată a lui x

Mai jos sunt cateva exemple:

$lungime = sqrt($arie);

Acest exemplu calculează lungimea laturilor unui pătrat, dacă este cunoscută aria pătratului.
În continuare este prezentat modul de utilizare al funcţiei max, care preia mai multe
argumente:

$punctaj_castigator = max($punctaj1, $punctaj2, $punctaj3);

Un alt exemplu calculează aria unui cerc de rază dată:

Cod:

<?php
$raza = 2.0;
$pi = 3.14159;
$arie = $pi * $raza * $raza;
echo "raza = ";
echo $raza;
echo "<br>arie = ";
echo $arie;
?>

Câteva idei utile pentru securitatea paginilor web

Regula numărul unu a securităţii online este: nu vă încredeţi niciodată în utilizator.


Întotdeauna verificaţi datele trimise către server şi "curăţaţi-le" înainte de a le utiliza. Pentru
aceasta trebuie să luaţi în considerare câteva posibile "găuri" de securitate. Menţionez că cele
scrise aici sunt doar noţiuni generale, pentru o securitate ridicată ar trebui sa aveţi noţiuni
specializate de baze de date şi de administrare a serverelor web.

1. Variabilele globale
Având variabilele globale din php.ini setate pe ON puteţi accesa datele trimise prin formulare
mai simplu: $variabila în loc de $_GET['variabila'], la fel şi pentru POST sau FILES. Dacă
scriptul nu este foarte bine gândit, variabilele globale pot prezenta un risc major de securitate.
Din acest motiv php.ini este distribuit cu globals=off în ultimele versiuni.

2. Ghilimele "magice"
Dacă în php.ini magic_quotes_gpc sunt OFF folosiţi funcţia addslashes pentru a preceda
ghilimelele din datele trimise de utilizatori cu caracterul \. Dacă magic_quotes_gpc sunt ON,
PHP adaugă automat caracterul \ înainte de ghilimele dar dacă ele sunt OFF, ghilimelele din
input vă pot crea probleme serioase.
Ca exemplu, să presupunem că interogarea SQL de verificare a numelui şi a parolei pentru
înregistrarea pe site este

SELECT * FROM users WHERE nume='$nume' AND parola='$parola'

şi dacă interogarea este executată cu succes, utilizatorul este logat. În acest caz, folosind
parola 'OR' 1=1 oricine poate avea acces pe site deoarece interogarea

SELECT * FROM user WHERE nume='un nume oarecare' AND parola=" OR '1=1'

este executată cu succes şi returnează un rezultat (toate înregistrarile din baza de date, de
fapt). Mai mult, atunci când vă aşteptaţi ca baza de date să returneze un singur rând, verificaţi
acest lucru şi nu dacă interogarea s-a executat cu succes. Implicit în php.ini
magic_quotes_gpc sunt ON pentru a vă proteja de astfel de atacuri, dar este bine să verificaţi
înainte de a renunţa la addslashes.

3. Includere
Încercaţi să evitaţi includerea "vizibilă" a fişierelor în forma http://site.ro/fisier.php?
file=cutare.html pentru a include fişiere în cadrul unei pagini. Cu puţină neatenţie din partea
voastră atacatorul ar putea accesa astfel de informaţii sensibile din cadrul sistemului. Nu
includeţi fişiere străine. PHP poate "include" fişiere aflate pe alte servere decât cel care rulează
dacă setarea URL fopen wrappers este activată în php.ini. În exemplul de mai sus, un atacator
ar fi putut accesa adresa

http://site.ro/fisier.php?file=http://www.rau.ro/scriptultau.php

pentru a include în fisier un script localizat pe alt server şi astfel obţine acces către toate
resursele sistemului la care are acces PHP, putând rula comenzi de sistem, afişa informaţii
confidenţiale sau sterge baza de date. Nu permiteţi includerea fişierelor din altă parte decât de
pe serverul vostru. Setaţi allow_url_fopen=OFF în php.ini.

4. Formulare
Folosiţi metoda POST în formulare atunci când informaţia din acestea urmează să fie introdusă
în baza de date. Dacă variabilele globale sunt OFF în php.ini sau metoda de transmitere a
formularului este GET, un utilizator rău intenţionat ar putea accesa adresa dvs. şi ar introduce
comentariul lui (exemplu "blabla") în baza voastră de date fără să treacă propriuzis prin site.
Aşa vă puteţi trezi că nu mai aveţi spaţiu pe server iar în baza de date sunt câteva milioane de
comentarii care spun acelaşi lucru "blabla".
Verificarea provenienţei cererilor către server este foarte importantă şi în alt caz: formularele
de loghin. Cineva care ştie numele de utilizator ar putea încerca să vă găsească parola foarte
usor. În acest caz va trebui să puneţi o protecţie suplimentară care să nu permită mai mult de
X încercări consecutive eşuate de logare pentru un nume de utilizator. Această problemă se
rezolva uşor folosind sesiunile. În momentul când cineva încearcă să trimita numele şi parola
din formular putem seta o variabilă de sesiune $_SESSION['login_count'] care să ţină minte
numărul de încercări. Când valoarea acesteia trece de 3 (încercări nereuşite) nici măcar nu
mai interogaţi baza de date pentru a verifica datele trimise. Variabila de sesiune va rămâne în
memorie cât timp browserul este deschis şi sesiunea activă (opţiunea implicită a PHP de
menţinere a sesiunilor active este de o oră). Dacă atacatorul aşteaptă o ora sau îşi închide
browserul, sesiunea va fi închisă şi va putea de alte X ori să se logheze. De cele mai multe ori
acestă măsură de siguranta este suficientă pentru a preveni încercările de aflare a parolelor.
5. Extensii
O practică obişnuită este de a acorda extensia .inc fişierelor care conţin biblioteci de funcţii ce
urmează a fi incluse şi folosite în cod. PHP nu parsează fişierele cu extensia .inc şi dacă
acestea sunt apelate direct ele sunt trimise plain text către browser. Nu puneţi informaţii
sensibile (precum nume şi parola) în fişiere cu extensia .inc, .txt, sau .html care pot fi
accesate şi văzute. Folosiţi pentru aceste fişiere extensia .php care, dacă sunt accesate direct,
vor fi rulate fără să afişeze informaţiile conţinute în ele.

6. Comanda CHMOD - setarea atributelor


Comanda CHMOD (abreviere pentru change mode permissions of a file) este folosită pentru a
schimba modul de acces (de permitere) a fişierelor şi directoarelor de pe server. Setarea poate
afecta modul cum poate fi citit, sau cum se poate executa un fişier pe server. De exemplu,
dacă aveţi un fişier .php care trebuie să execute o comandă de scriere pe server într-un fişier
.txt trebuie să îi daţi dreptul să poata fi executat iar la fişierul .txt trebuie să îi daţi dreptul de
a se putea scrie în el. Aveti 3 tipuri de acces - OWNER - GROUP - WORLD - fiecare cu câte 3
setări - READ - WRITE - EXECUTE -
Este bine ca la WORLD să nu daţi decât acces la citire (pentru a putea accesa paginile de pe
site) dar nu şi drepturi de scriere sau execuţie (pentru că nu doriţi ca oricine să vă scrie ce
vrea în respectivul fişier .txt)
În programul TOTAL COMMANDER (pe care eu îl folosesc şi pentru FTP) setarea atributelor pe
server se face din meniul FILES - CHANGES ATTRIBUTES. Fiecare program de FTP are în
meniul lui setare pentru atributele fişierelor de pe server.

7. Cookies
Dacă aveţi o secţiune de administrare pe site, unde accesul este restrictionat doar la membrii
de exemplu, este bine ca în toate paginile din această secţiune să încludă o pagină de
verificare a accesului. Această pagina va verifica la fiecare accesare dacă utilizatorul este
înregistrat şi are acces pe pagina respectivă şi permite rularea paginii doar dacă utilizatorul
este înregistrat. Fără această verificare, un utilizator ar putea accesa paginile din secţiunea de
administrare fără să treacă prin formularul de înregistrare. După autentificarea propriu-zisă,
vom folosi variabile de sesiune pentru a păstra în memorie câteva informaţii despre
autentificare, pentru a le verifica mai târziu, atunci când accesăm alte pagini din cadrul
secţiunii de administrare. Pornim întâi sesiunea după care trecem la salvarea informaţiilor în
ea ca în exemplul de mai jos:

session_start();
$_SESSION ['nume_admin'] = $_POST ['nume'];
$_SESSION ['parola_encriptata'] = $parolaEncriptata;

Pe lângă acestea, pentru o şi mai mare siguranţă, vom salva id-ul sesiunii în altă variabilă.
Toate sesiunile au un id unic, un string care seamănă cu rezultatul unei criptări MD5:
$_SESSION ['key_admin'] = session_id();
Cu autentificare făcută, spunem scriptului să încarce prima pagină din secţiunea de
administrare:

header ("location: admin.php");

În continuare pentru a împiedica accesul neautorizat la paginile din această secţiune, scriem
un mic script de verificare a datelor sesiunii înainte de a încărca orice pagină din secţiunea de
administrare:

session_start();
if ($_SESSION ['key_admin'] != session_id ()) {
print 'Acces neautorizat!';
exit;
}

8. Loguri de acces
Pentru o verificare ulterioară a persoanelor care încearcă să intre în paginile restrictionate de
pe site, este bine să salvăm în baza de date (sau într-un fişier text) numele, parola criptata,
ora, data, semnătura browserului şi ip-ul. Aşa veţi ştii cine a încercat să vă spargă site-ul şi
puteţi crea un script care sa verifice de exemplu ip-ul şi dacă corespunde cu unul din cele care
sunt blocate să nu aibă acces la nici una din pagini (chiar dacă găseşte userul şi parola
corecte)

9. Criptarea parolelor cu MD5


Parolele care sunt salvate în baza de date este recomandat să le ţineţi criptate, astfel dacă
cineva încearcă să citeasca parolele le va vedea criptate.

INSERT INTO admin VALUES ("administrator", md5("parola"));

Criptarea folosind md5 nu este reversibila (şi astfel nici dvs., nici altcineva nu o va putea afla
chiar dacă are acces la baza de date).

10. Pagina index.php în subdirectoare


Dacă aveţi mai multe directoare şi subdirectoare pe server este recomandat pentru a preveni
accesul la datele aflate în aceste directoare să introduceţi în fiecare director o pagină numită
index.html sau index.php care să facă redirectarea automat către pagina principală a site-ului.
Astfel minimizati riscul să intre cineva şi să vadă tot ce este în aceste subdirectoare.

11. Fişierul .htaccess


Pentru a bloca accesul la un anumit director (sau chiar la tot site-ul) puteti crea un fişier numit
.htaccess (cu punct înainte) în care să introduceţi ip-ul care doriţi să îl blocaţi (sau care să
aibă acces)

Order Deny,Allow
Allow from all

În exemplul de mai sus, toată lumea are acces. Dacă de exemplu ip-ul 192.168.1.1 nu doriţi
să aibă acces la acel director scrieţi

Deny from 192.168.1.1

Atenţie, să nu vă blocaţi singuri ip-ul la site, că altfel trebuie să luaţi legătura cu


administratorul serverului să steargă fişierul ca să puteţi intra din nou pe site, sau sa scrieti
prin FTP un nou fişier .htaccess. (la subdirectoare ştergeţi directorul sau salvaţi un alt fişier
.htaccess) În cazul în care după de aţi pus fişierul pe server nu îl vedeţi, el este acolo dar
serverul seteaza acest nume de fişier ca fişier ascuns.

12. Roboţii de căutare


Motoarele de căutare pot indexa tot ce se află la voi pe site. Dacă doriţi ca un fişier sau
director să nu fie indexat de către motoarele de căutare, trebuie să creaţi un fişier numit
robots.txt care să se afle în directorul principal de pe site (nu în subdirectoare). În el scrieţi
următoarele comenzi:

# robots.txt for http://www.tutoriale.far-php.ro


User-agent: *
Disallow: /cache/
Disallow: /admin
disallow: /search

unde pentru fiecare director sau fişier se specifică locaţia şi numele. Pentru mai multă
siguranţă, am găsit pe web un mic script care verifică tipul de browser şi dacă nu este un
browser cunoscut nu permite accesul (dacă cineva încearcă să citească paginile cu programe
spion sau gen web offline).
Cum am specificat şi la începutul acestui articol, cele spuse mai sus nunt doar cateva indicii şi
idei pentru a vă putea proteja mai bine paginile.

Structuri de control în PHP

După cum ştiţi, instrucţiunile PHP sunt separate prin caracterul ';'. Deseori, suntem nevoiţi să
grupăm mai multe instrucţiuni pentru a forma un bloc. Astfel, obţinem instrucţiunile compuse
care sunt formate din mai multe instrucţiuni simple, separate prin caracterul ';'. În PHP,
instrucţiunile compuse au următoarea sintaxa:

{ instructiune #1 instructiune #2 ... instructiune #n }

Instrucţiunile care formează instrucţiunea compusă pot fi de orice tip: orice structură de
control, alte instrucţiuni compuse etc. Aşadar un bloc de instructiuni (o instrucţiune compusă),
în PHP, este delimitat de acolade.

Structura if

Una dintre cele mai importante structuri în orice limbaj este cea alternativa. În PHP sintaxa
acestei structuri este următoarea:

if (conditie) instructiune

Folosirea unei astfel de structuri indică faptul că instrucţiunea se va executa dacă şi numai
dacă valoarea expresiei conditie (eventual după conversia la tipul boolean) este true.

Construcţia if - else

În foarte multe cazuri dorim să executăm o altă instrucţiune dacă valoarea expresiei condiţie
este false. În PHP putem utiliza o construcţie de tipul if - else în acest scop. Sintaxa este:

if (conditie) instructiune #1
else instructiune #2

Construcţia elseif

Uneori, suntem nevoiţi să folosim structuri alternative îmbricate în diferite scopuri. Folosind
construcţii de tipul if - else vom obţine o secvenţă de tipul:

if (conditie #1) instructiune #1


elseif (conditie #2) instructiune #2
else ...
elseif (conditie #n) instructiune #n
else instructiune #n+1

Limbajul PHP permite folosirea unei prescurtări şi anume construcţia elseif. Practic, aceasta
înlocuieste un else urmat de un if. Folosind această structură, codul anterior poate fi scris
astfel:

if (conditie #1) instructiune #1


elseif (conditie #2) instructiune #2
elseif ...
elseif (conditie #n) instruciune #n
else instructiune #n+1

Sintaxe alternative

Dacă dorim să se execute mai multe instrucţiuni când este indeplinită o anumită condiţie,
atunci ar trebui să folosim instrucţiunile compuse. De exemplu, pentru o structură if vom
scrie:

if (conditie):
instructiune #1
instructiune #2 ...
instructiune #n
endif

Practic, pentru orice structură de control PHP, putem înlocui acolada deschisa prin caracterul
':' şi acolada închisă printr-un cuvânt cheie opţinut prin adăugarea prefixului end la cuvântul
cheie care indică structura de control. Trebuie observat faptul că else şi elseif nu sunt
structuri, ele fiind simple construcţii folosite în cadrul structurii if. Din acest motiv, nu vom
avea niciodată endelse sau endelseif, ci doar endif-uri. Aşadar, sintaxa alternativă pentru o
structură if în care se folosesc construcţii else şi elseif este următoarea:

if (conditie #1)
grup instructiuni #1
elseif (conditie #2)
grup instructiuni #2
elseif ...
elseif (conditie #n)
grup instructiuni #n
else grup instructiuni #n+1
endif;

Structura while

Majoritatea script-urilor PHP vor conţine cicluri. Pentru a folosi o buclă anterior condiţionată
vom utiliza structura while. Sintaxa acestei proceduri este:

while (conditie) instructiune

Efectul acestei structuri este executarea instrucţiunii atât timp cât valoarea expresiei condiţie
(eventual după conversia la tipul boolean) este true. Trebuie observat faptul că este posibil ca
instrucţiunea să nu fie executată niciodată. Si pentru această structură avem la dispoziţie o
sintaxă alternativă şi anume:

while (conditie):
grup instructiuni
endwhile;

Structura do - while

Uneori, dorim să folosim bucle posterior condiţionate. În acest scop, în PHP avem la dispoziţie
structura do - while a cărei sintaxă este:

do instructiune while (conditie);


Singura diferenţă faţă de structura while este faptul că valoarea condiţiei este determinată, de
fiecare dată, după executarea instrucţiunii. Ca urmare, instrucţiunea va fi executată cel puţin o
dată. Nu există o sintaxă alternativă pentru această structură.

Structura for

O alternativă cu o funcţionalitate mai ridicată pentru utilizarea buclelor este structura


repetitivă for. Sintaxa este foarte asemănătoare cu cea din limbajele C/C++ şi Java şi anume:

for (expresie #1; expresie #2; expresie #3)


instructiune

Prima expresie este evaluată o singură dată, înainte de începerea execuţiei ciclului.
Instrucţiunea este executată cât timp cea de-a doua expresie are valoarea true. De fiecare
dată, după executarea instrucţiunii, este evaluată cea de-a treia expresie. Oricare dintre cele
trei expresii poate lipsi; în cazul în care o expresie lipseste, se consideră că ea are valoarea
true. Pentru structura for poate fi folosită şi următoarea sintaxă alternativă:

for (expresie #1; expresie #2; expresie #3):


instructiune
endfor;

Exemple

În continuare aveţi un exemplu care afişează numerele cuprinse între 1 şi 15. Numerele pare
vor fi scrise cu roşu, iar cele impare care sunt divizibile cu 3 cu verde, iar celelalte cu albastru.
Vom folosi o structură repetitivă pentru a afişa numerele şi o structură alternativă pentru a
determina culoarea cu care vor fi afişate. Putem utiliza oricare dintre cele trei structuri
repetitive; codul PHP pentru cele trei variante este prezentat mai jos.

Cod:

<?php
// Structuri alternative si repetitive
// Bucla for
// Exemplu
for ($i = 1; $i <= 15; $i++):
echo "<b><font size = 3 ";
echo "color = ";
if ( ! ($i % 2))
echo "red";
elseif ( ! ($i % 3))
echo "green";
else
echo "blue";
echo "> $i </font></b>";
endfor;
?>

Cod:

<?php
// Structuri alternative si repetitive
// Bucla while
// Exemplu
$i = 1;
while ($i<=15)
{
echo "<b><font size = 3 ";
echo "color = ";
if ( ! ($i % 2))
echo "red";
elseif ( ! ($i % 3))
echo "green";
else
echo "blue";
echo "> $i </font></b>";
$i++;
}
?>

Cod:

<?php
// Structuri alternative si repetitive
// Bucla do - while
// Exemplu
$i = 1;
do
{
echo "<b><font size = 3 ";
echo "color = ";
if ( ! ($i % 2))
echo "red";
elseif ( ! ($i % 3))
echo "green";
else
echo "blue";
echo "> $i </font></b>";
$i++;
}
while ($i <= 15);
?>

Rezultat:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Structura foreach

Această structură poate fi folosită pentru a realiza o iteraţie printre toate elementele unui
vector. Aşadar, ea nu poate fi folosită decât împreună cu vectorii; utilizarea sa asupra unei
variabile de alt tip duce la apariţia de erori. Există două sintaxe acceptate pentru această
structură şi anume:

foreach (expresie_vectoriala as $valoare)


instructiune
sau

foreach (expresie_vectoriala as $cheie => $valoare)


instructiune

Dacă se utilizează prima variantă, atunci la fiecare iteraţie valoarea elementului curent este
atribuită variabilei $valoare şi apoi se trece la elementul următor (a cărui valoare va fi
atribuită variabilei la următoarea iteraţie). Execuţia ciclului se încheie în momentul în care nu
mai există alte elemente în vector. Singura diferenţa care apare în cazul utilizării celei de-a
doua variante este faptul că la fiecare iteraţie valoarea cheii elementului curent este atribuită
variabilei $cheie. În continuare este un exemplu de folosire a celor doua sintaxe ale structurii
foreach.

Cod:

<?php
// structura foreach
echo '<table width="100%"><tr><td with="50%">';
// un vector obisnuit
$a = array (1, 2, 3, 10);
echo "<b>Parcurgerea unui vector:</b><br><ol>";
foreach ($a as $v)
echo "<li><i>Valoarea curenta este </i>:<tt>$v</tt>\n<br>";
/* parcurgerea vectorului, contorizarea elementelor si afisarea num
arului de ordine al elementului curent */
$i = 0;

echo "</ol><b>O alta parcurgere: </b><ul>";


foreach ($a as $v)
{
echo "<li><tt>\$a[$i] => $v</tt>\n <br>";
$i++;
}

/* un vector ale carui elemente sunt identificate prin chei */


$a = array
(
"unu" => 1,
"doi" => 2,
"trei" => 3,
"zece" => 10
);
echo "</ul><td><width = 50%><b>Parcurgere cu afisarea cheilor: </b><ul>"
;
foreach ($a as $k => $v)
{
echo "<li><tt>\$a[$k] => $v</tt>\n";
}

// o matrice
$b[0][0] = "a";
$b[0][1] = "b";
$b[1][0] = "c";
$b[1][1] = "d";
echo "</ul><b>Parcurgerea unei matrice:</b><br><tt>";
foreach ($b as $v1)
{
echo "&nbsp;&nbsp;";
foreach ($v1 as $v2)
echo "$v2\n";
echo "<br>";
}
echo "</tt><br><b>Parcurgerea unui vector generat dinamic: </b><br><tt>
&nbsp;&nbsp;";

// un vector generat dinamic


foreach (array (1, 2, 3, 4, 5) as $v)
echo "$v\n";

echo "</tt></td></tr></table>";
?>

Rezultatul codului de mai sus este:


Parcurgerea unui vector:
Parcurgere cu afisarea cheilor:
1. Valoarea curenta este :1
2. Valoarea curenta este :2 • $a[unu] => 1
3. Valoarea curenta este :3 • $a[doi] => 2
4. Valoarea curenta este :10 • $a[trei] => 3
• $a[zece] => 10
O alta parcurgere:
Parcurgerea unei matrice:
a b
• $a[0] => 1
c d
• $a[1] => 2
• $a[2] => 3 Parcurgerea unui vector generat dinamic:
1 2 3 4 5
• $a[3] => 10

Structura switch

În anumite cazuri trebuie să efectuăm anumite operaţii în funcţie de anumite valori ale unei
expresii. O soluţie ar fi folosirea unor structuri if îmbricate sau a uneia singure în care apar
mai multe construcţii elseif.
Să presupunem că o anumită variabilă poate avea cinci valori distincte şi pentru fiecare
valoare trebuie executată o anumită instrucţiune. Dacă folosim structura if, secvenţa de cod
va fi următoarea:

if ($variabila == valoare #1)


instructiune #1
elseif ($variabila == valoare #2)
instructiune #2
elseif ($variabila == valoare #3)
instructiune #3
elseif ($variabila == valoare #4)
instructiune #4
else
instructiune #5
Folosind structura switch, secvenţa echivalentă este:

swich ($variabila) {
case valoare #1: instructiune #1
break;
case valoare #2: instructiune #2
break;
case valoare #3: instructiune #3
break;
case valoare #4: instructiune #4
break;
case valoare #5: instructiune #5
break;
}

Prezentăm în continuare sintaxa generală a structurii switch:

switch (expresie) {
case valoare #1: grup instructiuni #1
case valoare #2: grup instructiuni #2
...
case valoare #n: grup instructiuni #n
[default: grup instructiuni #n + 1]
}

Pentru început se determină valoarea expresiei şi apoi se verifică dacă aceasta apare ca
valoare pentru una dintre construcţiile case. În caz afirmativ, toate instrucţiunile începând cu
cea corespunzătoare valorii respective (până la sfârşitul blocului swich) vor fi executate.
Execuţia acestor instrucţiuni poate fi întreruptă dacă este folosită instrucţiunea break, care va
fi prezentată mai jos. Dacă valoarea expresiei nu corespunde nici uneia dintre valorile
corespunzătoare construcţiilor case, se execută instrucţiunile corespunzătoare construcţiei
default. Dacă aceasta lipseste, atunci nu se execută nici o instrucţiune. Trebuie precizat faptul
că valorile corespunzătoare construcţiilor case pot fi numere întregi, numere reale sau şiruri
de caractere; nu pot fi utilizate obiecte sau vectori.

Instrucţiunea break

Această instrucţiune poate fi folosită pentru a întrerupe forţat execuţia unui ciclu sau a
secvenţei de instrucţiuni corespunzătoare unei structuri switch. Instrucţiunea poate fi urmată
de un argument care indică numărul de structuri îmbricate a căror execuţie se încheie.
Valoarea implicită este 1, deci se întrerupe execuţia unei singure structuri. Următoarea
secvenţă de cod PHP realizează parcurgerea elementelor unui vector de numere întregi până în
momentul în care se întâlneşte un număr negativ.

Cod:

<?php
foreach ($a as $v)
if ($v < 0)
break;
?>

Mai departe aveţi cazul în care este întreruptă execuţia mai multor cicluri; vom considera că
parcurgem elementele unei matrice pătratice cu n elemente şi n coloane până în momentul în
care întâlnim o valoare nulă.
Cod:

<?php
for ($i = 0; $i < $n; $i++)
for ($j = 0; $j < $n; $j++)
if ( ! $a [$i] [$j] )
break 2;
?>

Instrucţiunea break poate fi utilizată pentru întreruperea execuţiei secvenţelor de instrucţiuni


corespunzătoare structurilor for, foreach, while, do - while şi switch.

Instrucţiunea continue

Această instrucţiune este folosită pentru a întrerupe execuţia secvenţei de instrucţiuni din
interiorul unui ciclu şi trecerea la următoarea iteraţie. În cazul instrucţiunii for, înainte de
următoarea iteraţie se evaluează (execută) expresia de incrementare (expresia #3 din sintaxa
generală). La fel ca şi în cazul instrucţiunii break, poate apărea un argument care indică
numărul structurilor îmbricate asupra cărora are efect. Exemplul următor realizează afişarea
elementelor unui şir de numere întregi care sunt mai mari decât 1000.

Cod:

<?php
foreach ($a as $v)
{
if ($v <= 1000)
continue;
echo $v;
}
?>

Următorul exemplu ilustrează efectul folosirii argumentelor pentru instrucţiunea continue.

Cod:

<?php
$i = 0;
while ($i++ <5)
{
echo "Ciclul #1 <br>\n";
while (1)
{
echo "??Ciclul #2 <br>\n";
while (1)
{
echo "??Ciclul #3<br>\n";
continue 3;
}
echo "Acest mesaj nu va fi afisat niciodata.<br>\n";
}
echo "Nici acest mesaj nu va fi afisat niciodata.<br>\n";
}
?>

Rezultatul codului de mai sus este:

Ciclul #1
Ciclul #2
Ciclul #3
Ciclul #1
Ciclul #2
Ciclul #3
Ciclul #1
Ciclul #2
Ciclul #3
Ciclul #1
Ciclul #2
Ciclul #3
Ciclul #1
Ciclul #2
Ciclul #3

Alte structuri PHP

Există mai multe alte structuri PHP care pot fi utilizate în anumite scopuri. Vom aminti acum
câteva dintre ele:
Structurile include, require, include_once şi require_once pot fi utilizate pentru a "insera"
anumite instrucţiuni care sunt păstrate într-un alt fişier (document). Interpretorul PHP
consideră că secvenşa din fişierul inserat se află în fişierul din care s-a "comandat" inserarea
în poziţia în care apare structura de inserare.
O altă structură este declare care permite crearea unor directive în execuţie.
Funcţiile PHP trebuie să utilizeze instrucţiunea return pentru a furniza un rezultat.

Despre funcţii în PHP

În PHP funcţiile pot fi definite de către utilizator folosind următoarea sintaxă:

function numef ($param1, $param2, ..., $paramN) {


// instructiuni
}

În PHP o funcţie poate fi definită oriunde în cadrul script-ului şi în interiorul unei funcţii poate
să apară orice secvenţă validă de cod care include definirea de alte funcţii şi definiţii de clase.
Argumentele unei funcţii trebuie separate prin virgulă, şi, implicit, acestea sunt transmise prin
valoare. Pentru ca funcţia să returneze un rezultat se foloseşte construcţia return care
primeşte ca parametru o expresie care reprezintă valoarea funcţiei. În momentul în care este
întâlnită construcţia return, execuţia funcţiei se încheie. În exemplul următor se calculează cu
ajutorul unei funcţii PHP, pătratul unui număr.

Cod:
<?php
function patrat($n)
{
return $n * $n;
}
echo "4^2=<b>".patrat(4)."</b>";
?>

Rezultatul codului va fi:

4^2=16

Transmiterea parametrilor prin referinţă

Pentru a transmite parametri unei funcţii prin referinţă, fapt care implică modificarea valorii
parametrilor şi păstrarea noii valori după ce execuţia funcţiei s-a încheiat, se foloseşte
operatorul '&' înaintea numelui parametrului formal, în momentul definirii funcţiei. Următorul
exemplu indică modul în care se modifică valoarea unei variabile în interiorul unie funcţii şi
modul în care această modificare este resimţită în exteriorul acesteia:

Cod:

<?php
function modificInt ($s)
{
$s .= " prima functie.";
echo "<b>In modificInt: </b>".$s."<br>";
}
function modificExt (&$s)
{
$s .= " a doua functie.";
echo "<b>In modificExt: </b>".$s."<br>";
}

$s="Iesire din ";


echo "<b>In script: </b>".$s."<br>";
modificInt ($s);
echo "<b>In script: </b>".$s."<br>";
modificExt ($s);
echo "<b>In script: </b>".$s."<br>";
?>

Rezultat:

In script: Iesire din


In modificInt: Iesire din prima functie.
In script: Iesire din
In modificExt: Iesire din a doua functie.
In script: Iesire din a doua functie.

Nu există posibilitatea de supraâncărcare a unei funcţii, de redefinire a ei după ce aceasta a


fost definită în cadrul scriptului respectiv şi nu există nici posibilitatea de anulare a unei funcţii.
Parametri cu valori implicite

În PHP parametrii formali pot avea valori implicite, şi, în cazul în care parametrul actual
lipseşte, atunci se va considera că are valoarea implicită. Următorul exemplu ilustrează modul
de folosire al funcţiilor când acestea au parametri formali cu valori implicite:

Cod:

<?php
function comanda($s='cafea')
{
return "Ati comandat ".$s.".";
}

echo comanda();
echo "<br>";
echo comanda("suc");
?>

Rezultat:

Ati comandat cafea.


Ati comandat suc.

În cazul în care se folosesc parametri cu valori implicite este necesar ca orice parametru care
are o valoare implicită să se afle în partea dreaptă a tuturor parametrilor pentru care nu se
folosesc valori implicite, în caz contrar interpretorul PHP nu poate să decidă cărui parametru
să-i atribuie valoarea de pe o anumită poziţie din lista de parametri. De exemplu, dacă avem o
funcţie a cărei declaraţie este

function transform ($baza=10, $nr)

si care returnează rezultatul transformării lui $nr din baza 16 în baza $baza, a cărei valoare
implicită este 10, dacă se apeleaza transform (50), interpretorul nu atribuie valoarea 50
parametrului $nr, ci parametrului $baza şi generează o eroare deoarece lipseste valoarea
parametrului $nr.

Funcţii cu număr variabil de parametri

O altă facilitate a limbajului PHP este aceea că oferă programatorului posibilitatea de a utiliza
funcţii care au un număr nedeterminat de parametri. Funcţiile care folosesc un număr variabil
de parametri nu au nici o particularitate în ceea ce priveşte definirea lor. Aceste funcţii se
definesc la fel ca cele prezentate anterior, dar pentru a putea accesa parametri se vor folosi
următoarele funcţii predefinite:

- func_num_args( ) - această funcţie returnează numărul parametrilor funcţiei care a


apelat-o; dacă această funcţie este apelată din exteriorul unei funcţii definite de utilizator se
va genera un mesaj de avertizare;
- func_get_arg(arg_num) - returnează valoarea parametrului care se află pe pozitia
arg_num în lista de parametri; primul parametru are numărul de ordine 0; dacă este apelată
din exteriorul unei funcţii definite de utilizator se va genera un mesaj de avertizare;
- func_get_args( ) - returnează un tablou unidimensional care conţine valorile parametrilor
pe care funcţia apelantă i-a primit; dacă această funcţie este apelată din exteriorul unei funcţii
definite de utilizator se va genera un mesaj de avertizare.
În continuare aveţi 2 exemple de utilizare a acestor funcţii. Primul exemplu afişează lista
parametrilor funcţiei folosind funcţia func_num_argsşi func_get_arg, iar al doilea exemplu
afişează aceeaşi listă folosind numai funcţia func_get_args.

Cod:

<?php
function lista_parametri()
{
for ($i=0; $i<func_num_args(); $i++)
{
print_r(func_get_arg($i));
echo "<br>";
}
}
echo lista_parametri("Comanda:", 1, "calculator", 2, "procesoare", "con
figuratie", array("local", 2, 3));
?>

Cod:

<?php
function lista_parametrii()
{
foreach(func_get_args() as $i)
{
print_r ($i);
echo "<br>";
}
}
echo lista_parametrii ("Comanda:", 1, "calculator", 2, "procesoare", "c
onfiguratie", array("local", 2, 3));
?>

Rezultat:

Comanda:
1
calculator
2
procesoare
configuratie
Array ( [0] => local [1] => 2 [2] => 3 )

Valorile returnate de funcţii

Rezultatul obţinut după apelarea unei funcţii poate avea orice tip. O funcţie poate să returneze
chiar şi liste sau obiecte. În PHP există un caz special de rezultat numit referinţă. Pentru ca o
funcţie să poată returna o referinţă, aceasta trebuie declarată folosindu-se operatorul '&'
înaintea numelui funcţiei. Acest operator trebuie să apară înaintea numelui funcţiei şi în
momentul când o variabilă primeşte ca valoare referinţa rezultată din apelul funcţiei. În
exemplul următor se defineşte o funcţie al cărui rezultat îl constituie o referinţă:

Cod:

<?php
function &refer()
{
global $s;
return $s;
}

$s = "Acesta este continutul variabilei referite cu ajutorul functiei.";

$z = &refer();
echo $z;
?>

Rezultat:

Acesta este continutul variabilei referite cu ajutorul functiei.

Spre deosebire de majoritatea limbajelor de programare moderne, o funcţie PHP poate să


returneze o referinţă la o variabilă care a fost declarată în interiorul funcţiei, însă acest lucru
nu este indicat deoarece, în anumite cazuri, poate duce la efecte neaşteptate ale executării
unui script PHP. În alte limbaje de programare efectele devin uneori fatale.

Variabilele de tip funcţie

O altă facilitate a limbajului PHP în ceea ce priveşte funcţiile este aceea că suportă variabile de
tip funcţie. Acest lucru este util atunci când se folosesc liste de funcţii pentru prelucrarea
anumitor tipuri de date. Pentru a atribui un nume de funcţie unei variabile în PHP se foloseşte
aceeaşi construcţie ca în cazul atribuirii unui şir de caractere, şi anume, o variabilă va primi ca
valoare numele funcţiei scris între ghilimele simple sau duble. În cazul în care interpretorul
PHP găseşte un nume de variabilă urmată de o listă de parametri, acesta caută funcţia pe care
variabila o referă şi în cazul în care există, o execută. Variabilele de tip funcţie nu funcţioneaza
cu construcţii ale limbajului ca echo, unset, isset, empty, include etc. Mai jos aveţi un
exemplu care ilustrează modul de lucru cu variabilele de tip funcţie.

Cod:

<?php
function produs($a, $b)
{
return $a * $b;
}

function suma($a, $b)


{
return $a + $b;
}

$operatie = 'produs';
$rez = $operatie(4, 5);
echo "4 * 5 = <b>".$rez."</b><br>";
$operatie = 'suma';
$rez = $operatie(4, 5);
echo "4 + 5 = <b>".$rez."</b><br>";
?>

Rezultat:

4 * 5 = 20
4+5=9

Clase şi obiecte în PHP

O clasă este o colecţie de variabile şi funcţii care operează asupra variabilelor respective.
Sintaxa folosită pentru declararea unei clase în PHP este:

Cod:

<?php
class nume_clasa
{
// date membre
var nume_variabila_1
...
var nume_variabila_m
// metode
function nume_functie_1 (parametri)
{
... // definitia functiei
}
...
function nume_functie_n (parametri)
{
... // definirea functiei
}
}
?>

Pentru numele unei clase poate fi utilizat orice identificator permis în PHP cu o singură
excepţie: sdtclass; acest identificator este folosit de PHP în scopuri interne.
În PHP funcţiile ale căror identificatori încep cu _ sunt considerate funcţii magice şi utilizarea
acestora nu este recomandată.
În PHP, datele membre nu pot fi iniţializate decât cu valori constante. Pentru a iniţializa
variabilele cu valori care nu sunt constante trebuie folosit un constructor. Mai jos aveti un
exemplu de clasă în care initializările nu sunt corecte:

Cod:

<?php
class Nepermis
{
var $data = date("Y-m-d");
var $nume = $prenume;
var $dest = 'Mihai '.'Claudiu';
var $obiecte = array ("minge", "pantof");
}
?>

Obiecte

În PHP clasele sunt considerate a fi tipuri de date; ele pot fi privite ca fiind "amprentele"
variabilelor propriu-zise. Pentru a crea o variabilă al cărei tip este o clasă trebuie utilizat
operatorul new. În continuare vom defini o clasă Aritmetica cu două date membre x şi y care
sunt numere întregi şi două metode care realizează adunarea, respectiv înmulţirea lor.

Cod:

<?php
class Aritmetica
{
var x = 2;
var y = 3;
function Suma ()
{
return $this -> x + $this -> y;
}
function Produs()
{
return $this -> x * $this -> y;
}
}
?>

Pentru a crea un obiect de tipul Aritmetica vom utiliza o instrucţiune de tipul:

$aritm = new Aritmetica;

Acum putem utiliza metodele clasei; pentru a afişa suma sau produsul celor două numere vom
putea apela cele două metode astfel:

echo $aritm -> Suma ( );


echo $aritm -> Produs ( );

Vom obţine rezultatele 5, respectiv 6. Valorile datelor membre pot fi şi ele modificate prin
instrucţiuni de tipul:

$aritm -> x = 5;
$aritm -> y = 4;

Dacă, în urma modificării apelam din nou metodele Suma( ) şi Produs( ), rezultatele vor fi 9,
respectiv 20.
Cod:

<?php
class PHP4
{
var $salut = "Salut PHP4!";
function Salut()
{
return $this -> salut;
}
}
$salutare = new PHP4;
echo $salutare -> Salut()."<br>";
?>

Rezultatul codului de mai sus este:

Salut PHP4!

În acest exemplu a fost utilizată pseudo-variabila $this. Aceasta este folosită pentru a indica
faptul că se operează asupra unei date membre a obiectului curent.

Extinderea claselor

Deseori este necesară definirea unor clase cu proprietăţi (date membre) şi metode
asemănătoare. Pentru a usura definirea unor astfel de clase a fost introdus conceptul de
extindere (derivare) a claselor.
O clasă derivată va păstra toate proprietăţile şi metodele clasei pe care o extinde şi poate
conţine diferite proprietăţi şi metode noi. Nu există nici o posibilitate de a elimina din clasa
derivată anumite proprietăţi sau metode ale clasei de bază. O anumită clasă poate avea o
singură clasă părinte; aşadar, în PHP nu este permisă moştenirea multiplă. Pentru a extinde
o anumită clasă se utilizează cuvântul cheie extends.
ή următorul exemplu voi extinde clasa Aritmetica; o să adaug încă o variabilă şi o să crez două
noi funcţii: una pentru calculul sumei celor trei variabile şi una pentru calcularea produsului
lor:

Cod:

<?php
class Aritmetica3 extends Aritmetica
{
var z = 4;
function Suma3()
{
return $this -> x + $this -> y + $this -> z;
}
function Produs3()
{
return $this -> x * $this -> y * $this -> z;
}
}
?>
Dacă definim un obiect prin intermediul unei instrucţiuni de genul:

$aritm3 = new Aritmetica3;

atunci pentru acest obiect vom putea utiliza atât metodele definite în cadrul clasei
Aritmetica3: Suma3( )şi Produs3( ), cât şi metodele definite în cadrul clasei de bază
Aritmetica: Suma( )şi Produs( ).
În continuare aveţi un exemplu care ilustrează modul în care pot fi create şi utilizate clasele
derivate.

Cod:

<?php
class Aritmetica
{
var $x = 2;
var $y = 3;
function Suma()
{
return $this -> x + $this -> y;
}
function Produs()
{
return $this -> x * $this -> y;
}
}

class Aritmetica3 extends Aritmetica


{
var $z = 4;
function Suma3()
{
return $this -> x + $this -> y + $this -> z;
}
function Produs3()
{
return $this -> x * $this -> y * $this -> z;
}
}

$aritm3 = new Aritmetica3;


echo "<b>Inainte de modificare.</b>";
echo "<br>";
echo "Suma primelor doua numere: ";
echo $aritm3 -> Suma()."<br>";
echo "Produsul primelor doua numere: ";
echo $aritm3 -> Produs()."<br>";
echo "Suma celor trei numere: ";
echo $aritm3 ->Suma()."<br>";
echo "Produsul celor trei numere: ";
echo $aritm3 -> Produs()."<br>";

$aritm3 -> x = 5;
$aritm3 -> y = 4;
$aritm3 -> z = 3;
echo "<br><br>";
echo "<b>Dupa modificare.</b><br>";
echo "<br>";
echo "Suma primelor doua numere: ";
echo $aritm3 -> Suma3()."<br>";
echo "Produsul primelor doua numere: ";
echo $aritm3 -> Produs3()."<br>";
echo "Suma celor trei numere: ";
echo $aritm3 -> Suma3()."<br>";
echo "Produsul celor trei numere: ";
echo $aritm3 -> Produs3()."<br>";
?>

Rezultatul codului de mai sus este:

Citat:

Inainte de modificare.
Suma primelor doua numere: 5
Produsul primelor doua numere: 6
Suma celor trei numere: 5
Produsul celor trei numere: 6

Dupa modificare.

Suma primelor doua numere: 12


Produsul primelor doua numere: 60
Suma celor trei numere: 12
Produsul celor trei numere: 60

În PHP clasele trebuie definite înaintea utilizării lor; aşadar clasa părinte va fi definită
întotdeauna înaintea clasei fiu.

Constructori

Un constructor este o metodă (funcţie) a unei clase care este apelată automat în momentul în
care este creată o nouă instanţă a clasei (cu ajutorul operatorului new). În PHP, este
considerată ca fiind un constructor, orice funcţie care are acelaşi nume cu clasa în interiorul
căreia este definită.
Constructorii pot fi folosiţi pentru iniţializarea datelor membre cu valori care nu sunt
constante. Ei pot avea argumente, iar acestea pot fi optionale. Pentru a putea utiliza clasa fără
a specifica nici un parametru în momentul creării unui obiect, se recomandă stabilirea unor
valori implicite pentru toate argumentele constructorului. În cazul în care nu este definit un
constructor pentru o anumită clasă, se utilizează constructorul clasei de bază, dacă aceasta
există. De exemplu, pentru următoarea secvenţă de cod, în momentul creării obiectului
corespunzător variabilei $b, va fi apelat constructorul clasei A.

Cod:

<?php
class A
{
function A()
{
echo "Constructorul clasei A<br>";
}
function B()
{
echo "O functie obisnuita a clasei A.<br>";
}
}

class B extends A
{
function C()
{
echo "O functie obisnuita a clasei B.<br>";
}
}
?>

În PHP apelul constructorului clasei de bază trebuie să fie explicit dacă este necesară
executarea operaţiilor corespunzătoare. În majoritatea limbajelor de programare există funcţii
speciale numite destructori care sunt apelate automat în momentul "distrugerii" unui obiect. În
PHP nu există destructori.

Operatorul ::

Uneori este utilă folosirea unor metode sau variabile ale clasei de bază sau ale unei clase care
nu a fost instanţiată încă. În acest scop a fost introdus operatorul ::
Pentru a descrie modul de utilizare al acestui operator voi prezenta mai întâi un exemplu:

Cod:

<?php
class A
{
function exemplu()
{
echo "Functia clasei de baza. <br>";
}
}

class B extends A
{
function exemplu()
{
echo "Functia redefinita<br>\n";
A :: exemplu();
}
}

A :: exemplu();
$b = new B;
$b -> exemplu();
$b = new B;
?>
Prin intermediul instrucţiunii

A :: exemplu( );

este apelată metoda exemplu( ) a clasei A, aşadar se afişează mesajul 'Functia clasei de baza'
cu toate că nu există nici un obiect care este o instanţă a acestei clase, deci nu putem scrie o
instrucţiune de tipul $a -> exemplu( );
În schimb apelăm metoda

$b -> exemplu( );

ca "o funcţie a clasei" şi nu ca "o funcţie a unui obiect". Putem avea funcţii ale claselor, dar nu
putem avea variabile ale claselor. De fapt, în momentul unui astfel de apel nu se creeaza nici
un obiect care este instanţă a clasei respective. Ca urmare, o funcţie a unei clase nu poate
opera asupra unor proprietăţi ale clasei, dar poate utiliza variabile locale sau globale. În plus,
o astfel de funcţie nu poate utiliza pseudo-variabila $this.
În exemplul anterior, în cadrul clasei B este redefinită funcţia exemplu( ). Aşadar, definiţia
"originală" (din cadrul clasei A) nu poate fi accesată în interiorul clasei B decât dacă ne referim
la ea explicit prin intermediul operatorului ::.

Accesarea clasei de baza

În exemplul anterior am utilizat o funcţie a clasei de bază. În locul utilizării denumirii clasei de
baza poate fi folosită denumirea specială parent care este o referinţă la clasa de bază definită
în cadrul construcţiei extends. Folosirea denumirii speciale este utilă în cazul în care ierarhia
de clase se modifică. În acest caz este suficientă o singură modificare în cadrul construcţiei
extends, fără a mai fi necesare modificări în interiorul clasei derivate. Aşadar, definiţia clasei B
poate fi rescrisă astfel:

Cod:

<?php
class B extends A
{
function exemplu()
{
echo "Functia redefinita<br>\n";
parent :: exemplu();
}
}
?>

Serializarea obiectelor

Prin serializare se înţelege crearea unui şir de octeţi care conţin reprezentarea internă (binară)
a variabilei respective. Aşadar, serializarea permite "salvarea" valorilor unei variabile. Dacă
este serializat un obiect sunt salvate doar proprietăţile acestuia (variabilele membre) şi
numele clasei din care face parte, nu şi metodele, deoarece funcţiile nu reprezintă valori.
Pentru a serializa un obiect este utilizată funcţia serialize( ) care returnează şirul de octeţi
care conţine reprezentarea binară.
Pentru a deserializa un obiect se foloseşte funcţia pereche unserialize( ).
Pentru ca o astfel de operaţie să funcţioneze corect este necesară definirea clasei din care face
parte obiectul respectiv. Funcţia returnează valoarea variabilei serializate. În exemplul
următor aveţi prezentat modul în care poate fi serializat şi deserializat un obiect. Şirul de
octeţi obţinut în urma serializării va fi scris într-un fişier şi va fi citit din fişierul respectiv
pentru efectuarea deserializării. De obicei serializarea şi deserializarea sunt realizate în
documente php diferite deoarece aeste operaţii nu au aproape nici o utilitate dacă sunt folosite
în cadrul aceluiaşi document. Primul document în care se realizează serializarea trebuie să
conţină o secvenţă asemănătoare cu următoarea:

Cod:

<?php
class A
{
var $msg = "Salutare lume";
function scrie()
{
echo $this -> msg;
}
}

$a = new A;
$s = serialize ($a);
// salvarea sirului intr-un fisier
$fp = fopen ("fisier", "w");
fputs ($fp, $s);
fclose ($fp);
?>

Pentru deserializare al doilea document va conţine următoarea secvenţă:

Cod:

<?php
class A
{
var $msg = "Salutare lume";
function scrie()
{
echo $this -> msg;
}
}

// citirea sirului din fisier


$s = implode ("", @file ("fisier"));
$a = unserialize ($s);
// dupa deserializare obiectul poate fi folosit
$a -> show_one();
?>

Referinţele pot fi utilizate pentru a accesa conţinutul unei variabile folosind mai multe nume.
Spre deosebire de limbajul C, în PHP referinţele nu sunt pointeri, ci alias-uri într-o tabela de
simboluri. În PHP denumirile variabilelor şi conţinutul acestora nu sunt unul şi acelaşi lucru.
Aşadar este posibil ca acelaşi conţinut să aibă denumiri diferite.
Utilizarea referinţelor

Referinţele PHP permit unor variabile cu denumiri diferite să corespundă unui acelaşi conţinut.
Cu alte cuvinte, instrucţiunea

$a = &$b

are ca efect faptul că $a şi $b referă aceeaşi variabilă. În această situaţie $a şi $b<;/em> au


acelaşi statut. Nu se poate spune că $a referă $b sau invers. O altă posibilitate de utilizare a
referinţelor este transmiterea prin referinţă a parametrilor unei funcţii. Efectul unei astfel de
transmisii este crearea unei variabile locale care referă spre acelaşi conţinut ca variabila din
contextul apelant. Să luăm în considerare următorul exemplu:

Cod:

<?php
function inc(&$var)
{
$var++;
}

$a = 5;
inc($a);
?>

Iniţial valoarea variabilei $a este 5. După apel variabila locală $var şi variabila din contextul
apelant $a indică spre acelaşi conţinut. Valoarea păstrată în locaţia de memorie respectivă
este incrementată (devine 6) prin intermediul instrucţiunii $var++;.
Datorită faptului că cele două variabile au acelaşi conţinut, valoarea variabilei $a va fi 6 după
executarea funcţiei.
Un parametru transmis prin referinţă poate fi:
- o variabilă;
- o instrucţiune new;
- o referinţă returnată de o funcţie.
Dacă unei astfel de funcţii i se transmite ca parametru un alt tip de expresie rezultatul este
nedefinit. Aşadar, pentru o funcţie care are un parametru transmis prin referinţă nu se poate
folosi o constantă în momentul apelului. De exemplu, pentru funcţia inc( ) prezentată anterior
nu este permis un apel de forma inc(5).

Referinţe globale

În momentul declarării unei variabile globale (printr-o instrucţiune de tipul global $var) se
creează de fapt o referinţă spre o variabilă globală. Cu alte cuvinte, această instrucţiune este
echivalentă cu $var = &$GLOBALS ["var"];.

Referinţa $this

În cadrul unei metode a unui obiect $this este întotdeauna o referinţă spre obiectul care
utilizează funcţia (obiectul curent).
Crearea imaginilor thumbnails

Acest tutorial vă va învăţa cum să creaţi thumbnail-uri ale unor imagini mai mari ca
dimensiune. Thumbnail-urile sunt nişte imagini în miniatură de o rezoluţie mai mică. Odată
apăsat un thumbnail vom deschide poza originală. Să vedem în continuare cum vom face
acest lucru posibil. În primul rând avem nevoie de două foldere: unul pentru imaginile
originale, şi îl vom denumi pictures şi unul pentru thumnail-uri pe care îl vom denumi
thumbnails. Ceea ce este foarte important este că în aceste două foldere nu trebuie să se
găsească decât imagini de tip JPG altfel vom întâmpina erori. Este evident că putem adapta
scriptul pentru orice format de imagine, GIF sau PNG însă scopul principal al acestui tutorial
este acela de a vă face să întelegeţi care sunt paşii pe care trebuie sa îi urmaţi când faceţi un
asemenea script.
PHP-ul pe care îl rulaţi trebuie să aibă activată libraria GD2 pentru a rula acest script, altfel
veţi întâmpina o eroare prin care vă va fi adus la cunoştinţă că funcţia pentru imagini nu poate
fi găsită. Dacă librăria GD2 nu este activă o puteţi activa în felul următor în mediul WINDOWS:
adăugaţi liniile următoare în php.ini:

extension=php_gd2.dll

Vom deschide directorul pictures şi thumbnails şi vom citi numele fiecărui fişier care există
în aceste directoare şi le vom memora în vectorul $pictures şi $thumbnails

Cod:

<?php
$open_pictures = opendir("pictures");
while($file = readdir($open_pictures))
{
if(substr($file, 0, 1) != '.')
{
$pictures[] = $file;
}
}
closedir($open_pictures);

$open_thumbnails = opendir("thumbnails");
while($file = readdir($open_thumbnails))
{
if(substr($file, 0, 1) != '.')
{
$thumbnails[] = $file;
}
else
{
$thumbnails = array();
}
}
closedir($open_thumbnails);
?>

Vom reţine apoi în două variabile de tip vector numele pozelor care se află în folderul pictures
dar nu se află în folderul thumbnails, cât şi pozele care se află în folderul thumbnails dar nu
se afla în folderul pictures. Astfel pentru fiecare poză care exista în folderul pictures dar nu
se află şi în folderul thumbnails îi vom crea o poză în miniatură cu dimensiunile stabilite prin
variabila $max_width şi $max_width bineânţeles păstrând proporţiile pozei originale
calculate cu ajutorul variabilei $ratio, astfel încât dacă lungimea pozei originale este mai mare
decât înălţimea, atunci $ratio va lua valoarea lungimei maxime setate în variabila
$max_width împărţită la lungimea pozei originale, iar în caz contrar $ratio va lua valoarea
înălţimii maxime setate pentru thumbnail împărţite la înălţimea pozei originale.
Rezoluţia pozei originale o aflăm cu ajutorul funcţiei getimagesize() care returnează un
vector cu atributele pozei.
Vom afla în continuare noile dimensiuni ale pozei în miniatură calculate în variabilele
$thumbnail_width şi $thumbnail_height prin îmulţirea dimensiunilor pozei originale cu
$ratio.

Cod:

<?php
$diff_pic = array_diff($pictures, $thumbnails);
$diff_tumb = array_diff($thumbnails, $pictures);
foreach($diff_pic as $key => $value)
{
$image_name = 'pictures/'.$value;
$image_attribs = getimagesize($image_name);
$max_width = 100;
$max_height = 100;
$ratio = ($image_attribs[0] > $image_attribs[1]) ? $max_width / $im
age_attribs[0] : $max_height / $image_attribs[1];
$thumbnail_width = $image_attribs[0] * $ratio;
$thumbnail_height = $image_attribs[1] * $ratio;

În continuare vom crea acele thumbnail-uri ale pozelor prin aplicarea funcţiilor PHP pentru
imagini. Pentru început vom returna o imagine din poza originală cu ajutorul funcţiei
imagecreatefromjpeg() după care vom crea o imagine neagră cu dimensiunile calculate mai
sus pentru thumbnail.
Numele pozei în miniatură va fi acelaşi cu numele pozei originale numai că o vom salva în alt
director. Calea către thumbnail o vom ţine într-o variabilă $thumbnail_name, apoi vom
copia imaginea originală peste imaginea thumbnail păstrând proporţiile. Vom crea imaginea
jpg în calea specificată în variabila $thumbnail_name cu ajutorul funcţiei imagejpeg().

Cod:

$image = imagecreatefromjpeg($image_name);
$image_new = imagecreatetruecolor($thumbnail_width, $thumbnail_heig
ht);
imageantialias($image_new, true);
$thumbnail_name = 'thumbnails/'.$value;
imagecopyresampled($image_new, $image, 0, 0, 0, 0, $thumbnail_width,
$thumbnail_height, $image_attribs[0], $image_attribs[1]);
imagejpeg($image_new, $thumbnail_name);
imagedestroy($image);
}
?>

Este posibil ca în directorul thumbnails să se afle imagini ale pozelor care nu se mai află în
directorul pictures, acestea nu sunt necesare şi le vom şterge cu ajutorul funcţiei unlink().
Vă amintiţi că mai sus am aflat care sunt pozele care se afla în directorul thumbnails dar nu
se afla în directorul pictures cu ajutorul funcţiei array_diff() care face diferenţa dintre
valorile primului vector analizat şi cel de-al doilea vector.

Cod:

<?php
foreach($diff_tumb as $key => $value)
{
unlink("thumbnails/".$value);
}
?>

În acest moment avem create thumbnail-urile imaginilor originale şi le vom afişa în pagină
încadrate într-un tabel cu $modulo celule, cu link către pozele originale. Mai jos aveţi întreg
codul sursă pentru crearea imaginilor thumbnail şi afişarea acestora în pagină.

Cod:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://


www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"
/>
<title>Thumbnails</title>
</head>

<body>
<?php
$open_pictures = opendir("pictures");
while($file = readdir($open_pictures))
{
if(substr($file, 0, 1) != '.')
{
$pictures[] = $file;
}
}
closedir($open_pictures);

$open_thumbnails = opendir("thumbnails");
while($file = readdir($open_thumbnails))
{
if(substr($file, 0, 1) != '.')
{
$thumbnails[] = $file;
}
else
{
$thumbnails = array();
}
}
closedir($open_thumbnails);

$diff_pic = array_diff($pictures, $thumbnails);


$diff_tumb = array_diff($thumbnails, $pictures);
foreach($diff_pic as $key => $value)
{
$image_name = 'pictures/'.$value;
$image_attribs = getimagesize($image_name);
$max_width = 100;
$max_height = 100;
$ratio = ($image_attribs[0] > $image_attribs[1]) ? $max_width / $im
age_attribs[0] : $max_height / $image_attribs[1];
$thumbnail_width = $image_attribs[0] * $ratio;
$thumbnail_height = $image_attribs[1] * $ratio;
$image = imagecreatefromjpeg($image_name);
$image_new = imagecreatetruecolor($thumbnail_width, $thumbnail_heig
ht);
imageantialias($image_new, true);
$thumbnail_name = 'thumbnails/'.$value;
imagecopyresampled($image_new, $image, 0, 0, 0, 0, $thumbnail_width,
$thumbnail_height, $image_attribs[0], $image_attribs[1]);
imagejpeg($image_new, $thumbnail_name);
imagedestroy($image);
}
foreach($diff_tumb as $key => $value)
{
unlink("thumbnails/".$value);
}
$open_thumbnails = opendir("thumbnails");
$l = 0;
$modulo = 4;

echo '<table border="0" align="center">';


while($file = readdir($open_thumbnails))
{
if(substr($file, 0, 1) != '.')
{
if($l % $modulo == 0)
{
echo '<tr>';
echo '<td align="center" valign="middle"><a href="pictures/'
.$file.'" target="_blank" title="Click to enlarge!" >';
echo '<img src="thumbnails/'.$file.'" alt="thumbnail" borde
r="0" />';
echo '</a></td>';
}
if($l % $modulo == $modulo - 1)
{
echo '</tr>';
}
$l++;
$unfinished = $l % $modulo;
}
}
closedir($open_thumbnails);

if($unfinished != 0)
{
for($k = $unfinished; $k < $modulo; $k++)
{
echo '<td>&nbsp;</td>';
}
echo '</tr>';
}
echo '</table>';
?>
</body>
</html>

Articol preluat de la http://boo.opaq.org

Autentificarea în paginile restricţionate şi câteva informaţii despre cookie, uploadul


fişierelor şi includerea lor în pagini, precum şi informaţii despre starea conexiunii.

După cum probabil ştiţi, anumite site-uri au accesul restricţionat şi conţinutul lor poate fi
accesat numai de către anumite persoane autorizate. Una dintre variantele prin care poate fi
verificat faptul dacă un anumit utilizator are dreptul de a accesa un anumit site este cererea
introducerii unui nume de utilizator şi a unei parole în momentul în care persoana respectivă
încearcă să acceseze aceste informaţii. În momentul acceasării paginii web este trimis un
mesaj care indică faptul că autentificarea este necesară. Programul de navigare va afişa o
casetă de dialog care permite introducerea unui nume de utilizator şi a unei parole. După
introducerea informatiilor necesare va fi accesată din nou pagina web dar, de această data,
variabilele predefinite PHP_AUTH_USER, PHP_AUTH_PW şi PHP_AUTH_TYPE vor conţine
numele de utilizator, parola, respectiv tipul autentificării. Pentru a trimite mesajul care cere
autentificarea este utilizată funcţia header() . Nu este posibilă decât autentificarea de tip
"Basic". Un exemplu în care este prezentată o autentificare înaintea accesării informaţiilor este
prezentat în continuare:

Cod:

<?php
if (!isset($_SERVER['PHP_AUTH_USER']))
{
header ('WWW-Authenticate: Basic realm="php4"');
header ('HTTP/1.0 401 Unauthorized');
echo 'Pentru accesarea continutului este necesara o autentificare!'
;
exit;
}
else
{
echo "<html><head>";
echo "<title>Autentificare</title>";
echo "</head><body>";
echo "<p>Salut <b><i>{$_SERVER['PHP_AUTH_USER']}</i></b>!</p>";
echo "<p>Parola introdusa este <b><i>{$_SERVER['PHP_AUTH_PW']}</i><
/b>.</p>";
echo "</body></html>";
}
?>
Rezultatul codului de mai sus îl puteţi vedea dând clik aici.

Pentru o compatibilitate cât mai mare, cuvântul Basic trebuie scris cu majusculă, valoarea
pentru realm trebuie să fie cuprinsă între ghilimele (nu între apostrofuri), iar între HTTP/1.0 şi
401 trebuie să existe exact un spaţiu. În acest exemplu, numele de utilizator şi parola sunt
afişate. În practică, se va verifica validitatea lor, de obicei printr-o interogare a unei baze de
date. În situaţia în care este apăsat butonul Cancel, pagina web generată va conţine un mesaj
de avertizare.

Funcţia setcookie.

În PHP există o funcţie specială care poate fi folosită pentru crearea cookie-urilor şi anume
setcookie(). Funcţia defineşte un cookie care va fi trimis împreună cu celelalte headere HTTP.
Ca şi alte headere, cookies trebuie trimis înaintea oricărui caracter din script (aceasta
deoarece există o restricţie de protocol, nu se poate trimite conţinutul paginii şi apoi headerul,
headerele trebuiesc trimise primele, înaintea oricărui mesaj). Dacă a fost trimis ceva la
browser (chiar şi un simplu spaţiu blank) înainte de apelarea acestei funcţii, setcookie() va
genera un mesaj de eroare de tipul FALSE. Dacă setcookie() a putut genera cu succes
cookie-ul, va returna TRUE. Aceasta nu indică dacă userul a acceptat sau nu cookie, ci doar că
a fost generat şi trimis cu succes.
Începând de la php4, puteţi folosi funcţiile ob_start() la începutul scriptului şi
ob_end_flush() la sfârşitul scriptului pentru a se genera un buffer cu tot ce trebuie trimis la
browser, şi astfel la sfârşit se vor trimite toate odată, începând cu headerele şi continuând cu
restul paginii, indiferent dacă în script aţi trimis întâi text şi apoi headere (folosind prima
funcţie, buffer-ul se va genera pe măsură ce primeşte date, iar la sfârşit, când se cere
închiderea buffer-ului prin apelarea celei de-a doua funcţii - ob_end_flush() - , headerele se
vor trimite primele apoi restul buffer-ului).
O altă variantă este de a seta directiva output_buffering din php.ini (în fişierul de
configurare al serverului).
Funcţia setcookie() are şase parametri, doar prezenţa primului parametru fiind obligatorie.
Sintaxa este:

setcookie(nume, valoare, expirare, cale, domeniu, securitate);

Parametru Descriere Exemplu


nume şir de caractere care reprezintă 'nume_cookie' va fi apelat ca
numele cookie-ului $_COOKIE['nume_cookie']
valoare şir de caractere care reprezintă Presupunând că numele este 'cookiename',
valoarea cookie-ului (informaţia valoarea va fi preluată prin
corespunzătoare), care va fi $_COOKIE['cookiename']
salvat pe calculatorul clientului
(nu trimiteţi date sensibile, gen
parola)
expirare un număr întreg care indică time()+60*60*24*30 va seta cookie să expire
momentul de timp în care în 30 de zile. Dacă nu e setat, cookie va expira la
cookie-ul nu va mai putea fi terminarea sesiunii curente (când se închide
utilizat. Valoarea este în format browserul)
"Unix timestamp", adică se poate
seta folosind funcţia time() plus
numărul de secunde până când
doriţi să expire, sau puteţi folosi
mktime().
cale şir de caractere care reprezintă o Dacă este setată ca '/', cookie va fi accesibil
cale generică a fişierelor care pot pentru întreg domeniu. Dacă este setat ca '/foo/',
accesa cooke-ul atunci cookie va fi accesibil doar pentru fişierele
şi scripturile din directorul /foo/ (de pe server)
înclusiv toate sub-directoarele acelui director,
cum ar fi /foo/bar/. Valoarea standard este setată
ca directorul curent (directorul curent adică
directorul în care există scriptul care a setat acel
cookie).
domeniu şir de caractere care reprezintă Pentru a face cookie disponibil pentru toate
domeniul pe care trebuie stocate subdomeniile, de exemplu domeniu.com puteţi
fişierele care pot accesa cookie- seta astfel '.domeniu.com'. Punctul dinainte nu
ul este neaparat necesar, dar îl face compatibil cu
mai multe browsere. Setând ca
www.example.com veţi face cookie-ul disponibil
doar pentru sub-domeniul www. Pentru alte
detalii vedeţi specificaţiile de aici.
securitate număr întreg care, dacă are 0 sau 1
valoarea 1 (TRUE), arată că
informaţia poate fi transmisă
doar folosindu-se o conexiune
HTTPS securizată. Setarea de
bază este 0 (FALSE)

Dacă unul dintre parametri este prezent, atunci toţi parametrii anteriori trebuie să fie prezenţi.
Dacă unul dintre aceştia nu este utilizat, se va folosi în poziţia respectivă fie şirul vid, fie
valoarea 0. În continuare sunt prezentate câteva exemple de apeluri prin care sunt create
cooke-uri:

- setcookie ("TestCookie", "PHP4");


- setcookie ("TestCookie", "Site", time()+3600);
// expiră dupa o oră de la creare
- setcookie ("TestCookie", "Test", time()+3600, "/articole/", ".php4.as.ro",1);

Cu ajutorul funcţiei setcookie() este posibilă şi ştergerea cookie-urilor. Următoarele exemple


ilustrează modul în care poate fi realizată această operaţie:

setcookie ("TestCookie", "", time()-3600);

sau

setcookie ("TestCookie", "", time()-3600, "/comenzi/", ".php4.as.ro", 1);

Se observă că momentul expirării este setat ca fiind anterior momentului executării operaţiei
de stergere. Există posibilitatea de a crea şiruri de cookie-uri prin simpla introducere a
parantezelor drepte în denumiri. Un exemplu de creare şi utilizare a unor astfel de şiruri este
prezentat în continuare:

Cod:

<?php
setcookie ("cookie[three]", "cookiethree");
setcookie ("cookie[two]", "cookietwo");
setcookie ("cookie[one]", "cookieone");
if (isset ($cookie))
{
while (list($name,$value)=each($cookie))
{
echo "$name == $value<br>";
}
}
?>
Pentru a accesa cookie-urile stocate pe calculatorul unui vizitator al paginii Web, este
disponibil vectorul $_COOKIE. Voi prezenta în continuare un exemplu cu ajutorul căruia se
generează o pagină care conţine denumirile şi valorile tuturor cookie-urilor.

Cod:

<?php
foreach ($_COOKIE as $cheie=>$valoare)
{
echo "$cheie = $valoare<br>";
}
?>

Fişierele pot fi încărcate pe un server dacă utilizatorul foloseşte un program de navigare


compatibil RFC-1867; pot fi utilizate ultimile versiuni ale celor mai cunoscute browsere. Este
posibilă încărcarea atât a fişierelor text, cât şi a celor binare. Folosind autentificarea PHP şi
funcţiile de manipulare a fişierelor, avem controlul total asupra utilizatorilor care pot încărca
fişiere şi asupra operaţiilor efectuate cu fişierul încărcat.

Formularul de încarcare (upload)

Pentru ca utilizatorul să poată încărca un fişier, el trebuie să aibă la dispoziţie un formular care
să permită alegerea fişierului. Un astfel de formular poate fi creat, de exemplu, folosind
limbajul HTML standard. În continuare este prezentat un document HTML care generează o
pagina web care permite alegerea unui fişier şi încărcarea sa pe un server.

Cod:

<html>
<head>
<title>Incarcarea unui fisier pe server</title>
</head>
<body>
<form enctype="multipart/form-data" action="upload.php" method="post">
Alegeti fisierul: <br>
<input name="fisier" type="file">
<input type="hidden" name="MAX_FILE_SIZE" value="1024"><br>
<input type="submit" value="Trimite fisierul!">
</form>
</body>
</html>

Butonul Browse... poate fi utilizat pentru alegerea unui fişier care urmează a fi încărcat. Este
posibilă specificarea fişierului precizând exact calea în caseta de text afişată. URL-ul care este
folosit ca valoare pentru atributul action al marcajului <from> trebuie să reprezinte
documentul php care va realiza încărcarea.

Operatia de încarcare (upload)

Aşadar, formularul prin intermediul căruia este ales fişierul va fi prelucrat de către un script
PHP. Pentru a manipula fişierele poate fi utilizat tabloul $_FILES. Pentru script-ul care
prelucrează formularul prezentat anterior, informaţiile referitoare la fişierul încărcat vor fi
acceasate folosind variabila $_FILES['fisier'] care este tot un vector. Elementele acestui
vector sunt prezentate în cele ce urmează:

- $_FILES['fisier'] ['name']
numele pe care îl are fişierul pe calculatorul utilizatorului;
- $_FILES['fisier'] ['tmp_name']
numele temporar pe care îl are fişierul pe server după încheierea procesului de încărcare;

- $_FILES['fisier'] ['type']
tipul fişierului în cazul în care programul de navigare furnizează această informaţie; un
exemplu ar putea fi image/gif;
- $_FILES['fisier'] ['size']
dimensiunea fişierului, exprimată în bytes;
- $_FILES['fisier'] ['fisier'] ['error']
un cod de eroare generat în urma efectuării încărcării.

Fişierul va fi stocat pe server în directorul care conţine fişierele temporare. O secvenţă de


instrucţiuni PHP care poate fi folosită pentru a prelucra fişierul încărcat şi a-l muta în directorul
dorit este următoarea:

Cod:

<?php
if (is_uploaded_file($_FILES['fisier']['tmp_name'))
{
copy($_FILES['fisier']['tmp_name'],"/directorul/dorit");
}
else
{
echo "Eroare de transfer ".$_FILES['fisier']['name'];
}
?>

O variantă alternativă ar fi:

Cod:

<?php
move_uploaded_file($_FILES['fisier']['tmp_name'],"/directorul/dorit");
?>

Coduri de eroare

Începând cu versiunea PHP 4.2.0, în urma efectuării unui transfer, sunt generate anumite
coduri de eroare. Versiunea 4.3.0 introduce constante predefinite pentru fiecare dintre aceste
coduri. În funcţie de codul de eroare generat în urma operaţiei, trebuie realizate diferite
acţiuni. Codul de eroare poate fi accesat prin intermediul elementului ['error'] al vectorului
care păstrează informaţiile despre fişier. Codurile de eroare care pot fi generate sunt
următoarele:

- UPLOAD_ERR_OK (0)
nu a fost semnalată nici o eroare în timpul transferului; operaţia de încărcare s-a încheiat
cu succes;
- UPLOAD_ERR_INI (1)
dimensiunea fişierului este mai mare decât valoarea maximă permisă (această valoare
este specificată în momentul configurării server-ului şi poate fi schimbată modificând fişierul
PHP.INI);
- UPLOAD_ERR_FORM_SIZE (2)
dimensiunea fişierului este mai mare decât valoarea maximă indicată de directiva
MAX_FILE_SIZE care este specificată în formular; această valoare este specificată prin
intermediul unui câmp ascuns al cărui text este MAX_FILE_SIZE;
- UPLOAD_ERR_PARTIAL (3)
fişierul a fost încărcat doar parţial;
- UPLOAD_ERR_NO_FILE (4)
nu a fost încărcat nici un fişier.

Încărcarea mai multor fişiere

Există posibilitatea de a încărca mai multe fişiere dacă sunt folosite nume diferite pentru
marcajul <input> utilizat pentru afişarea casetei de text şi a butonului folosite pentru alegerea
fişierului. De asemenea, este posibil ca fişierele încărcate să fie organizate automat într-un
vector. Pentru aceasta, la numele folosite trebuie adaugate caracterele ' [ ] '. Un exemplu este
prezentat în continuare:

Cod:

<?php
<form action="upload.php" method="post" enctype="multipart/form-data">
Alegeti fisierele:<br>
<input name="fisiere[]" type="file">
<br>
<input name="fisiere[]" type="file">
<br>
<input type="submit" value="Trimite fisierele">
</form>
?>

Să presupunem că am ales să încărcăm fişierele POZA1.GIF şi DOC1.PDF. În acest caz,


$_FILES['fisiere']['name'][0] va avea valoarea POZA1.GIF, în timp ce $_FILES['fisiere']
['name'][1] va avea valoarea DOC1.PDF. Dimensiunile celor două fişiere pot fi determinate
folosind valorile $_FILES['fisiere']['size'][0], respectiv $_FILES['fisiere']['size'][1].

Includerea fişierelor

Deseori, mai multe pagini web pe care le creăm trebuie să conţină secvenţe identice. Evident,
putem copia secvenţele dintr-un fişier în altul, dar această varianta, pe lângă faptul că este
incomodă, duce la un consum mărit de spaţiu pe server şi, în cazul în care secvenţele sunt
lungi sau sunt folosite în foarte multe pagini, problema este destul de importantă.
Interpretorul PHP permite păstrarea secvenţelor comune în fişiere separate şi accesarea
acestora din cadrul altor documente PHP. Pentru a accesa un astfel de fişier, poate fi utilizată
directiva include(). Practic, din punct de vedere logic, tot conţinutul fişierului inclus este
inserat în poziţia în care apare directiva. Sintaxa acestei directive este include(fisier);. Să
presupunem că avem un fişier numit HELLO.TXT cu următorul conţinut:

Cod:
<?php
echo "Pagina de test";
?>

În continuare aveţi un model în care puteţi vedea cum poate fi inclus acest fişier într-un
document php.

Cod:

<head>
<title>Pagina cu fisier inclus</title>
</head>
<body>
<?php
include("HELLO.TXT");
?>
</body>
</html>

Pentru ca fişierul inclus să fie interpretat, acesta trebuie


obligatoriu să indice faptul că secvenţele de text din cadrul său
reprezintă instrucţiuni php. Aşadar, prezenţa construcţiei <?php... ?>
este necesară pentru ca textul să fie interpretat corect. Dacă fişierul
HELLO.TXT ar conţine doar secvenţa echo "Pagina de test";, atunci
acesta nu ar fi interpretat ca fiind cod php, ci ca fişier html.
Aceasta se datorează faptului că în momentul includerii unui fişier se
iese din modul PHP şi tot textul este interpretat ca fiind cod HTML.
După interpretarea textului din fişierul inclus se intră din nou în
modul PHP. În concluzie, folosirea celor două fişiere este echivalentă
cu utilizarea următorului fişier:

Cod:

<head>
<title>Pagina cu fisier inclus</title>
</head>
<body>
<?php
echo "Pagina de test";
?>
</body>
</html>

Includerea în cadrul funcţiilor

Dacă directiva de includere apare în cadrul unei funcţii, atunci se


consideră că toate instrucţiunile din cadrul fişierului inclus fac
parte din corpul funcţiei. Aşadar, domeniul de vizibilitate al
variabilelor folosite în fişierul inclus este acelaşi cu domeniul pe
care l-ar fi avut dacă ar fi apărut în cadrul funcţiei. Pentru a
ilustra acest aspect vom considera un fişier var.txt care conţine
secvenţa:

Cod:

<?php
$culoare = "verde";
$fruct = 'mar';
?>

şi următorul document PHP:

Cod:

<?php
function fructe()
{
global $culoare;
include('var.txt');
echo "un $fruct $culoare<br>";
}
fructe();
echo "un $fruct $culoare<br>;
?>

Rezultatul va fi:

un mar verde
un verde

După cum se poate vedea, variabilele definite în cadrul fişierului


inclus au domeniul de vizibilitate corespunzător funcţiei fructe(). Din
aceste motive valoarea variabilei $fruct nu este disponibilă în afara
funcţiei. Valoarea variabilei $culoare este disponibilă şi în afara
funcţiei, deoarece a fost declarată ca fiind o variabilă globala.
Aşadar, instrucţiunea echo din cadrul funcţiei duce la afişarea
mesajului

un mar verde,

deoarece ambele valori ale variabilelor sunt disponibile, iar


instrucţiunea din afara funcţiei duce la afişarea mesajului

un verde,

deoarece, în afara funcţiei, variabila $fruct nu a fost definită


anterior şi este automat iniţializata cu şirul vid.

Includeri prin HTTP

După cum aţi observat, directiva include are ca parametru un şir de


caractere care conţine numele fişierului care va fi inclus. Acesta
poate fi orice URL valid, aşadar este posibilă includerea unui fişier
aflat pe un alt server. Un exemplu ar putea fi
include("http://www.site-ul.meu/pagina.mea");. O astfel de directivă
funcţioneaza doar dacă se foloşeste PHP 4.3.0 sau o versiune ulterioară.

Includerea unui fişier o singură dată

Uneori, mai ales în situaţiile în care se folosesc variabile pentru


numele fişierelor incluse, este posibil ca anumite fişiere să fie
incluse de mai multe ori. De obicei, fişierele incluse conţin definiţii
ale unor funcţii sau clase, motiv pentru care este de dorit ca un
astfel de fişier să nu fie inclus de mai multe ori. Pentru ca un fişier
să fie inclus o singură dată, se utilizează o directiva alternativă
numită include_once. După cum rezultă din denumire, un fişier va fi
inclus o singură data. Cu alte cuvinte, în momentul în care se cere
includerea unui fişier, se verifică dacă acesta a fost deja inclus şi
în această situaţie directiva nu are nici un efect (fişierul nu este
inclus încă o dată).
Alternative:
Pe lângă directivele includeşi include_once există două alte directive
a căror utilizare are un efect aproape echivalent. Acestea sunt require
(echivalentă cu include) şi require_once (echivalentă cu include_once).
Singura diferenţa dintre include şi require (respectiv dintre
include_onceşi require_once) este dată de modul în care este tratată
situaţia în care fişierul care se doreşte a fi inclus nu există sau nu
este disponibil. În cazul directivelor include şi include_once este
generat un avertisment şi execuţia script-ului continuă fără ca
fişierul să fie inclus. Practic, din punct de vedere logic, este
ignorată directiva. În cazul directivelor require şi require_once este
generată o eroare fatală şi execuţia script-ului este întreruptă.
Aşadar, în situaţiile în care este absolut necesară existenţa
fişierului, pentru a nu apărea efecte bizare, trebuie utilizată
directiva require, respectiv require_once.

Starea conexiunii

În PHP, conexiunea poate avea una dintre cele trei stări posibile:
- NORMAL (0)
starea normală de funcţionare;
- ABORTED (1)
utilizatorul care accesează pagina generată de script-ul aflat
în execuţie s-a deconectat (de obicei prin apăsarea butonului Stop al
programului de navigare);
- TIMEOUT (2)
a fost atinsă limita de timp impusă de PHP.

Pentru fiecare dintre cele trei stări există un indicator (flag) care
este setat sau nu în funcţie de starea conexiunii. În funcţie de
script, este necesar sau nu ca execuţia acestuia să se incheie în
momentul în care este întreruptă conexiunea. De exemplu, în cazul în
care script-ul actualizează o bază de date ar fi de dorit ca execuţia
să continue. În principiu, este indicat ca script-urile să îşi încheie
execuţia chiar dacă datele de ieşire nu vor mai fi trimise
utilizatorului. Pentru a decide dacă execuţia script-ului se va încheia
în momentul întreruperii conexiunii puteţi (sau nu!) să apelaţi funcţia
ignore_user_abort(). Implicit, în momentul în care conexiunea este
întreruptă, se întrerupe şi execuţia script-ului. Este posibil (chiar
recomandabil!) să fie definită o funcţie care va fi executată înaintea
întreruperii execuţiei script-ului. Aceasta poartă denumirea de funcţie
de dezactivare (shutdown function) şi este definită la fel ca orice
altă funcţie. Pentru a specifica faptul că o anumită funcţie trebuie
apelată înaintea intreruperii execuţiei, aceasta trebuie înregistrată
ca fiind funcţie de dezactivare. Aceasta se realizează printr-un apel
al funcţiei registrer_shutdown_function(). În cadrul funcţiei se poate
testa dacă execuţia a fost determinată de întreruperea conexiunii prin
apelarea funcţiei connexion_aborted(). Aceasta va returna valoarea TRUE
dacă a fost întreruptă conexiunea. Funcţia de dezactivare va fi apelată
automat şi în cazul în care este depăşită limita de timp. În cadrul
funcţiei se poate testa dacă un astfel de eveniment a avut loc prin
apelarea funcţiei connection_aborted() care returnează valoarea TRUE în
cazul depăşirii acestei limite. Există posibilitatea de a testa ambele
indicatoare printr-un singur apel al funcţiei connection_status().
Funcţia va returna un număr întreg ai cărui biţi reprezintă
indicatoarele. De exemplu, dacă sunt setate indicatoarele ABORTED şi
TIMEOUT, valoarea returnată va fi 3. Trebuie remarcat faptul că este
posibil ca indicatorii ABORTED şi TIMEOUT să fie ambii setaţi la un
moment dat. Această situaţie poate apărea în cazul în care întreruperea
conexiunii este ignorată. PHP va detecta faptul că a fost întreruptă
conexiunea şi va seta indicatorul corespunzător. Totuşi, execuţia
script-ului va continua şi este posibil să expire şi limita de timp,
moment în care este setat şi indicatorul TIMEOUT. Implicit, limita de
timp este de 30 de secunde, dar ea poate fi modificată folosind funcţia
set_time_limit().

Fişiere aflate la distanţă

Aşa cum am spus în secţiunea dedicată includerii fişierelor, începând


cu versiunea PHP 4.3.0 este posibilă includerea de fişiere aflate pe
alte servere. Evident, este posibilă utilizarea de fişiere aflate pe
alte servere şi în alte scopuri. Practic, în aproape toate funcţiile
care manipulează fişiere, pot fi folosite atât fişiere locale, cât şi
fişiere aflate la distanţă. În continuare este prezentat modul în care
pot fi citite date dintr-un fişier aflat pe server:

Cod:

<?php
// accesam fisierul si setam atributul r de la citire (read)
$file = fopen("locatia/fisierului/nume_fisier.extensia", "r");
if(!$file)
{
echo "Fisierul nu poate fi accesat!\n";
exit;
}
// citirea datelor din fisier
// inchiderea fisierului
fclose ($file);
?>
Pentru a scrie în fişier se poate folosi o secvenţă de tipul:

Cod:

<?php
// accesam fisierul si setam atributul w de la scriere (write)
$file=fopen("locatia/fisierului/nume_fisier.extensia", "w");
if(!$file)
{
echo "Fisierul nu poate fi accesat!\n";
exit;
}
// scrierea datelor in fisier
// inchiderea fisierului
fclose ($file);
?>

Puteţi folosii aceste idei pentru a creea o pagină cu acces


restricţionat, şi unde să scrieţi într-un fişier pe server datele
vizitatorului (cum ar fi adresa lui de ip, host, timpul cât a stat pe
pagina respectivă, ce pagini a vizitat etc...).

Descrierea funcţiilor care pot fi utilizate la manipularea tablourilor

Funcţia array_change_key_case

Această funcţie realizează conversia tuturor literelor care apar în cadrul denumirilor cheilor
elementelor unui tablou. Funcţia are doi parametri: un tablou asupra căruia se vor efectua
modificările şi un întreg care arată dacă se vor converti toate literele mari în litere mici sau
invers. Pentru acest parametru pot fi utilizate constantele predefinite CASE_UPPER (conversie
la litere mari) şi CASE_LOWER (conversie la litere mici). Acest parametru poate lipsi, caz în
care va avea valoarea implicită CASE_LOWER , deci va realiza conversia tuturor literelor mari
în litere mici. Următorul script PHP ilustrează modul în care poate fi utilizată această funcţie.

Cod:

<?php
$a = array("Pagina" => "Pagina", "de" => "de", "Php" => "Php");
echo "<TABLE cellpadding= 5>
<TR><TD><B>Tabloul initial:</B><TD>
<TT>";
print_r($a);
echo "</TT>
<TR><TD><B>Tabloul dupa conversia implicita:</B><TD><TT>";
$b = array_change_key_case($a);
print_r($b);
echo "</TT><TR><TD><B>Tabloul dupa conversia la litere mari:
</B><TD><TT>";
$b = array_change_key_case($a,CASE_UPPER);
print_r($b);
echo "</TT><TR><TD><B>Tabloul dupa conversia la litere mici:
</B><TD><TT>";
$b = array_change_key_case($a,CASE_LOWER);
print_r($b);
echo "</TT></TABLE>";
?>

După cum se poate vedea, funcţia are efect doar asupra cheilor elementelor, valorile acestora
rămânând nemodificate.

Funcţia array_chunks

Această funcţie poate fi utilizată pentru a împărţi un tablou în mai multe bucăţti (chunks). Ea
are trei parametri, şi anume: vectorul care urmează a fi împărţit, dimensiunea unei bucăţi
(numărul de elemente) şi un indicator care arată dacă se păstrează sau nu cheile elementelor
(acesta poate lipsi; în acest caz are valoarea implicită false, deci nu se vor păstra cheile
elementelor). În cazul în care numărul elementelor tabloului iniţial nu este multiplu al
dimensiunii unei bucăţi, atunci ultima bucată va fi mai "scurtă" . Funcţia va returna un tablou
al bucăţilor (un tablou de tablouri).
În continuare este prezentat un exemplu care arată utilizarea acestei funcţii:

Cod:

<?php
$vector = array("a", "b", "c", "d", "e");
echo "<pre>";
print_r(array_chunk($vector, 2));
echo "<p>";
print_r(array_chunk($vector, 2, TRUE));
echo "</pre>";
?>

Funcţia array_count_values

Această funcţie are ca parametru un tablou şi returnează un alt tablou ale cărui elemente au
chei date de valorile elementelor tabloului transmis ca parametru. Pentru fiecare valoare se va
genera un singur element (chiar dacă valoarea apare de mai multe ori), iar valoarea
elementului respectiv este dată de numărul apariţiilor. De exemplu, în urma execuţiei unei
secvenţe de forma:

$tablou = array (1, "Pagina" , 1, "mea" , "Pagina" );


$rez = array_count_values ($tablou);

vectorul $rez va conţine trei elemente, acestea vor avea cheile 1, Paginaşi mea, iar valorile
vor fi 2, 2, respectiv 1.

Funcţiile array_diff şi array_diff_assoc

Uneori dorim să eliminăm dintr-un tablou anumite elemente; în acest scop pot fi utilizate
funcţiile array_diff( ) şi array_diff_assoc( ) .
Acestea au ca parametri mai multe tablouri şi returnează un tablou care conţine toate
elementele din tabloul reprezentat de primul parametru care nu apar în nici unul dintre
tablourile corespunzatoare celui de-al doilea parametru. În cazul funcţiei array_diff( ) sunt
eliminate elemente din primul tablou dacă în celelalte există elemente cu aceeaşi valoare. În
cazul functiei array_diff_assoc( ) sunt eliminate elemente din primul tablou dacă în celelalte
există elemente cu aceeaşi valoare şi aceeaşi cheie.
Funcţia array_fill

Această funcţie poate fi utilizată pentru a completa cu o anumită valoare elementele unui
tablou. Funcţia are trei parametri: primul reprezintă indicele la care începe completarea, al
doilea reprezintă numărul elementelor completate, iar cel de-al treilea indică valoarea cu care
se completează elementele. De exemplu, în urma executării instrucţiunii

$a = array_fill(5, 6, 'Pagina mea! ' );

vom avea un tablou cu sase elemente (cheile acestora sunt 5, 6, 7, 8, 9 si 10), valorile tuturor
acestora fiind Pagina mea! .

Funcţia array_filter

Această funcţie realizează o filtrare a elementelor unui vector pe baza unei funcţii. Funcţia
array_filter( ) are ca parametri un tablou şi identificatorul funcţiei care este utilizată pentru
filtrare. Această funcţie trebuie să fie definită şi va fi apelată pentru fiecare element al
vectorului. În cazul în care funcţia returnează valoarea true (eventual, în urma conversiei la
tipul boolean), elementul este păstrat; în caz contrar, acesta este eliminat. Funcţia
array_filter( ) returnează vectorul obţinut după eliminarea elementelor. În continuare este
prezentat un exemplu în care se utilizează această funcţie pentru a filtra elementele unui
vector în funcţie de paritatea acestora.

Cod:

<?php
function impar($var)
{
return $var % 2;
}
function par($var)
{
return 1 - $var % 2;
}
$vector = array("2", "4", "5", "7");
echo "<pre>";
print_r(array_filter($vector, par));
echo "<p>";
print_r(array_filter($vector, impar));
echo "</pre>";
?>

Funcţia array_flip

Această funcţie are ca parametru un tablou şi returnează un alt tablou în care a fost realizată
o interschimbare a cheilor elementelor cu valorile. Cu alte cuvinte, pentru fiecare element va fi
creat un element a cărui cheie va fi vaIoarea elementului în tabloul iniţial şi a cărui valoare va
fi cheia elementului din tabloul iniţial. De exemplu, pentru tabloul definit prin

$tablou = array("A" => "Pagina" , "B" => "de" , "C" => "php");

în urma executării apelului

$b = array_flip($tablou)

tabloul $b va avea forma


array("Pagina" => "A" , "de" => "B" , "php" => "C")

În cazul în care în vectorul transmis ca parametru există mai multe elemente care au aceeaşi
valoare, datorită faptului că elementele unui vector trebuie să aibă chei distincte, vor fi
eliminate toate aceste elemente, cu excepţia ultimului.

Funcţiile array_intersect şi array_intersect_assoc

Aceste funcţii au un comportament similar funcţiilor array_diff( ), respectiv


array_diff_assoc( ). Singura diferenţă este dată de faptul că tabloul rezultat va conţine toate
elementele care se află în fiecare dintre tablourile transmise ca parametri (pentru funcţia
array_diff( ) elementele trebuie să aibă aceeaşi valoare, în timp ce pentru funcţia
array_diff_assoc( ) ele trebuie să aibă aceeaşi cheie şi aceeaşi valoare).

Funcţia array_key_exists

Această funcţie are doi parametri (o cheie şi un vector) şi verifică, aşa cum sugerează şi
numele, dacă vectorul conţine un element cu cheia respectivă. Funcţia returnează o valoare
logică, iar pentru parametrul care reprezintă cheia poate fi folosită orice valoare care poate fi
cheie într-un vector.

Funcţia array_keys şi array_values

Aceste funcţii returnează un vector care conţine ca valori toate cheile (respectiv toate valorile)
elementelor unui tablou transmis ca parametru. Pentru funcţia array_keys( ), în cazul în care
se foloseste un parametru suplimentar, vectorul rezultat va conţine doar cheile elementelor
care au valoarea egală cu cea indicată de acest parametru.

Funcţia array_map

Această funcţie realizează o transformare a elementelor unui vector pe baza unei funcţii.
Funcţia este transmisă ca parametru şi este aplicată tuturor elementelor unui vector care este,
şi el, transmis ca parametru. Iată un exemplu:

Cod:

<?php
function cub($n)
{
return $n * $n * $n;
}
$a = array(l, 2, 3, 4, 5);
$b = array_map("cub", $a);
?>

În urma executării secvenţei, vectorul $b va avea cinci elemente ale căror valori vor fi 1, 8,
27, 64 şi 125.
Există posibilitatea de a transmite mai multe tablouri ca parametri. În acest caz, numărul
argumentelor funcţiei utilizate trebuie să fie egal cu numărul tablourilor transmise şi se
recomandă ca tablourile să aibă acelaşi număr de elemente. În caz contrar, tablourile mai
"scurte" vor fi completate cu elemente nule. Un artificiu interesant permite crearea unor
vectori de vectori folosind funcţia array_map( ). Pentru aceasta vom utiliza valoarea null
pentru funcţia transmisă ca parametru. Vom prezenta în continuare un exemplu:
Cod:

<?php
$a = array("unu", "doi", "trei");
$b = array("one", "two", "three");
$c = array("un", "deux", "trois");
$d = array_map(null, $a, $b, $c);
?>

Vectorul $d va avea urmatoarea structura:

Citat:

Array
(
[0] => Array
(
[0] => unu
[1] => one
[2] => un
)
[1] => Array
(
[0] => doi
[2] => two
[3] => deux
)
[2] => Array
(
[0] => trei
[1] => three
[2] => trois
)
)

Funcţiile array_merge şi array_merge_recursive

Aceste funcţii realizează o "interclasare" a două sau mai multe tablouri prin adăugarea
elementelor unui vector la sfârşitul tabloului anterior. În cazul în care există elemente cu
aceeaşi cheie (reprezentată de un şir de caractere) în tabloul rezultat va apărea un singur
element cu cheia respectivă, şi anume primul întâlnit în timpul interclasării. În cazul în care
cheia identică este reprezentată de un număr, în tabloul rezultat vor apărea ambele valori, dar
valoarea corespunzătoare unei chei care apare deja în tablou va avea cheia reprezentată de
cel mai mic număr mai mare decât cheia iniţială care nu apare înca în tabloul rezultat.
În cazul în care tablourile conţin elemente care sunt tablouri, atunci funcţia este
array_merge_recursive( ) şi are ca efect şi interclasarea acestor tablouri (care sunt elemente
ale altor tablouri) şi procedeul continua recursiv. În cele ce urmeaza vom prezenta un exemplu
care ilustrează diferenţele dintre cele două funcţii.

Cod:

<?php
$v1 = array(
"culoare" => array(
"preferata" => "rosu"),
(5));
$v2 = array(
10,
"culoare" => array(
"preferata" => "verde",
"albastru"));
echo "<PRE>";
print_r(array_merge($v1, $v2));
echo "<br>";
print_r(array_merge_recursive($v1, $v2));
echo "</PRE>";
?>

Funcţia array_multisort

Această funcţie poate fi utilizată pentru a sorta mai multe tablouri sau un tablou
multidimensional. Primul parametru al funcţiei trebuie să fie un tablou, iar următoarele pot fi
tablouri şi indicatori de sortare. Fiecare indicator de sortare descrie caracteristici ale sortării
pentru cel mai apropiat tablou aflat înaintea indicatorului în lista de parametri. Exista două
categorii de indicatori de sortare:

- indicatori de ordine:
- SORT_ASC: sortare în ordine crescătoare;
- SORT_DESC: sortare în ordine descrescătoare;

- indicatori de tip:
- SORT_REGULAR: elementele sunt comparate fără a efectua conversii;
- SORT_NUMERIC: elementele sunt comparate după ce sunt convertite la valori numerice;
- SORT_STRING: elementele sunt comparate după ce sunt convertite în şiruri de caractere.

Pentru un tablou nu pot fi specificaţi doi indicatori care fac parte din aceeaşi categorie (de
exemplu, nu este permisă specificarea pentru un tablou a indicatorilor SORT_NUMERIC şi
SORT_STRING). Nu este obligatorie specificarea ambelor tipuri de indicatori pentru fiecare
tablou. În cazul în care indicatorii lipsesc, sunt utilizate valorile implicite SORT_ASC şi
SORT_REGULAR. Tablourile transmise ca parametri sunt considerate a fi coloane într-o matrice
care trebuie sortată pe linii. Primul tablou reprezintă criteriul de baza. Pentru valori egale în
primul tablou se ia în considerare al doilea criteriu (reprezentat de al doilea tablou). Pentru
valori egale în primele două tablouri se ia în considerare al treilea criteriu şi aşa mai departe.
Funcţia returnează o valoare logică ce indică dacă operaţia de sortare sa încheiat cu succes.
Să considerăm doi vectori definiţi astfel:

$v1 = array("10", 100, 100, "a");


$v2 = array(1, 3, "2", 1);

În urma execuţiei apelului array_multisort($v1, $v2); vectorul $v1 va conţine elementele


"10", "a", 100 şi 100, în timp ce vectorul $v2 va conţine elementele 1, 1, "2" şi 3. Se observă
că elementele din al doilea vector corespunzătoare elementelor cu valori egale din primul
vector (3 şi "2" corespund celor două elemente cu valoarea 100 din primul vector) au fost şi
ele sortate.

Vom prezenta acum un exemplu în care vom sorta un tablou bidimensional definit prin:

$v = array(array("10", 100, 100, "a"), array(1,3,"2",11));

În urma unui apel de forma:

array_multisort($v[0], SORT_ASC, SORT_STRING, $v[l], SORT_NUMERIC, SORT_DESC);


prima linie a tabloului va conţine elementele "10", 100, 100 şi "a" (au fost sortate crescător ca
şiruri de caractere), iar cea de-a doua va conţine elementele 1, 3, "2" şi 1 (pentru valori egale
în prima linie, elementele de pe a doua au fost sortate descrescător ca valori numerice).

Funcţia array_pad

Această funcţie poate fi utilizată pentru a completa un tablou cu o valoare dată, astfel încât să
aibă o dimensiune specificată. Funcţia are trei parametri: tabloul care trebuie completat,
dimensiunea pe care trebuie să o aibă tabloul completat şi valoarea cu care este completat
tabloul. Tabloul va fi completat astfel încât dimensiunea sa să fie egală cu valoarea absolută a
celui deal doilea parametru. În cazul în care valoarea acestui parametru este pozitivă, tabloul
va fi completat la dreapta, iar dacă aceasta este negativă, tabloul va fi completat la stânga.
Dacă valoarea absolută a acestui parametru este mai mică sau egală cu dimensiunea tabloului
transmis ca parametru, atunci nu sunt adăugate elemente. Funcţia returnează tabloul obţinut
după completare.
Să considerăm vectorul definit prin:

$v = array(2 , 4 , 5 , 7);

În continuare vom prezenta câteva apeluri ale funcţiei şi vectorii returnaţi de aceasta:

$r = array_pad($v2, 6, -1) : (2, 4, 5, 7, -1, -1);


$r = array_pad($v2, -7, 0) : (0, 0, 0, 2, 4, 5, 7);
$r = array_pad($v2, 3, 5) : (2, 4, 5, 7);
[nu este adăugat nici un element]

Funcţiile array_pop şi array_push

Aceste funcţii permit utilizarea tablourilor similar stivelor. Funcţia array_pop( ) este utilizată
pentru a elimina un element al tabloului (ultimul), iar funcţia array_push( ) pentru a adăuga în
tablou unul sau mai multe elemente.
Să considerăm ca vectorul $v este vid. În urma execuţiei apelului
array_push( $v , 1 , 2 , 3)
acesta va conţine elementele 1, 2 şi 3. În acest moment, un apel de forma array_pop($v) va
returna valoarea 3, iar vectorul $v va conţine elementele 1 şi 2. În cazul în care vectorul
transmis ca parametru este vid, funcţia array_pop( ) returnează valoarea null. Funcţia
array_push( ) va returna întotdeauna noua dimensiune a vectorului.

Funcţiile array_shift şi array_unshift

Perechile funcţiilor array_pop( ) şi array_push( ) sunt array_shift( ) şi array_unshift( ).


Acestea pot fi utilizate pentru a insera sau elimina elemente la începutul unui tablou.
Executarea acestor funcţii va duce la modificarea cheilor întregi astfel încât acestea să înceapă
de la 0.

Funcţia array_rand

Această funcţie permite alegerea aleatoare a unui număr de elemente dintr-un vector. Funcţia
are ca parametri un vector şi o valoare numerică ce indică numărul elementelor care vor fi
alese. Acest al doilea parametru poate lipsi, caz în care are valoarea implicită 1. În cazul în
care se alege un singur element, funcţia va returna cheia acestuia. În caz contrar, funcţia va
returna un tablou care va conţine cheile elementelor alese. În continuare este un exemplu
care ilustrează modul de utilizare a acestei funcţii.

Cod:

<?php
$v = array(2, 4, 5, 7);
$a = array_rand($v);
echo "A fost ales elementul a carui cheie este <B>$a</B>.
Valoarea acestui element este <B>$v[$a]</B>.<BR><BR>";
$a = array_rand($v);
echo "A fost ales elementul a carui cheie este <B>$a</B>.
Valoarea acestui element este <B>$v[$a]</B>.<BR><BR>";
$a = array_rand($v, 2);
echo "Au fost alese elementele ale caror chei sunt <B>$a[0]</B> si <B>$
a[1]</B>.
Valorile acestor elemente sunt <B>".$v[$a[0]]."</B> si
<B>".$v[$a[1]]."</B>.<BR><BR>";
$a = array_rand($v, 2);
echo "Au fost alese elementele ale caror chei sunt <B>$a[0]</B> si <B>$
a[1]</B>.
Valorile acestor elemente sunt <B>".$v[$a[0]]."</B> si <B>" .
$v[$a[1]]."</B>.";
?>

Funcţia array_reduce

Această funcţie aplică o altă funcţie transmisă ca parametru asupra elementelor unui tablou
până în momentul în care tabloul este redus la o singură valoare. Mai exact, funcţia transmisă
ca parametru este apelată pentru primele două elemente ale tabloului. Cele două elemente
sunt eliminate şi în tablou este inserat pe prima poziţie rezultatul apelului funcţiei. Procedeul
continuă până în momentul în care vectorul conţine o singură valoare care este returnată.
Exista şi posibilitatea de a transmite o valoare iniţială pentru efectuarea operaţiilor. În acest
caz funcţia transmisă ca parametru va fi apelată pentru valoarea iniţială şi primul element al
tabloului. În cazul în care tabloul este vid, rezultatul apelului va fi această valoare iniţială. Să
considerăm funcţiile definite astfel:

function S($v, $w)


{
return $v + $w;
}
function P($v, $w)
{
return $v + $w;
}

În urma executării instrucţiunilor:

$a = array(2, 4, 5, 7);
$x = array( );
$b = array_reduce($a, "S") ;
$c = array_reduce($a, "P", 10) ;
$d = array_reduce($x, "S", l) ;

valorile variabilelor $b, $c şi $d vor fi 18 (2+4+5+7), 2800 (10*2*4*5*7), respectiv 1


(datorita faptului ca vectorul $x este vid).

Funcţia array_reverse

Această funcţie inversează ordinea elementelor unui vector transmis ca parametru. În cazul în
care este prezent un al doilea parametru şi valoarea acestuia este TRUE (eventual după o
conversie), atunci se păstrează corespondenţa dintre chei şi valori. Funcţia returnează tabloul
obţinut după inversare. Să considerăm tabloul definit astfel:

$v = array("Pagina", "de", "programare", array("martie", 2004));


În urma apelurilor $a = array_reverse($v) şi $b = array_reverse($v, TRUE) tablourile $a şi $b
vor avea forma prezentată mai jos:

Array Array
( (
[0] => Array [3] => Array
( (
[0] => martie [0] => martie
[1] => 2004 [1] => 2004
) )
[1] => programare [2] => programare
[2] => de [1] => de
[3] => Pagina [0] => Pagina
) )
Tabloul $a Tabloul $b

Funcţia array_search

Această funcţie verifică dacă un vector conţine un element care are o anumită valoare şi, dacă
un astfel de element există, returnează cheia acestuia. În caz contrar funcţia returnează
valoarea FALSE. Primul parametru al funcţiei este valoarea căutată, iar al doilea este vectorul
în care este căutata valoarea respectivă. Funcţia permite folosirea unui al treilea parametru
care este opţional. În cazul în care acesta există şi are valoarea TRUE, atunci în timpul căutării
se verifică şi egalitatea tipurilor.

Funcţia array_slice

Această funcţie poate fi utilizată pentru a prelua o porţiune a unui tablou. Primul parametru
reprezintă tabloul, al doilea reprezintă poziţia la care începe porţiunea preluată, iar al treilea
indica numărul elementelor preluate. Această funcţie ignoră cheile elementelor şi ia în
considerare pozitiile "reale" ale elementelor în tablou. În cazul în care valoarea celui de-al
doilea parametru este pozitivă, poziţia de început este determinată relativ faţă de începutul
tabloului. Pentru o valoare negativă, poziţia este determinată relativ faţă de sfârşitul tabloului.
În cazul în care valoarea celui de-al treilea parametru este pozitivă, ea va indica numărul
elementelor preluate. Dacă ea este negativă, atunci valoarea sa absolută va indica poziţia faţă
de sfârşitul vectorului la care se va "opri" preluarea elementelor. Acest parametru poate lipsi,
caz în care sunt preluate toate elementele, până la sfârşitul tabloului. Funcţia va returna un
tablou care va conţine elementele preluate.
În continuare este prezentat modul în care poate fi utilizată această funcţie pentru a prelua
porţiuni ale unui vector.

Cod:

<?php
function DisplayArray($v)
{
echo "<B>";
foreach($v as $val)
{
echo "$val<BR>";
}
echo "</B><BR>";
}
$v = array("a", "b", "c", "d", "e");
echo "<TT>Vectorul initial:";
DisplayArray($v);
echo "array_slice(\$v,2):";
DisplayArray(array_slice($v,2));
echo "array_slice(\$v,2,-1):";
DisplayArray(array_slice($v,2,-1));
echo "array_slice(\$v,-2,1):";
DisplayArray(array_slice($v,-2,1));
echo "array_slice(\$v,0,3):";
DisplayArray(array_slice($v,0,3));
echo "</TT>";
?>

Funcţia array_splice

Efectul acestei funcţii este similar efectului funcţiei array_slice( ), diferenţa constând în faptul
că porţiunea preluată este eliminată din tablou şi înlocuită cu elementele unui al patrulea
parametru care reprezintă un vector.

Funcţia array_sum

Această funcţie calculează suma elementelor unui tablou. În funcţie de tipul elementelor,
rezultatul va fi un număr întreg sau un număr real. Pentru valorile nenumerice se încearcă
efectuarea unei conversii la numere întregi sau reale şi în cazul în care valorile pot fi convertite
(rezultatul conversiei nu este 0) ele sunt luate în considerare în momentul calculării sumei. De
exemplu, în urma executării secvenţei:

$a = array(2, 4, 6, 8);
echo "suma(a) = ".array_sum($a)."\n";
$b = array("a" => 1.2 , "b" => 2.3 , "c" => 3.4);
echo "sum (b) = ".array_sum($b)."\n";

se va afisa:

sum(a) = 20
sum(b) = 6.9

Funcţia array_unique

Această funcţie elimină dintr-un vector toate valorile care apar de două sau mai multe ori şi
returnează vectorul obţinut în urma eliminării. Pentru a elimina elementele, funcţia le sortează
mai întâi considerandu-le şiruri de caractere. Apoi, pentru fiecare valoare care apare de mai
multe ori, va păstra prima cheie întâlnită în şirul sortat.

Funcţii de sortare

Interpretorul PHP pune la dispozitie o mulţime de funcţii care pot fi utilizate pentru a sorta
elementele unui tablou. Acestea sunt (în ordine alfabetică):
- arsort( ) - sortează un tablou în ordine descrescătoare şi păstrează asocierile dintre indici;
- asort( ) - sortează un tablou în ordine crescătoare şi păstrează asocierile dintre indici;
- krsort( ) - sortează un tablou în ordine descrescătoare în funcţie de cheile elementelor
acestuia;
- ksort( ) - sortează un tablou în ordine crescătoare în funcţie de cheile elementelor acestuia;
- natcasesort( ) - sortează un tablou folosind o "ordine naturală" fără a face distincţie între
literele mari şi literele mici;
- natsort( ) - sortează un tablou folosind o "ordine naturală" făcând distincţie între literele mari
şi literele mici;
- rsort( ) - sortează un tablou în ordine descrescătoare în funcţie de valorile elementelor
acestuia;
- sort( ) - sortează un tablou în ordine crescătoare în funcţie de valorile elementelor acestuia;
- uasort( ) - sortează un tablou folosind pentru comparări o funcţie indicată de utilizator şi
păstrează asocierile dintre indici;
- uksort( ) - sortează un tablou în funcţie de cheile acestuia folosind pentru comparări o
funcţie indicată de utilizator;
- usort( ) - sortează un tablou folosind pentru comparări o funcţie indicată de utilizator.

Toate funcţiile necesită un parametru care reprezintă vectorul care trebuie sortat.
Functiile arsort( ), asort( ), krsort( ), ksort( ), rsort( ) şi sort( ) permit utilizarea unui al doilea
parametru (opţional) care este un indicator de tip. Valoarea implicită a acestuia este
SORT_REGULAR. Al doilea parametru al funcţiilor uasort( ), uksort( ) şi usort( ) reprezintă
identificatorul funcţiei care va fi folosită pentru comparare.
Funcţiile natsort( ) şi natcasesort( ) nu permit utilizarea unui alt parametru şi stabilesc ordinea
aşa cum ar face o fiinţă umană (ordine naturală). De exemplu, pentru şirurile de caractere
IMG1.GIF, IMG2.GIF, IMG10.GIF şi IMG12.GIF, un algoritm "clasic" (bazat pe ordinea
lexicografică) ar stabili ordinea: IMG1. GIF, IMG10 .GIF, IMG12 .GIF şi IMG2 .GIF, dar
algoritmul care foloseste ordinea naturala nu ar efectua nici o modificare.

Funcţia compact

Această funcţie are ca argumente un număr variabil de şiruri de caractere sau tablouri. Ea
creează un tablou în care va insera toate şirurile care reprezintă o variabilă (aceste şiruri vor fi
chei, iar valorile elementelor corespunzătoare vor fi valorile variabilelor). În cazul tablourilor,
vor fi luate în considerare toate elementele care sunt şiruri de caractere, iar dacă tablourile
conţin elemente care, la randul lor, sunt tablouri, atunci procedeul se aplică recursiv şi asupra
acestora.

Funcţiile count şi sizeof

Aceaste funcţii returnează numarul elementelor unui vector transmis ca parametru. Teoretic,
parametrul poate să nu fie un vector, dar în acest caz se va returna valoarea 1 (doar tablourile
pot conţine mai multe elemente). Nu există nici o diferenţă între aceste funcţii.

Funcţii pentru elementul curent

Fiecărui vector îi este asociată o referinţă care indică elementul curent. Există mai multe
funcţii care pot utiliza această referinţă. Acestea sunt (în ordine alfabetică):
- current( ) - returnează valoarea elementului curent al tabloului;
- each( ) - returnează cheia şi valoarea elementului curent şi deplasează referinţa la elementul
următor; funcţia returnează un tablou cu patru elemente: două dintre ele au cheile 0şi key şi
conţin cheia elementului; celelalte două au cheile 1şi value şi conţin valoarea elementului;
- end( ) - deplasează referinţa la ultimul element al tabloului;
- key( ) - returnează cheia elementului curent al tabloului;
- next( ) - deplasează referinţa la următorul element al tabloului;
- pos( ) - returnează valoarea elementului curent al tabloului (are acelaşi efect ca şi funcţia
current( ) );
- prev( ) - deplasează referinţa la elementul anterior al tabloului;
- reset( ) - deplasează referinţa la primul element al tabloului.

Funcţia extract

Această funcţie este utilizată pentru a crea variabile pe baza valorilor elementelor unui vector.
Cheile elementelor vor deveni identificatori de variabile, iar valorile elementelor vor deveni
valorile variabilelor respective. Funcţia verifică dacă cheile reprezintă identificatori valizi ai
variabilelor sau dacă se încearcă crearea unei variabile care exista deja. Aceste situaţii sunt
tratate în funcţie de valoarea unui al doilea parametru care reprezintă un indicator şi este
opţional. Valorile posibile pentru acest parametru sunt următoarele:
- EXTR_OVERWRITE : dacă variabila există deja, valoarea curenta va fi suprascrisă;
- EXTR_OVERWRITE : dacă variabila există deja, valoarea curenta nu va fi modificată;
- EXTR_PREFIX_SAME: dacă variabila există deja, denumirea noii variabile va fi prefixată cu
un prefix transmis ca al treilea parametru al funcţiei;
- EXTR_PREFIX_ALL : denumirile tuturor variabilelor vor fi prefixate;
- EXTR_PREFIX_INVALID : în cazul în care o cheie nu reprezintă un identificator de variabilă
validă, denumirea cheii va fi prefixată;
- EXTR_IF_EXISTS : nu sunt create variabile noi, ci sunt doar suprascrise valorile variabilelor
care există deja;
- EXTR_PREFIX_IF_EXISTS : în cazul în care cheia reprezintă denumirea unei variabile, se
creează o nouă variabilă prefixată; dacă nu există o astfel de variabilă, nu este creată o
variabilă nouă;
- EXTR_REFS : variabilele create reprezintă referinţe; aşadar, prin intermediul lor pot fi
modificate şi elementele vectorului; acest indicator poate fi utilizat împreuna cu oricare dintre
celelalte cu ajutorul unei disjunctii logice.
Cel de-al treilea parametru al funcţiei trebuie să apară doar dacă valoarea celui de-al doilea
este unul din indicatorii ai cărui identificator conţine secvenţa PREFIX.
Al doilea parametru poate lipsi, caz în care are valoarea implicită EXTR_OVERWRITE.

Funcţia in_array

Această funcţie este similară funcţiei array_search( ), singura diferenţă fiind faptul că, în cazul
în care căutarea se încheie cu succes, nu este returnată cheia elementului găsit, ci valoarea
TRUE.

Funcţia range

Această funcţie returnează un vector care conţine toate valorile cuprinse între două limite date
(st şi dr). Primul element al vectorului va avea valoarea st, iar următoarele vor avea valorile st
+ 1, st + 2 etc. dacă st < dr, respectiv st - 1, st - 2 etc. dacă st > dr. Începând cu versiunea
PHP 4.4.0 exista şi posibilitatea de a crea şiruri în care diferenţa dintre doua elemente să fie
diferită de 1. În cele ce urmeaza este prezentat un document PHP care ilustrează modul de
utilizare a acestei funcţii.

Cod:

<?php
function DisplayArray($v)
{
echo "<B>";
foreach ($v as $val)
{
echo "$val<BR>";
}
echo "</B><BR>";
}
echo "<TT>";
DisplayArray (range(1,10));
DisplayArray (range(10,1));
DisplayArray (range('a', 'k'));
DisplayArray (range('k', 'a'));
echo "</TT>";
?>

Funcţia shuffle

Această funcţie poate fi utilizată pentru a "amesteca" elementele unui tablou. Ea nu


returnează nici o valoare, dar modifică ordinea elementelor tabloului.
Cod:

<?php
function DisplayArray($v)
{
echo "<B>";
foreach ($v as $val)
{
echo "$val<BR>";
}
echo "</B><BR>";
}
echo "<TT>Sirul initial:<BR>&nbsp;";
$a = range(l, 10);
DisplayArray($a);
echo "Sirul amestecat:<BR>&nbsp;";
shuffle($a);
DisplayArray($a);
echo "</TT>";
?>

Lucrul cu fişiere şi directoare

Încerc în continuare să vă prezint lucrul cu fişiere şi directoare (foldere) prin intermediul


scripturilor php. Deoarece va fi un articol destul de lung, îl voi împarţi în mai multe subcapitole
pentru a putea înţelege mai bine ideile prezentate. Voi începe în acest articol să va prezint
sistemul de fişiere UNIX (asemănător cu LINUX), apoi voi continua cu vizualizarea informaţiilor
despre fişiere, proprietăţile şi privilegiile ce se pot acorda fişierelor sau directoarelor
continuând apoi cu exemplificări. În articolele viitoare voi continua cu descrierea funcţiilor php
de prelucrare a fişierelor şi a directoarelor, bineînţeles cu exemplele aferente. Deci, să încep:

Sistemul de fişiere UNIX


Pentru a înţelege cum trebuie utilizat limbajul PHP pentru a lucra cu fişiere şi cataloage,
trebuie să înţelegeti sistemul de fişiere UNIX. Acest fapt este valabil chiar dacă foloşiţi PHP sub
Microsoft Windows, deoarece modelul folosit de PHP pentru lucrul cu fişiere şi directoare este
bazat pe UNIX. Un fişier este o serie de octeţi stocaţi pe o unitate de hard-disc, CD-ROM sau
alt mediu de stocare. Fişierele primesc nume pentru a se putea face cu uşurinţă referire la
acestea. Un nume de fişier UNIX poate avea o lungime aproape nelimitată şi poate include
aproape orice caracter. Totuşi pentru compatibilitate nu vă recomand să creaţi fişiere cu nume
mai lungi de 255 de caractere şi să nu conţină caractere speciale sau diacritice. Spre deosebire
de numele de fişiere Windows, numele de fişiere UNIX sunt sensibile la diferenţa între
majuscule şi minuscule; ca atare, index.php şi INDEX.PHP se referă la fişiere UNIX diferite.
Sunt sigur că unii dintre voi la început când puneaţi fişierele pe server vă întrebaţi de ce nu
merg anumite pagini deşi link-ul era corect şi pagina era pusă pe server... problema era
diferenţa dintre majuscule şi minuscule. Pentru a evita problemele, mai ales atunci când
deplasaţi fişiere între UNIX şi Windows, trebuie să folosiţi minuscule, cifre, puncte, caractere
de subliniere şi cratime în numele fişierelor; de asemenea, numele fişierelor trebuie să înceapă
cu o minusculă sau cu o cifră.

Vizualizarea informaţiilor despre fişiere


Pentru a vizualiza informaţii care descriu un fisier, emiteţi comanda:
ls -1 nume_fisier
unde nume_fisier este numele fişierului. Datele de ieşire includ următoarele câmpuri:
- tipul fişierului şi permisiunile de acces.
- legături: numărul legăturilor hard asociate acestui fişier. Fiecare legătură hard stabileşte un
nume după care este cunoscut fişierul respectiv. În general putem ignora acest câmp.
- Utilizator: numele utilizatorului care este posesorul fişierului
- Grup: Numele grupului care este posesorul fişierului
- Dimensiunea fişierului exprimată îin octeţi.
- Data modificării: data şi ora ultimei modificări a fişierului. Dacă fişierul nu a suferit modificări
recente, vor fi afişate data şi anul.
- Numele fişierului: numele atribuit fişierului.
În Windows, o comanda asemănătoare ar fi comanda dir. Rulaţi într-un script sub windows
comanda următoare:

Cod:

<?php
$comanda = `dir`;
//pentru ghilimele folositi tasta de langa 1
// deasupra tastei tab nu caracterul asta '.
echo $comanda;
?>

Pentru a funcţiona această comandă trebuie introdusă în ghilimele simple ` (a nu se folosi


ghilimelele ' )

Proprietatea asupra fişierelor


Fiecare fişier are un cont de utilizator asociat, cunoscut sub numele de posesor al fişierului.
Puteţi determina posesorul unui fişier prin emiterea comenzii ls. Utilizatorul care creează un
fişier devine posesorul fişierului. Cu toate acestea, un administrator de sistem poate atribui un
fişier unui alt utilizator, prin emiterea comenzii chown (este şi comandă php).
Administratorii de sistem UNIX pot defini grupuri de utilizatori, sau pur şi simplu grupuri, care
reprezintă seturi de utilizatori. Un utilizator poate fi membru al unui număr oricât de mare de
grupuri. Posesorul unui fişier poate atribui unui fişier un nou grup posesor prin emiterea
comenzii chgrp:
chgrp grup nume_fisier
unde nume_fisier este numele fişierului, iar grup este numele grupului. În afară de calitatea de
posesor al fişierului, utilizatorul care emite comanda trebuie să fie un membru al grupului
grup.

Privilegii de fişier
Privilegiile asociate unui fişier determină operaţiile pe care utilizatorii le pot efectua cu fişierul
respectiv. Privilegiile sunt date sub forma a trei grupuri alcătuite din câte trei caractere
fiecare; cu alte cuvinte, trei triade. Prima triadă indică privilegiile acordate posesorului
fişierului. Cea de-a doua triadă indică privilegiile acordate membrilor grupului care este
posesorul fişierului. Cea de-a treia triadă indică privilegiile acordate altor utilizatori, cu alte
cuvinte, persoanelor care nu sunt nici posesoare ale fişierului şi nici nu sunt membre ale
grupului care care este posesorul fişierului. Fiecare caracter al unei triade de privilegii poate fi
o literă sau o cratimă. Literele au următoarele semnificaţii:

- r, fişierul poate fi citit


- w, se poate scrie în fişier
- x, conţinutul fişierului poate fi executat.

Privilegiul x este semnificativ numai pentru fişierele care includ un conţinut executabil, cum
sunt fişierele binare executabile sau anumite categorii de scripturi. Caracterele unei triade
apar întotdeauna în secvenţa rwx. Daca o anumită literă este înlocuită de o cratimă, privilegiul
asociat nu este utilizabil. De exemplu, avem un fişier cu privilegiile următoare:

rwxr-xr--

Aceste caractere au următoarea semnificaţie:

- rwx, posesorul fişierului poate citi, scrie sau executa fişierul


- r-x, membrii grupului posesor al fişierului pot citi sau executa fişierul, dar nu pot scrie în
fişier
- r--, alti utilizatori pot citi fişierul, dar nu pot scrie în fişier sau executa conţinutul fişierului.

Posesorul unui fişier poate modifica privilegiile asociate fişierului emiţând comanda chmod.
Această comandă are două forme. O formă vă permite să specificaţi privilegiile folosind cifre
scrise în octal; cealaltă vă permite să le specificaţi folosind litere. Pentru a specifica privilegiile
folosind cifre în octal, calculaţi valoarea numerică a fiecărei triade. Pentru aceasta, însumaţi
numerele corespunzătoare fiecărui privilegiu disponibil din cadrul triadei. Numerele asociate
privilegiilor sunt:

r- 4
w-2
x-1

De exemplu, privilegiul rwx are valoarea 4+2+1 = 7. Similar, privilegiul r-x are valoarea 4+1
= 5, iar privilegiul r-- are valoarea 4. După ce aţi calculat valoarea numerică a fiecărei triade,
formaţi un număr din trei cifre scris în octal. De exemplu, privilegiile rwxr-xr-- corespund
valorii în octal 754. Forma comenzii chmod care foloseste cifre în octal este următoarea:

chmod mod nume_fisier

unde mod este numărul din trei cifre scris în octal care indică privilegiile, iar nume_fisier este
numele fişierului căruia urmează a i se aplica privilegiile. De exemplu, pentru a acorda
posesorului acces complet la fişierul test şi pentru a acorda altor utilizatori numai acces de
citire, emiteţi comanda:

chmod 744 test

Majoritatea utilizatorilor găsesc mai comodă utilizarea acelei forme a comenzii chmod care le
permite specificarea privilegiilor folosind litere. Această formă alternativă vă permite să
specificaţi privilegii, precum şi să adaugaţi sau să extrageti privilegii dintr-un fişier.

chmod utilizatori operatie privilegii

Între argumentele comenzii nu sunt permise spaţii. Argumentul utilizatori include între una şi
trei dintre următoarele litere:

- u, care indică utilizatorul posesor al fişierului


- g, care indică pe membrii grupului posesor al fişierului
- o, care indică utilizatori alţii decât posesorul şi membrii grupului posesor.

Argumentul operatie este unul din următoarele:

- r, fişierul poate fi citit


- w, în fişier este permisă scrierea
- x, conţinutul fişierului poate fi executat

Se pot specifica mai mulţi utilizatori, mai multe operaţii şi mai multe grupuri; fiecare
specificaţie trebuie separată de următoarea cu ajutorul unei virgule. De exemplu, iată o
comandă care atribuie privilegiile rwxr--r-- pentru fişierul test:

chmod u=rwx,g=r,o=r test

Iată o comandă care retrage privilegiile de scriere fiecărui utilizator, cu excepţia posesorului
fişierului, respectiv adăuga privilegiile de executare la privilegiile posesorului fişierului:

chmod u+x,go-w test

Această comandă nu modifică nici privilegiile de citire şi de scriere ale posesorului fişierului,
nici privilegiile de citire şi de execuţie ale celorlati utilizatori.
Sistemele UNIX furnizează un cont special de utilizator, denumit radacina (root) sau super-
utilizator (superuser), care poate obţine acces la fişiere şi le poate manipula fără nici un fel de
restricţii. Administratorul unui sistem este, în general, singura persoană autorizată să utilizeze
contul rădăcină. Uneori, administratorii de sistem folosesc numeroase privilegii speciale astfel
că pot apărea şi alte privilegii în afară de r,w şi x.. De exemplu, un privilegiu special, cunoscut
sub numele de setuid, modifică temporar identitatea utilizatorului deţinător al acestui privilegiu
care ruleaza un fişier program. Asemenea privilegii speciale nu sunt, în general, folosite de
programatorii aplicaţiilor PHP.

Crearea unui director (folder sau catalog)


Pentru a crea un director, invocaţi funcţia mkdir(), care are următoarea formă:

mkdir(nume_director, mod)

unde nume_director este calea absolută sau relativă


(O cale absolută este calea care începe de la directorul rădăcină urmând structura
arborescentă a directoarelor şi sub-directoarelor acestuia până se ajunge la directorul dorit.
Fiecare director din listă este separat de directorul următor de un caracter slash orientat
înainte (/). Calea relativă se referă la calea unui fişier sau director începând de la directorul
curent de lucru.
De exemplu, dacă fişierul index.php se află în directorul /home/tutoriale/articole şi dorim să
includem în el un alt fişier numit test.php aflat cu un director mai sus îl putem accesa relativ la
locaţia prezentă astfel ../test.php)
sau numele directorului care urmează a fi creat, iar mod atribuie privilegiile care trebuie
acordate noului director. În mod normal, prima cifră a argumentului mod trebuie să fie 0,
astfel încat PHP să-l perceapă ca pe o valoare scrisă în octal. Funcţia returneaza true dacă
creează directorul; în caz contrar, returnează false. De exemplu, pentru a crea un director
denumit "test" şi pentru a-i atribui privilegiile "rwxr-x--x", invocaţi functia mkdir() astfel:

mkdir("test", 0751)

Puteţi folosi funcţia rename() pentru a modifica numele unui director.

Ştergerea unui director


Pentru a şterge un director, se foloseşte funcţia rmdir(), transferându-i ca argument calea sau
numele directorului care urmează a fi şters. De exemplu, pentru a şterge directorul
"home/tutoriale/teste/vechi", invocaţi funcţia rmdir() astfel:

rmdir("home/tutoriale/teste/vechi")

Se pot sterge numai directoare vide. Funcţia va returna zero în cazul producerii unei erori.

Privilegii pentru directoare


Ca şi fişierele, directoarele au privilegii asociate. Privilegiile unui director se notează folosind
aceleaşi litere care indică privilegiile fişierelor; cu toate acestea, literele au semnificaţii
oarecum diferite atunci când se aplică asupra directoarelor:
- r, directorul poate fi citit; cu alte cuvinte, sub-directoarele şi fişierele pe care le conţine pot fi
afişate
- w, directorul poate fi scris; cu alte cuvinte, sub-directoarele şi fişierele pe care le conţine pot
fi create în catalog şi apoi şterse de acolo.
- x, directorul se poate folosi, cu alte cuvinte, sub-directoarele şi fişierele pe care le conţine
sunt accesibile.

Vizualizarea şi modificarea privilegiilor de director


Puteţi invoca funcţia chmod(), folosind ca argument un fişier sau un director. Puteţi vedea
privilegiile de director utilizând funcţia fileperms().

Obţinerea şi modificarea directorului de lucru


Functia getcwd() returnează un şir care conţine directorul curent de lucru. Funcţia nu necesită
argumente şi, implicit, poate fi utilizată astfel:

$director_curent = getcwd();

Pentru a schimba directorul curent de lucru, invocaţi funcţia chdir(), care are următoarea
formă:

chdir(nume_director)

unde nume_director este calea sau numele directorului de lucru dorit. Funcţia returnează true
dacă operaţia reuşeşte; în caz contrar, returnează false. De exemplu, pentru a face din /teste
directorul curent de lucru, invocaţi funcţia chdir() după cum urmează:

$schimba_dir = chdir("/teste");
if (!$schimba_dir) { die("<br>A aparut o eroare la schimbarea directorului curent de
lucru.") }

Manipularea căilor de acces


Funcţia dirname() preia calea de acces la un fişier şi returnează toată calea, mai puţin
componenta finală a căii specificate. În cazul în care componenta finală este un fişier, funcţia
vă ajută să izolaţi numele fişierului de restul căii. De exemplu, dacă se dă calea
"home/tutoriale/teste/test.php", funcţia va returna "home/tutoriale/teste". Funcţia are
următoarea formă:

dirname(cale)

Funcţia basename() execută operaţia complementară, returnând numai componenta finală a


căii specificate. De exemplu, dacă este dată calea "home/tutoriale/teste/test.php", funcţia va
returna "test.php". Funcţia are următoarea formă:

basename(cale)

Dacă doriţi să executaţi mai multe operaţii cu o cale, funcţia pathinfo() vă poate fi de folos.
Această funcţie returnează un tablou asociativ care include trei elemente: rezultatul invocării
funcţiei dirname() având ca argument calea respectivă, rezultatul invocării funcţiei
basename() având ca argument calea respectivă, precum şi extensia fişierului (dacă există)
asociată rezultatului invocării funcţiei basename() având ca argument calea respectivă. Iată
un exemplu care prezintă modul de utilizare a funcţiei pathinfo():
Cod:

<?php
$info = pathinfo("/home/tutoriale/teste/test.php");
foreach ($info as $nume=>$valoare)
{ echo "<br>$nume => $valoare"; }
?>

Datele de ieşire ale exemplului vor fi:

Citat:

dirname => /home/tutoriale/teste


basename => test.php
extension => php

Versiunea PHP 4.04pl1 işi încheie execuţia dacă invocaţi funcţia pathinfo() pe o cale din care
lipseste extensia fişierului. Se pare că acest defect de program a fost remediat în versiunea
PHP 4.05

Citirea conţinutului unui director


PHP furnizează trei funcţii care vă permit să citiţi conţinutul unui director, ca şi cum directorul
ar fi un fişier. Aceste funcţii sunt:

- opendir(), care permite citirea unui director


- readdir(), care citeste o intrare dintr-un director
- closedir(), care închide directorul, eliberând resursele alocate de funcţia opendir()

Rezultatul apelării funcţiei readdir() este un şir care conţine numele următorului fişier sau sub-
director al directorului deschis. Funcţia returnează false atunci când au fost citite toate intrările
din catalog. Exemplu:

Cod:

<?php
$director = opendir("/home/tutoriale/teste");
if (!$director)
{
die("A aparut o eroare la deschiderea directorului");
}
$citire = readdir($director);
while ($citire)
{
echo "<br>$citire";
$citire = readdir($director);
}
closedir($director);
?>

Acest exemplu afişează conţinutul directorului "/home/tutoriale/teste" (atât sub-directoarele


cât şi fişierele)

Obţinerea atributelor unui fişier


PHP furnizează numeroase funcţii care vă permit să obţineţi informaţii care descriu un fişier.
Tabelul de mai jos rezumă cele mai cunoscute dintre aceste funcţii.

Funcţie Descriere
file_exists() returnează true dacă fişierul specificat există, respectiv false în caz contrar.
fileatime() returnează timpul de acces la fişier sub formă de amprentă de timp UNIX
returnează timpul de modificare al i-nodului (structura de date care conţine
filectime()
informaţii despre fişierele UNIX) sub formă de amprentă de timp UNIX
filegroup() returnează identificatorul numeric al grupului care deţine fişierul
returnează momentul de timp al modificării fişierului sub formă de amprentă de
filemtime()
timp UNIX.
fileowner() returnează identificatorul numeric de utilizator al fişierului
fileperms() returnează permisiunile fişierului <;/tr>
filesize() returnează dimensiunea fişierului, în octeţi.
returnează tipul fişierului, în speţă "fifo", "char", "dir", "block", "link", "file" sau
filetype()
"unknown".
returnează true dacă fişierul specificat există şi este un director, în caz contrar
is_dir()
returnează false
returnează true dacă fişierul specificat există şi este un fişier obişnuit; în caz
is_file()
contrar, returnează false.
returnează true dacă fişierul specificat există şi poate fi citit, în caz contrar
is_readable()
returnează false.
returnează true dacă fişierul specificat există şi se poate scrie în acel fişier; în caz
is_writable()
contrar, returnează false.

Funcţiile fileowner() şi filegroup() returnează fiecare un identificator numeric; puteţi converti


identificatorul numeric într-un şir prin invocarea funcţiei posix_getpwuid() cu un identificator
de utilizator, respectiv a funcţiei posix_getgrgid() cu un identificator de grup. Un exemplu al
acestor funcţii este dat mai jos.

Cod:

<?php
$nume_fisier = "pagina_demo.php";
$rezultat = file_exists($nume_fisier);
echo "<br>file_exists(): $rezultat";

$rezultat = posix_getpwuid(fileowner($nume_fisier));
$rezultat = $rezultat["name"];
echo "<br>fileowner(): $rezultat";

$rezultat = posix_getgrgid(filegroup($nume_fisier));
$rezultat = $rezultat["name"];
echo "<br>filegroup(): $rezultat";

$rezultat = filetype($nume_fisier);
echo "<br>filetype(): $rezultat";

$rezultat = filesize($nume_fisier);
echo "<br>filesize(): $rezultat";

$rezultat = fileatime($nume_fisier);
$rezultat = date("m-d-Y H:i", $rezultat);
echo "<br>fileatime(): $rezultat";

$rezultat = filectime($nume_fisier);
$rezultat = date("m-d-Y H:i", $rezultat);
echo "<br>filectime(): $rezultat";

$rezultat = filemtime($nume_fisier);
$rezultat = date("m-d-Y H:i", $rezultat);
echo "<br>filemtime(): $rezultat";

$rezultat = fileperms($nume_fisier);
$rezultat = decoct($rezultat);
echo "<br>fileperms(): $rezultat";

$rezultat = is_file($nume_fisier);
echo "<br>is_file(): $rezultat";

$rezultat = is_dir($nume_fisier);
echo "<br>is_dir(): $rezultat";

$rezultat = is_readable($nume_fisier);
echo "<br>is_readable(): $rezultat";

$rezultat = is_writable($nume_fisier);
echo "<br>is_writable(): $rezultat";
?>

Modificarea privilegiilor unui fişier


Pentru a modifica privilegiile unui fişier, invocaţi chmod(), o funcţie ale cărui argumente sunt
asemănatoare celor folosite în linia de comandă UNIX:

chmod(nume_fisier, mod)

unde nume_fisier specifică numele sau calea de acces a fişierului ale cărui privilegii urmează a
fi modificate, iar argumentul mod specifică privilegiile dorite. În general se preferă exprimarea
privilegiilor sub forma unui număr scris în octal. Pentru aceasta, prefixaţi valoarea folosind
cifra 0. De exemplu, valoarea literală 010 are valoarea 8, nu valoarea 10. Ca atare, puteti
atribui unui fişier privilegiile rw-r----- specificând valoarea 0640. Pentru ca funcţia chmod() să
se execute cu succes, PHP trebuie să ruleze sub contul utilizatorului posesor al fişierului.
Funcţia returnează true în caz de reuşită, respectiv false în caz contrar. Funcţia chmod() nu
funcţionează sub Windows.

Modificarea proprietăţii asupra unui fişier


Pentru a modifica grupul posesor al unui fişier, invocaţi funcţia chgrp(), care are forma:

chgrp(nume_fisier, grup)

unde nume_fisier este numele sau calea fişierului, iar grup este numele sau identificatorul
numeric al grupului. Pentru ca funcţia să se execute cu succes, contul de utilizator sub care
rulează PHP trebuie să fie posesor al fişierului şi să fie membru al grupului specificat de
argumentul grup. Funcţia returnează true în caz de reuşită, respectiv false în caz contrar.
Funcţia chgrp() nu funcţionează sub Windows. Deşi PHP include o funcţie chown() care
modifică proprietatea asupra unui fişier, PHP trebuie să ruleze folosind contul rădăcină pentru
ca această funcţie să poată da rezultate. Deoarece acesta este un procedeu nesigur şi rareori
folosit, în general funcţia chown() nu este disponibilă.
Deschiderea unui fişier
Înainte de a putea citi sau scrie într-un fişier, trebuie să deschideţi fişierul folosind funcţia
fopen():

fopen(nume_fisier, mod)

unde nume_fisier specifică numele sau calea spre fişierul care urmează a fi deschis, iar mod
indică tipul de acces dorit. De exemplu, instrucţiunea următoare deschide fişierul text.txt
pentru citire:

$fisier = fopen("text.txt", "r");

Funcţia fopen() returnează valoarea false dacă PHP nu a reuşit să deschidă fişierul. În caz
contrar, această valoare conţine un întreg care se numeşte identificator de fişier, care se
foloseşte pentru identificarea unui fişier de către funcţiile care execută operaţii cu fişiere.
Tabelul de mai jos prezintă valorile argumentului mod care pot fi transmise funcţiei fopen().
Literele care desemnează modurile corespund cuvintelor read (citire), write (scriere) şi append
(adăugare). Modul "r" permite accesul la citire. Modurile "w" şi "a" permit accesul la scriere.
Modurile care includ semnul "+" permit ambele tipuri de acces. Unele moduri determină PHP
să încerce a crea fişierul, dacă acesta nu există.

Mod Citire Scriere Creare Trunchiere Pointer


"r" x Început
"r+" x x Început
"w" x x x Început
"w+" x x x x Început
"a" x x Sfârşit
"a+" x x x Sfârşit

Pentru ca funcţia fopen() să se execute cu succes, PHP trebuie să ruleze sub contul unui
utilizator care dispune de suficiente privilegii pentru a executa operaţiile indicate de modul
respectiv. De exemplu, pentru a putea crea un fişier, PHP trebuie să ruleze ca utilizator cu
acces de scriere la catalogul în care urmează a fi creat fişierul.
Fiecare fişier are un pointer asociat, care indică amplasarea octetului din fişier unde se va
produce următoarea operaţie (citire sau scriere). Valoarea modului funcţiei fopen() determină
valoarea iniţială a pointerului de fişier. PHP furnizează o formă alternativă a funcţiei fopen(),
care preia trei argumente:

fopen(nume_fisier, mod, cale);

Dacă argumentul cale are valoarea "1", PHP va căuta fişierul într-un director special, denumit
cale de includere. Administratorul PHP configurează identitatea căii de includere. Dacă
specificaţi argumentul cale, argumentul nume_fisier trebuie să fie alcătuit dintr-un nume de
fişier sau o cale relativă, nu dintr-o cale absolută.
În mod prestabilit, PHP 4.04pl1 raportează că este configurată calea de includere. Cu toate
acestea, este necesară stabilirea manuală a valorii variabilei include_path din fişierul php.ini;
în caz contrar, calea de includere nu va fi folosită.
Sub Windows, fişierele ASCII şi fişierele binare sunt tratate în mod diferit. Când deschideţi un
fişier binar sub Windows, specificaţi "b" ca al doilea caracter al modului; de exemplu, "rb".
Dacă nu procedaţi astfel, citirile din fişier şi alte operaţii se vor încheia prematur sau vor eşua.

Verificarea finalizării unei operaţii cu un fişier


Operaţiile cu fişiere pot eşua dintr-o varietate de motive. Deci, este important să verificaţi
dacă fiecare operaţie s-a încheiat cu succes. Iată o modalitate în care puteţi verifica:

Cod:

<?php
$fisier = fopen("text.txt", "r");
if (!$fisier) { die("Nu se poate deschide fisierul pentru citire"); }
?>

Funcţia fopen() returnează false dacă nu reuşeşte să deschidă fişierul. În acest caz, scriptul
invocă funcţia die() pentru a afişa un mesaj şi pentru a-şi încheia execuţia. Cu mult mai
compacte, dar şi posibil mai derutante, sunt formele folosite de programatorii PHP cu
experienţă:

Cod:

<?php
$fisier = fopen("text.txt", "r") or die("Nu se poate deschide fisierul
pentru citire");
?>

sau aceeaşi instrucţiune mai complexă:

Cod:

<?php
($fisier = fopen("text.txt", "r")) || die("Nu se poate deschide fisierul
pentru citire");
?>

Închiderea unui fişier


Un fişier deschis consumă resursele sistemului. Când un script a terminat de utilizat un fişier,
scriptul trebuie să închidă fişierul, eliberând aceste resurse. La sfârşitul unui script, PHP
inchide în mod automat fişierele deschise. Totuşi, în programare se recomandă să închideţi
fişierele mai rapid, ori de câte ori este posibil. Pentru a închide un fişier invocaţi funcţia
fclose():

fclose(identificator_fisier)

unde identificator_fisier este identificatorul fişierului, returnat la deschiderea acestuia. De


exemplu: <;br>

Cod:

<?php
$fisier = fopen("text.txt", "r");
if (!$fisier)
{ die("Nu se poate deschide fisierul"); }
// Aici se introduc instructiunile care folosesc fisierul deschis
@fclose($fisier);
?>

Funcţia fclose() returnează valoarea true dacă fişierul a fost închis cu succes. Testarea acestei
valori este rareori necesară, deoarece nu se mai pot face prea multe după ce s-a ratat o
încercare de a închide un fişier.

Citirea dintr-un fişier


PHP furnizează o varietate de funcţii pentru citirea fişierelor. Prima dintre acestea este fread()
care are următoarea formă:

fread(identificator_fisier, lungime)

Argumentul identificator_fisier este valoarea returnată de funcţia fopen(), iar argumentul


lungime specifică numărul maxim de octeţi care vor fi citiţi. Octeţii citiţi din fişier sunt returnaţi
sub formă de valoare de tip şir. Dacă operaţia de citire întâlneşte sfârşitul fişierului, PHP va
returna mai puţin de lungime octeţi. PHP include o funcţie conexă, denumită fgetc(), care
citeşte un octet din fişierul specificat. Exemplu:

Cod:

<?php
$fisier = fopen("text.txt", "r") OR die("Nu se poate deschide fisierul
pentru citire");
$citire = fread($fisier, 256);
echo "<br>Citeste: $citire";
fclose($fisier);
?>

Exemplul citeşte maximum 256 de octeţi din fişier. Pentru a citi un număr mai mare sau mai
mic de octeţi, modificaţi valoarea argumentului lungime al funcţiei fread(). Pentru a citi şi a
afisa întregul conţinut al fişierului, folosiţi funcţia filesize() pentru a furniza valoarea
argumentului lungime, astfel:

Cod:

<?php
$nume_fisier = "text.txt";
$fisier = fopen($nume_fisier, "r") OR die("Nu se poate deschide fisierul
pentru citire");
$citire = fread($fisier, filesize($nume_fisier));
echo "<br>Citeste: $citire";
fclose($fisier);
?>

Citirea unei linii de text


O linie de text este o serie de caractere urmate de un caracter de terminare a liniei. Funcţia
fgets() citeşte o linie dintr-un fişier. Funcţia are următoarea formă:

fgets(identificator_fisier, lungime)

Ca şi în cazul funcţiei fread(), argumentul identificator_fisier este o valoare returnată de


funcţia fopen(); cu toate acestea, argumentul lungime specifică numărul maxim de octeţi care
vor fi citiţi, minus o unitate, pentru a permite includerea caracterului de terminare a liniei.
Octeţi citiţi din fişier sunt returnaţi ca valoare de tip şir. În exemplul următor este prezentat
modul de citire şi de afişare a primei linii a unui fişier:
Cod:

<?php
$nume_fisier = "text.txt";
$fisier = fopen($nume_fisier, "r") OR die("Nu se poate deschide fisierul
pentru citire");
$citire = fgets($fisier, 256);
echo "<br>Citeste: $citire";
fclose($fisier);
?>

În exemplul de mai sus s-a presupus că linia cea mai lungă a fişierului conţine mai puţin de
256 octeţi. Pentru a permite lungimi de linie mai mari, modificaţi valoarea argumentului
lungime al funcţiei fgets().

Citirea linie cu linie a unui întreg fişier


Funcţia feof() este folosită pentru a determina momentul când fişierul a fost citit în totalitate.
Funcţia returnează o valoare care arată dacă s-a ajuns sau nu la sfârşitul fişierului. Funcţia are
următoarea formă:

feof(identificator_fisier)

Argumentul identificator_fisier este valoarea returnată de funcţia fopen(). Funcţia feof()


returnează true dacă fişierul specificat este la sfârşit; în caz contrar returnează false. Iată cum
se poate folosi funcţia feof() pentru a controla procesul de citire a unui întreg fişier, linie cu
linie:

Cod:

<?php
$nume_fisier = "text.txt";
$fisier = fopen($nume_fisier, "r") OR die("Nu se poate deschide fisierul
pentru citire");
$citire = fread($fisier, filesize($nume_fisier));
while (!feof($fisier))
{
echo "<br>Citeste: $citire";
$citire = fread($fisier, filesize($nume_fisier));
}
fclose($fisier);
?>

Instrucţiunea while asigură faptul că funcţia fgets() este apelată în mod repetat, până la
citirea tuturor liniilor.
O modalitate mai simplă de a citi linie cu linie un întreg fişier constă în a folosi funcţia file().
Această funcţie returnează un tablou în care fiecare element conţine o linie a fişierului text
specificat. Iată un exemplu:

Cod:

<?php
$tablou = file("text.txt");
foreach ($tablou as $citire)
{
echo "<br Citeste: $citire";
}
?>

Această metodă nu este adecvată pentru fişiere de foarte mari dimensiuni, deoarece în tablou
este încărcat întregul conţinut al fişierului, ceea ce poate necesita o cantitate de memorie
superioară celei disponibile.

Afişarea conţinutului unui fişier


PHP furnizează două funcţii care facilitează afişarea conţinutului unui fişier. Una dintre funcţii,
fpassthru(), necesită un argument care specifică identificatorul fişierului care urmează să fie
afişat:

$fisier = fopen("text.txt", "r");


fpassthru($fisier);

După ce a afişat fişierul, funcţia îl închide automat. Cealaltă funcţie, readfile(), necesită numai
numele sau calea fişierului:

readfile("text.txt");

Navigarea printr-un fişier


Aşa cum am mai spus, fiecare fişier are un pointer asociat care indică poziţia octetului unde se
va produce următoarea operaţie. Puteţi folosi funcţia rewind() pentru a readuce pointerul la
începutul fişierului. Funcţia are următoarea formă:

rewind(identificator_fisier)

unde identificator_fisier este identificatorul de fişier returnat de funcţia fopen(). Nu se poate


readuce pointerul unui fişier la începutul propriu-zis al unui fişier dacă fişierul a fost deschis
pentru un acces de tip ataşare, adică într-unul din modurile "a" sau "a+". Dacă se produce o
eroare, funcţia rewind() returnează zero. Deşi funcţia rewind() este utilă în caz de nevoie,
necesitatea de a readuce un pointer de fişier la începutul fişierului nu este chiar atât de
frecventă. Funcţia fseek() furnizează o mai mare flexibilitate, permiţându-vă să poziţionaţi
pointerul de fişier astfel încât să puteţi citi sau scrie în orice punct al fişierului. Funcţia are
două forme, cea mai simplă fiind următoarea:

fseek(identificator_fisier, offset)

unde identificator_fisier este identificatorul de fişier returnat de funcţia fopen(), iar offset este
poziţia dorită a pointerului de fişier, specificată în octeţi, în raport cu începutul fişierului. În caz
de reuşită, funcţia fseek() returnează 0; în caz contrar, returnează -1. O formă alternativă a
funcţiei asigură un grad superior de flexibilitate:

fseek(identificator_fisier, offset, baza)

unde baza ia una dintre următoarele valori:

- SEEK_SET, care stabileşte poziţia pointerului de fişier în raport cu începutul fişierului


- SEEK_CUR, care stabileşte poziţia pointerului de fişier în raport cu valoarea curentă a
pointerului
- SEEK_END, care stabileşte poziţia pointerului de fişier relativ la sfârşitul fişierului.

Valoarea argumentului offset poate fi pozitivă, negativă sau zero. De exemplu, pentru a
poziţiona pointerul cu 10 octeţi înainte de sfârşitul fişierului, emiteţi următorul apel de funcţie:

fseek($fisier, -10, SEEK_END)


unde $fisier este identificatorul fişierului al cărui pointer doriţi să-l repoziţionaţi.
Pentru a obţine valoarea curentă a pointerului de fişier, invocaţi functia ftell(), care are
următoarea formă:

ftell(identificator_fisier)

Funcţia returnează valoarea curentă a identificatorului de fişier, respectiv valoarea zero dacă
funcţia eşuează.

Scrierea într-un fişier


Spre deosebire de varietatea de funcţii furnizate pentru citirea fişierelor, PHP oferă o singură
funcţie pentru scrierea în fişiere, şi anume fwrite(), care are următoarea formă:

fwrite(identificator_fisier, data)

unde identificator_fisier este identificatorul de fişier returnat de funcţia fopen(), iar data este o
valoare şir care determină datele ce urmează a fi scrise. Dacă execuţia funcţiei reuşeşte,
returnează numărul octeţilor scrişi; în caz contrar, returnează valoarea -1. Iată un exemplu de
scriere a datelor într-un fişier:

Cod:

<?php
$nume_fisier = "text.txt";
$fisier = fopen($nume_fisier, "a") OR die("Nu se poate deschide fisierul
pentru citire");
$scriere = fwrite($fisier, "Un rand de text atasat la fisier.\n");
echo "<br>Rezultatul scrierii: $scriere";
fclose($fisier);
?>

Scriptul scrie în fişier o linie de text. Deoarece fişierul a fost deschis folosind modul "a", datele
sunt ataşate la fişier; cu alte cuvinte, datele sunt scrise după toate datele existente în fişier.
Dacă lucraţi cu fişiere text, în general trebuie să includeţi un caracter de terminare a liniei la
sfârşitul fiecărei linii scrise în fişier (în exemplul de mai sus am pus \n la sfârşitul liniei).
Scriptul din exemplul de mai sus scrie în fişier o singură linie de text. Totuşi, puteţi scrie mai
multe linii, dacă doriţi. Dacă apelaţi funcţia fwrite() din interiorul unei bucle, aveţi posibilitatea
să scrieţi mai multe linii. După ce aţi scris toate liniile de care aveţi nevoie, închideţi fişierul
prin apelarea funcţiei fclose(). PHP mai furnizează şi o formă alternativă a funcţiei fwrite():

fwrite(identificator_fisier, data, lungime)

Această formă include un al treilea argument, şi anume lungime, care vă permite să specificaţi
numărul maxim de octeţi care vor fi scrisi. Argumentul lungime trebuie utilizat atunci când se
scrie în fişiere binare sub Windows. De asemenea, Windows preferă secvenţa de terminare a
liniei "\r\n". PHP dispune de o altă funcţie pentru scrierea fişierelor, în speţă fputs(). Totuşi, în
afară de nume, fputs() este una şi aceeaşi funcţie cu fwrite() (reprezintă una şi aceeaşi funcţie
dar cu nume diferite).

Obţinerea accesului exclusiv la un fişier


Uneori, accesul simultan la un fişier poate avea ca rezultat deteriorarea fişierului. Să ne
imaginăm că avem un contor de pagini asociat unei pagini web. Dacă 2 sau mai mulţi vizitatori
intră simultan pe pagină scriptul de contorizare va deschide fişierul pentru scriere în acelaşi
timp pentru toţi utilizatorii şi ce credeţi că va scrie în el? În loc să incrementeze contorul cu o
unitate pentru fiecare vizitator este posibil sa dea eroare şi informaţiile din fişier să se piardă.
Pentru a evita astfel de probleme, este necesar ca fiecare proces să obţină acces exclusiv la
fişierul care conţine contorul din pagină. Astfel, accesul la fişier este succesiv: fişierul va fi
folosit mai întâi de un proces, şi apoi de celălalt. Atâta vreme cât procesele sunt împiedicate
să obţină simultan accesul la fişier, contorul nu va indica valori eronate. Funcţia flock()
permite unui proces să obţină un acces exclusiv la un fişier, acordând procesului o blocare a
fişierului. Funcţia are forma:

flock(identificator_fisier, operatie)

unde identificator_fisier este identificatorul de fişier returnat de funcţia fopen(). Argumentul


operatie este o constantă sau o expresie care specifică operaţia dorită, după cum urmează:

Operaţie Descriere
Obţine o blocare partajată a fişierului specificat. Mai multe procese
pot deţine o blocare partajată; pentru un fişier însă, nici un proces
LOCK_SH nu poate obţine o blocare partajată în timp ce un alt proces deţine
o blocare exclusivă. Procesul va aştepta până când are posibilitatea
de a obţine blocarea cerută.
Obţine o blocare exclusivă pentru fişierul specificat. Un singur
LOCK_EX proces poate deţine o blocare exclusivă a unui fişier. Procesul va
aştepta până când are posibilitatea de a obţine blocarea cerută.
Încearcă să obţină o blocare partajată a fişierului specificat; totuşi,
LOCK_SH + LOCK_NB nu aşteaptă obţinerea blocării, dacă aceasta nu este disponibilă
imediat.
Încearcă să obţină o blocare exclusivă pentru fişierul specificat;
LOCK_EN + LOCK_NB totuşi, nu aşteapta obţinerea blocării, dacă aceasta nu este
disponibilă imediat.
LOCK_UN Eliberează blocarea fişierului specificat.

Funcţia flock() returnează true în caz de reuşită, respectiv false când blocarea solicitată nu
poate fi obţinută (LOCK_SH şi LOCK_EX) sau eliberată (LOCK_UN). Blocarea este o activitate
care se desfăşoară în comun. Procesele nu au niciodată accesul interzis la fişiere, ci numai la
blocări. Ca atare, un proces care nu încearcă să blocheze un fişier poate obţine acces la fişier
chiar dacă un alt proces a cerut şi a obţinut o blocare exclusivă a fişierului. Unele servere Web,
inclusiv IIS de la Microsoft, rulează un singur proces multifir. În asemenea situaţii, funcţia
flock() nu va reuşi să furnizeze acces exclusiv la fişiere.

Copierea unui fişier


PHP furnizează o funcţie care facilitează copierea fişierelor, şi anume funcţia copy(). Funcţia
copy() are următoarea formă:

copy(sursa, destinatie)

unde sursa este numele sau calea fişierului care urmează a fi copiat, iar destinatie este
numele sau calea unde se va copia. Funcţia returnează true dacă operaţia de copiere reuşeste;
în caz contrar, returnează false. Exemplu:

Cod:

<?php
$copiaza = copy("text.txt", "text.bak");
if (!$copiaza) { die("<br>A fost produsa o eroare la copierea fisierulu
i"); }
?>

Exemplul crează o copie de siguranţă a fişierului "text.txt", cu numele "text.bak". PHP trebuie
să aibă acces de scriere la directorul în care se va afla copia; în caz contrar, PHP nu va putea
crea copia. Funcţia copy() va suprascrie fişierul destinaţie, dacă acesta există.

Modificarea numelui unui fişier


PHP furnizează o funcţie care vă permite să modificati numele unui fişier, şi anume rename(),
funcţie care are următoarea formă:

rename(nume_vechi, nume_nou)

unde nume_vechi este numele sau calea originală a fişierului, iar nume_nou este numele sau
calea dorită. Funcţia returnează true dacă operaţia de modificare a numelui a reuşit; în caz
contrar, returnează false. Exemplu:

Cod:

<?php
$redenumeste = rename("text.bak", "text.txt");
if (!$redenumeste) { die("<br>A fost produsa o eroare la redenumirea fi
sierului"); }
?>

Exemplul modifică numele fişierului "text.bak", atribuindu-i numele "text.txt". La fel ca la


funcţia copy(), PHP trebuie să aibă acces de scriere la directorul în care se va afla fişierul cu
numele modificat; în caz contrar, PHP nu va putea modifica numele fişierului. Ca şi în cazul
comenzii UNIX mv, funcţia rename() va suprascrie fişierul destinaţie, dacă acesta există.

Ştergerea unui fişier


PHP furnizează o funcţie care vă permite să ştergeţi un fişier, şi anume unlink(). Funcţia are
forma:

unlink(nume_fisier)

unde nume_fisier este numele sau calea fişierului care urmează a fi şters. Funcţia returnează
true dacă operaţia de ştergere a avut succes, respectiv false în caz contrar. Exemplu:

Cod:

<?php
$sterge = unlink("text.txt");
if (!$sterge) { die("<br>A fost produsa o eroare la stergerea fisierulu
i"); }
?>

Reţineţi că PHP trebuie să aibă acces de scriere la directorul în care se află fişierul; în caz
contrar, PHP nu va putea şterge fişierul. În conformitate cu manualul PHP, functia unlink() "s-
ar putea să nu funcţioneze" în sistemele Windows.

Încărcarea unui fişier în server


Pe anumite pagini cu formulare HTML se poate încărca un fişier pe server. Pentru a crea un
astfel de formular de încărcare, specificaţi ENCTYPE="multipart/form-data" în eticheta FORM şi
includeţi un control de introducere a datelor cu atributul TYPE="FILE". Iată un exemplu:

Cod:

<HTML>
<HEAD>
<TITLE>incarcare fisier</TITLE>
</HEAD>
<BODY>
<FORM METHOD="POST" ACTION="incarca.php" ENCTYPE="multipart/form-data">
Incarca un fisier: <INPUT NAME="fisier_utilizator" TYPE="FILE">
<BR><BR>
<INPUT TYPE="SUBMIT" VALUE="Trimite">
</FORM>
</BODY>
</HTML>

Când utilizatorul apasă pe butonul de trimitere, browserul încarcă fişierul în server. Scriptul
vostru PHP poate obţine accesul la calea fişierului încărcat astfel:

$HTTP_POST_FILES["fisier_utilizator"]["tmp_name"]

unde fisier_utilizator este valoarea atributului NAME asociat controlului INPUT folosit pentru
încărcarea fişierului. La terminarea execuţiei scriptului, PHP şterge în mod automat fişierul
încărcat. Dacă doriţi să salvaţi fişierul, puteţi invoca funcţia move_uploaded_file(). De
exemplu:

Cod:

<?php
$rezultat = move_uploaded_file ($HTTP_POST_FILES["fisier_utilizator"]
["tmp_name"],
"/home/tutoriale/upload/nume_fisier.ext");
$rezultat = $rezultat ? "true" : "false";
echo "<br>move_uploaded_file(): $rezultat";
?>

Funcţia move_uploaded_file() vă impune să specificaţi calea fişierului încărcat şi calea unde


doriţi să fie mutat fişierul. Funcţia returnează true dacă operaţia reuşeşte, respectiv false în
caz contrar.

Momentan mă opresc aici cu prima parte a acestui tutorial, sper că aţi aflat lucruri interesante
până acum.

Descrierea funcţiilor de prelucrare a fişierelor

În articolul precedent am discutat despre sistemul de fişiere si am generalizat despre fisiere si


directoare. În continuare o să încerc sa detaliez lucrul cu fişierele şi să discut ceva mai mult
despre cele mai folosite funcţii care se ocupă de fişiere. Limbajul PHP oferă un set de funcţii
pentru a facilita accesul la conţinutul fişierelor. Sintaxa majorităţii dintre acestea este similară
funcţiilor de manipulare a fişierelor prezente în limbajul C/C ++. Datorită faptului că limbajul
PHP este independent de platformă, printre numele funcţiilor se regăsesc şi nume cunoscute
pe platformele de operare *nix şi Microsoft Windows.

Funcţia fopen
Această funcţie se foloşte pentru deschiderea unui fişier în vederea citirii sau scrierii datelor
din/în acesta. Funcţia are patru parametri, dintre care ultimii doi sunt opţionali. Primul
parametru îl reprezintă numele fişierului care urmează a fi deschis. Fişierul poate fi şi unul
aflat la distanţă. Un fişier este recunoscut de PHP a fi la distanţă dacă este accesibil printr-unul
dintre protocoalele HTTP (Hyper Text Transfer Protocol), HTTPS (Secure HTTP), FTP (File
Transfer Protocol) sau FTPS (Secure FTP). Fişierele standard de intrare şi ieşire pot fi
accesate folosind următorii identificatori:

- php://stdin - fişierul standard de intrare pentru procesul curent creat de PHP;


- php://stdout - fişierul standard de ieşire pentru procesul curent creat de PHP;
- php://stderr - fişierul standard de erori pentru procesul curent creat de PHP;
- php://input - cu ajutorul acestui identificator se poate accesa conţinutul datelor transmise
paginii prin intermediul metodei POST;
- php://output - cu ajutorul acestui identificator se pot scrie date direct în pagina web.

Fişierele php://input şi php://stdin pot fi deschise numai în scopul citirii, în timp ce fişierele
php://output, php://stdout şi php://stderr pot fi deschise numai pentru scriere. Scrierea
datelor în fişierul php://output are acelaşi efect ca şi utilizarea funcţiilor print şi echo.
Cel de-al doilea parametru este de tipul şir de caractere şi reprezintă modul de deschidere a
fişierului care poate fi:

-"r" - deschide fişierul pentru citire şi poziţionează pointer-ul la începutul acestuia;


-"r+" - deschide fişierul pentru citire şi scriere şi poziţionează pointer-ul la începutul acestuia;
-"w" - deschide fişierul pentru scriere, poziţioneaza pointer-ul la începutul acestuia şi sterge
conţinutul; dacă fişierul nu există, acesta este creat.
-"w+ " - deschide fişierul pentru citire şi scriere, poziţionează pointer-ul la începutul acestuia şi
sterge conţinutul; dacă fişierul nu există, acesta este creat.
-"a" - deschide fişierul pentru scriere şi poziţionează pointer-ul la sfârşitul acestuia, însă fără a
şterge conţinutul; dacă fişierul nu există, acesta este creat.
- "a+" - deschide fişierul pentru citire şi scriere şi poziţionează pointer-ul la sfârşitul acestuia,
însă fără a şterge conţinutul; dacă fişierul nu există, acesta este creat.

La sfărşitul şirului care reprezintă modul de deschidere a fişierului mai poate apărea şi
caracterul "b". Acesta este util atunci când se doreşte deschiderea fişierului în mod binar şi nu
în mod text. Pe sistemele de operare *nix nu are nici un efect, în schimb pentru portabilitate
este indicată folosirea lui. Cel de-al treilea parametru este de tip întreg şi poate avea valorile 0
sau 1 şi indică funcţiei faptul că se poate folosi (valoarea 1) sau nu (valoarea 0) lista de
directoare, cu care interpretorul a fost configurat, pentru a găsi fişierul care se doreşte a fi
deschis, în cazul în care numele acestuia nu include şi o cale absolută. Cel de-al patrulea
parametru este de tipul resource şi este folosit în scopul optimizării unor operaţii. Funcţia
fopen returnează un număr întreg care reprezintă identificatorul de acces la fişierul care
tocmai a fost deschis. Acest identificator va fi transmis tuturor funcţiilor pe care le veţi utiliza
pentru a accesa date din fişier. În cazul în care deschiderea fişierului nu poate avea loc din
diferite motive, atunci funcţia returnează valoarea logică FALSE. De exemplu, pentru a
deschide fişierul cu numele "test.txt" pentru a citi date, vom folosi următoarea linie de cod
sursa:

$f = fopen("test.txt", "r");

Dacă dorim să scriem date în fişier, atunci îl putem deschide folosind următorul cod:

$f = fopen("test.txt", "w");
Funcţia tmpfile
Această funcţie realizează crearea şi deschiderea unui fişier temporar pentru scriere şi citire.
Funcţia tmpfile nu are parametri şi returnează un număr întreg care reprezintă identificatorul
de acces al fişierului temporar. Fişierul temporar va fi şters în mod automat în momentul în
care este închis sau când script-ul îşi încheie execuţia. Apelul acestei funcţii este identic cu cel
al funcţiei fopen cu parametrii: un nume de fişier temporar (de obicei generat aleator) şi
"w+b" ca mod de deschidere a fişierului.

Functia fclose
Această funcţie realizează închiderea unui fişier care a fost deschis cu ajutorul funcţiilor fopen
sau tmpfile. Funcţia fclose are un singur parametru de tip întreg, care reprezintă identificatorul
de acces la fişierul care se doreşte a fi închis. Funcţia returnează valoarea logică TRUE dacă
închiderea fişierului a reuşit şi valoarea logica FALSE în caz contrar. Un exemplu de apel al
acestei funcţii este

fclose($fd)

unde fd reprezintă identificatorul de acces la fişierul care se doreşte a fi închis.

Funcţia feof
Această funcţie verifică dacă s-a ajuns la sfârşitul fişierului sau nu. Funcţia feof are un singur
parametru de tip întreg, care reprezintă identificatorul de acces la fişierul care se doreşte a fi
închis. Funcţia returnează valoarea logică TRUE dacă am ajuns la sfârşitul fişierului şi valoarea
logică FALSE în caz contrar.

Funcţiile fscanf
Această funcţie citeşte date dintr-un fişier text şi are doi parametri obligatorii. Primul
parametru este de tip întreg şi reprezintă identificatorul de acces la fişierul din care se face
citirea, iar cel de-al doilea parametru este de tipul şir de caractere şi indică funcţiei formatul
intrării. Formatul acestuia din urmă este similar formatului folosit pentru funcţia fscanf
prezentă în limbajul C/C++. Ceilalţi parametri reprezintă referinţele la variabilele care vor
conţine rezultatul citirii. Funcţia returnează un vector cu valorile citite, deci prezenţa
variabilelor nu mai este obligatorie ca în cazul limbajului C/C++. De exemplu, dacă din fişierul
"c:\test.txt" dorim să citim un număr şi un şir de caractere separate printr-un spaţiu, atunci
vom folosi următorul cod:

Cod:

<?php
$f = fopen("c:\\test.txt","r");
$rez = fscanf($f, "%d %s \n");
list($nr, $sir) = $rez;
fclose($f);
echo "Am citit numarul: ".$nr."<BR>";
echo "si sirul: ".$sir;
?>

Funcţia fread
Această funcţie se foloseşte pentru citirea datelor din fişiere binare. Pentru compatibilitate cu
toate sistemele de operare se recomandă ca la deschiderea fişierului, pentru citire, să se
adauge caracterul "b" la parametrul care reprezintă modul de deschidere a fişierului. Funcţia
fread are doi parametri obligatorii. Primul parametru este de tip întreg şi reprezintă
identificatorul de acces al fişierului din care se doreşte să se citească date, iar al doilea
parametru, tot de tip întreg, reprezintă numarul de octeţi care se doresc a fi citiţi. Rezultatul
returnat de această funcţie este de tip şir de caractere care este format din octeţii care s-au
citit din fişierul de intrare. În cazul în care în fişierul din care se citesc date nu mai este
disponibil numărul de octeţi specificat în cadrul celui de-al doilea parametru, atunci funcţia
returnează toţi octeţii disponibili de la poziţia curentă din fişier şi până la sfârşitul acestuia. În
continuare este un exemplu de folosire a acestei funcţii. Codul este compatibil cu toate
sistemele de operare pe care limbajul PHP poate fi instalat.

Cod:

<?php
$fis = "test.txt";
$fd = fopen($fis, "rb");
$continut = fread($fd, filesize($fis));
fclose($fd);
echo "Continutul fisierului este: ";
echo $continut;
?>

Funcţia fgetc
Această funcţie citeşte următorul caracter disponibil din fişierul de intrare. Funcţia are un
singur parametru de tip întreg care reprezintă identificatorul de acces la fişierul din care se
doreşte să se facă citirea. Funcţia fgetc returnează un şir de caractere, în cazul în care nu s-a
ajuns la sfârşitul fişierului, format dintr-un singur caracter, şi anume, cel citit din fişier. În
cazul în care ne aflăm la sfârşitul fişierului, funcţia fgetc returnează valoarea logică FALSE.

Cod:

<?php
$fisier = "test.txt";
$fd = fopen($fisier,"r");
$car = fgetc($fd);
fclose($fd);
echo "Primul caracter din fisier este: ";
echo $car;
?>

Funcţia fgets
Această funcţie se foloseşte pentru a citi o linie dintr-un fişier de tip text. Sintaxa acestei
funcţii este similară cu cea a funcţiei fread, cu menţiunea că cel de-al doilea parametru este
opţional. Funcţia fgets returnează un şir de caractere care conţine datele citite. Citirea datelor
din fişier se încheie în momentul în care s-a citit un număr de caractere egal cu valoarea celui
de-al doilea parametru (în cazul în care acesta este prezent), în momentul întâlnirii unui sfârşit
de linie sau în momentul în care s-a ajuns la sfârşitul fişierului. În cazul în care ne aflăm la
sfârşitul fişierului, funcţia fgets returnează valoarea logică FALSE.

Cod:

<?php
$fisier = "test.txt";
$fd= fopen($fisier,"r");
$linie = fgets($fd);
fclose($fd) ;
echo "Prima linie din fisier este: ";
echo $linie;
?>

În acest exemplu am omis cel de-al doilea parametru.

Funcţia fgetss
Această funcţie citeşte o linie dintr-un fişier HTML. Spre deosebire de funcţia fgets, funcţia
fgetss are trei parametri. Primii doi parametri sunt identici cu cei folosiţi în cazul funcţiei fgets.
Cel de-al treilea parametru este opţional, este de tip şir de caraetere şi reprezintă o listă de
marcaje HTML sau PHP pe care funcţia nu trebuie să le elimine în momentul citirii. Această
funcţie returnează un şir de caractere care reprezintă datele din fişierul HTML care au fost
citite. Citirea datelor se încheie în momentul în care s-au citit atâtea caractere câte indică cel
de-al doilea parametru sau în momentul în care am ajuns la sfârşitul fişierului.

Cod:

<?php
$fis = "test.html";
$fd = fopen($fis, "r");
echo "Continutul fisierului HTML este: ";
while (!$linie = fgetss($fd, filesize($fis)))
{
echo $linie."<br>";
}
fclose($fd);
?>

În cazul în care fişierul test.html conţine multe linii cu marcaje html, prin eliminarea lor, şirul
returnat devine vid, iar pe ecran se vor afişa multe rânduri goale.

Funcţia fgetcsv
Această funcţie citeşte date dintr-un fisier CSV (Comma Separated Values - valori separate
prin virgula). Un fişier de tip CSV are formatul text şi conţine mai multe înregistrări. Este o
reprezentare textuala a unui fişier de tip tabelar. Pe fiecare linie a unui astfel de fişier se află
mai multe valori ale unor câmpuri care sunt delimitate printr-un separator. De obicei acest
separator este caracterul " , " (virgula), de unde şi numele acestui tip de fişier. Funcţia fgetcsv
are trei parametri dintre care primii doi sunt obligatorii. Primul parametru este de tip întreg şi
reprezintă identificatorul de acces la fişierul de intrare, al doilea parametru este de tip întreg şi
reprezintă numărul maxim de octeţi care se vor procesa la o citire şi trebuie să aibă o valoare
mai mare decât lungimea celei rnai mari linii din fişierul CSV, iar al treilea parametru este de
tip şir de caractere care trebuie să aibă lungimea 1 şi reprezintă separatorul care se va folosi
la procesarea datelor. Funcţia returnează, în cazul în care nu ne aflăm la sfârşitul fişierului de
intrare, un tablou de şiruri de caractere care reprezintă valorile citite. În cazul în care ne aflăm
la sfârşitul fişierului, funcţia fgetcsv returnează valoarea logică FALSE. În continuare este
prezentat un exemplu de utilizare a acestei funcţii pentru un fişier CSV în care fiecare linie nu
are o lungime mai mare de 1000 de caractere:

Cod:
<?php
$lin = 1;
$fp = fopen("test.csv", "r");
while ($date = fgetcsv($fp, 1000, ","))
{
$num = count($date);
echo "<p>$num campuri pe linia $lin: <br>";
$lin++;
for ($c=0; $c<$num; $c++)
{
echo $date[$c]."<br>";
}
}
fclose($fp);
?>

Funcţia file_get_contents
Această funcţie citeşte conţinutul unui fişier de tip text şi are doi parametri. Primul parametru
este de tip şir de caractere şi reprezintă numele fişierului al cărui conţinut se va citi, iar cel de-
al doilea parametru este opţional şi indică dacă pentru găsirea fişierului se va folosi sau nu
lista de directoare predefinită. Funcţia returnează un şir de caractere care conţine toate datele
din fişierul primit ca parametru în cazul în care citirea s-a efectuat cu succes şi valoarea logică
FALSE în caz contrar.

Funcţia file
Această funcţie citeşte conţinutul unui fişier de tip text şi are aceeaşi sintaxă cu funcţia
file_get_contens, dar rezultatul returnat de aceasta este un tablou de şiruri de caractere,
fiecare dintre acestea constând într-o linie din fişierul primit ca parametru.

Funcţia filetype
Această funcţie returnează un şir de caractere care reprezintă tipul unui fişier. Funcţia filetype
are un singur parametru de tip şir de caractere, mai exact numele fişierului pentru care dorim
să determinăm tipul. Valorile posibile pentru tipul unui fişier sunt "pipe", "fifo", "char", "dir",
"block", "link", "file", şi "unknown".

Funcţia filesize
Această funcţie se foloşeste pentru a afla dimensiunea, exprimată în octeţi, a unui fişier.
Funcţia filesize are un singur parametru de tip şir de caractere, mai exact numele fişierului
pentru care dorim să determinăm dimensiunea.

Funcţia fwrite
Această funcţie se foloseşte pentru a scrie date într-un fişier text sau binar. Pentru
compatibilitate cu toate sistemele de operare, se recomandă ca la deschiderea fişierului,
pentru scriere, să se adauge caracterul "b" la parametrul care reprezintă modul de deschidere
a fişierului. Funcţia fwrite are trei parametri. Primul parametru este de tip întreg şi reprezintă
identificatorul de acces la fişierul în care se doreşte să se scrie date, cel de-al doilea parametru
este de tip şir de caractere şi reprezintă datele care se vor scrie în fişier, iar cel de-al treilea
parametru este de tip întreg, opţional şi reprezintă numărul de octeţi din şirul de caractere
care se vor scrie în fişier. Funcţia returnează un număr întreg care reprezintă numărul de
octeţi pe care a reuşit să-i scrie în fişier, în cazul în care nu au apărut erori şi valoarea logică
FALSE în caz contrar. În continuare este un exemplu de utilizare a acestei funcţii:
Cod:

<?php
$fis = "test.txt";
$sir = "Scriere in fisier";
$fp = fopen($fis, "a");
fwrite($fp, $sir);
echo "Am scris ($sir) in fisierul ($fis).";
fclose($fp);
?>

Funcţia fputs
Această funcţie este o redenumire a funcţiei fwrite, pentru compatibilitate cu limbajul C/C++,
şi are acelaşi comportament. În limbajul C/C++ functia fwrite este folosită pentru a scrie un
şir de octeţi într-un fişier, spre deosebire de PHP, unde şirul de octeţi este reprezentat chiar de
şirul de caractere.

Funcţia fflush
Această funcţie forţează salvarea pe disc a conţinutului zonelor tampon folosite pentru scrierea
într-un fişier. Funcţia fflush primeşte un singur parametru de tip întreg, care reprezintă
identificatorul de acces al fişierului pentru care se doreşte golirea zonelor tampon. Funcţia
returnează valoarea logică FALSE în caz de eroare şi valoarea logică TRUE în caz contrar .

Funcţia flock
Această funcţie se foloşeste pentru a bloca sau debloca accesul la un fişier. Necesitatea
utilizării funcţiei flock apare în momentul în care mai multe procese doresc să acceseze acelaşi
fişier şi nu se vrea afectarea integrităţii acestuia. Funcţia are trei parametri. Primul parametru
reprezintă identificatorul de acces la conţinutul fişierului, cel de-al doilea parametru reprezintă
tipul operaţiei de blocare a fişierului, iar al treilea parametru este de tip referinţă la întreg şi va
primi valorea logică TRUE în cazul în care funcţia flock va opri execuţia script-ului până în
momentul în care va reuşi să blocheze fişierul. Pentru cel de-al doilea parametru, în limbajul
PHP sunt disponibile constantele:

- LOCK_SH - se foloseşte în cazul în care fişierul se blocheaza în mod partajat pentru citirea
datelor;
- LOCK_EX - se foloseşte în cazul în care fişierul se blocheaza în mod exclusiv pentru scrierea
datelor;
- LOCK_UN - se foloseşte în cazul în care se doreşte deblocarea unui fişier;
- LOCK_NB - se foloseşte împreună cu una dintre primele trei constante dacă nu se doreşte ca
funcţia flock să întrerupă execuţia script-ului până în momentul în care va reuşi să efectueze
operaţia cerută; această constantă se adună la una dintre primele trei.

Funcţia returnează valoarea logică TRUE în caz de succes şi valoarea logică FALSE în cazul
unui eşec.

Funcţia fseek
Această funcţie se foloseşte pentru modificarea poziţiei de citire sau scriere în interiorul unui
fişier. Funcţia fseek are trei parametri. Primul parametru este de tip întreg şi reprezintă
identificatorul de acces la un fişier, al doilea parametru este de tip întreg şi indică numărul de
poziţii cu care se va face modificarea, iar al treilea parametru, tot de tip întreg, este opţional şi
specifică modul în care se va face modificarea. Se observă că cel de-al doilea parametru poate
avea şi valori negative. Modificarea poziţiei de citire sau scriere se poate face în trei moduri
pentru care sunt definite constante:
- relativ la începutul fişierului - constanta SEEK_SET;
- relativ la pozitia curentă - constanta SEEK_CUR;
- relativ la sfârşitul fişierului - constanta SEEK_SET.

În cazul în care cel de-al treilea parametru lipseste se va folosi ca valoare pentru acesta
constanta SEEK_SET. Funcţia returnează o valoare întreagă egală cu 0, în cazul în care nu au
aparut erori, şi egală cu -1 în caz contrar. Această funcţie nu poate fi folosită pentru fişiere
care sunt accesate folosind unul dintre protocoalele HTTP sau FTP.

Funcţia rewind
Această funcţie schimbă poziţia de citire sau scriere într-un fişier la începutul acestuia şi are
un singur parametru care specifică identificatorul de acces la fişier. Rezultatul returnat de
funcţia rewind este acelaşi cu cel returnat de funcţia fseek. Apelul acestei funcţii este
echivalent cu apelul funcţiei fseek cu primul parametru având ca valoare identificatorul de
acces al fişierului, al doilea parametru având valoarea 0 şi cel de-al treilea parametru având
valoarea SEEK_SET chiar dacă lipseşte.

Funcţia ftell
Această funcţie se foloseşte pentru a afla poziţia curentă de la care se va face următoarea
citire sau scriere într-un fişier, relativ la începutul acestuia. Funcţia ftell primeşte ca parametru
identificatorul de acces al fişierului pentru care se aplică şi returnează o valoare întreagă
reprezentând poziţia din fişier, în caz de succes sau valoarea logică FALSE în caz de eşec.

Funcţia ftruncate
Această funcţie realizează redimensionarea fişierului cu o valoare primită ca parametru.
Funcţia ftruncate are doi parametri. Primul dintre aceştia este identificatorul de acces al
fişierului care se redimensionează, iar al doilea parametru este de tip întreg şi reprezintă noua
dimensiune a fişierului. Trebuie ţinut cont de faptul ca în cazul în care cel deal doilea
parametru are o valoare mai mare decât dimensiunea curentă a fişierului, va fi alocat, pe disc,
spaţiu suplimentar care nu va fi iniţializat. În cazul în care cel de-al doilea parametru are o
valoare mai mica decât dimensiunea curentă a fişierului, atunci toate datele din fişier, care se
află după poziţia indicată de noua valoare, se vor pierde.

Funcţia delete
Această funcţie este mai degrabă o redenumire a funcţiei unlink, care se foloseşte pentru a
şterge un fişier de pe disc. Funcţia delete a fost inclusă în pachetul de funcţii oferit de limbajul
PHP pentru cei care au programat în limbaje precum Pascal şi nu au avut la dispoziţie funcţia
unlink. Funcţia unlink primeşte ca parametru un nume de fişier şi returnează valoarea logică
TRUE în cazul în care ştergerea s-a efectuat cu succes. În cazul în care ştergerea nu s-a putut
efectua, funcţia returneză valoarea logică FALSE.

În urătorul articol o să încerc să detaliez funcţiile php care se ocupă de manipularea


directoarelor.

Funcţii care faciliteaza lucrul cu directoare

În articolele anterioare am discutat despre structura de fisiere şi felul cum sunt ele salvate pe
server şi am detaliat funcţiile php care se ocupă de fişiere. În acest articol se află descrierea
celor mai importante funcţii şi clase oferite de limbajul PHP pentru manipularea directoarelor.
Funcţia getcwd
Această funcţie returnează un şir de caractere care reprezintă directorul curent. Funcţia
getcwd nu are nici un parametru. În continuare este un exemplu de utilizare al acestei funcţii:

Cod:

<?php
$cdir = getcwd();
echo "Directorul curent este: ".$cdir;
?>

Funcţia chdir
Această funcţie se foloseşte pentru a schimba directorul curent şi primeşte ca parametru un şir
de caractere care reprezintă noul director. Funcţia chdir returnează valoarea logică TRUE
atunci când schimbarea directorului curent s-a efectuat cu succes şi valoarea logică FALSE în
caz contrar.

Funcţia chroot
Această funcţie se foloseşte pentru a schimba directorul rădăcină pentru procesul curent şi
primeşte ca parametru un şir de caractere care reprezintă noul director rădăcină. Funcţia
chroot returnează valoarea logică TRUE atunci când schimbarea directorului rădăcină s-a
efectuat cu succes şi valoarea logică FALSE în caz contrar. Această funcţie nu este
implementată pe platformele de operare Microsoft Windows şi nu este recomandată folosirea
ei decat în cazul în care interpretorul PHP este utilizat folosind metoda de execuţie CGI.

Functia opendir
Aceasta functie se foloseste pentru a deschide un director in scopul citirii continutului sau.
Functia opendir are un singur parametru de tip sir de caractere care reprezinta numele
directoruiui al carui continut se va prelucra. Aceasta functie returneaza un identificator de
acces la continutul directorului si este de tipul resursa. In cazul in care nu se reuseste
deshiderea directorului,
functia returneaza valoarea logica FALSE.

Funcţia closedir
Această funcţie se foloseşte pentru a închide un director care a fost deschis pentru citire
folosind funcţia opendir. Funcţia closedir are un singur parametru de tipul resursă, care
reprezintă identificatorul de acces al directorului care se doreste a fi închis. Această funcţie nu
returnează nici o valoare, ea având tipul void.

Funcţia readdir
Funcţia readdir se foloseşte pentru a citi următoarea intrare disponibilă într-un director. Ea are
un singur parametru de tip resursă, care reprezintă identificatorul de acces al directorului din
care se va citi. Funcţia readdir returnează un şir de caractere reprezentând numele următoarei
intrări din director, în cazul în care nu am ajuns la sfârşitul acestuia sau nu au aparut erori şi
valoarea logică FALSE în caz contrar. În continuare este un exemplu de utilizare a funcţiilor
opendir, readdir şi closedir:

Cod:

<?php
$dir = "E:\\";
$dh = opendir($dir);
echo "Continutul directorului $dir<BR>";
while (false!==($fis=readdir($dh)))
{
echo "$fis<BR>";
}
closedir($dh);
?>

Funcţia rewinddir
Această funcţie resetează poziţia curentă dintr-un director, şi anume, dacă după un anumit
număr de citiri este apelată această funcţie şi după aceeea se mai citeşte o intrare din
directorul respectiv, atunci se va returna prima intrare din director. Funcţia are un singur
parametru de tipul resursă, care reprezintă identificatorul de acces al directorului din care se
va citi şi nu returnează nici o valoare.

Clasa dir
Această clasa încapsulează funcţiile opendir, closedir, readdir şi rewinddir. Structura acesteia
este următoarea:

Cod:

class dir

dir (string directory)

string path

resource handle

string read (void)

void rewind (void)

void close (void)

Constructorul clasei dir primeşte ca parametru un şir de caractere care reprezintă numele
directorului care se va citi şi apelează funcţia opendir. Funcţiile read, rewind şi close din cadrul
acestei clase au acelaşi comportament cu funcţiile readdir, rewinddir, respectiv closedir şi se
deosebesc de acestea prin simplul fapt că nu mai au parametri, deoarece identificatorul de
acces la director este de asemenea încapsulat în cadrul clasei dir. În continuare este prezentat
un exemplu de utilizare a acestei clase care reprezintă implementarea cu clase a exemplului
anterior:

Cod:

<?php
$d = dir("E:\\");
echo "Continutul directorului $d -> path <BR>";
while (false !== ($fis = $d -> read()))
{
echo "$fis<BR>";
}
$d -> close();
?>

Funcţia mkdir
Această funcţie se foloseşte pentru a crea un director nou şi primeşte ca parametru un şir de
caractere care reprezintă numele directorului care se va crea şi atributele acestuia (parametru
de tip întreg) în format *nix. Funcţia returnează valoarea logică TRUE în caz de succes şi
valoarea logică FALSE în caz de eşec.

Funcţia rmdir
Această funcţie se foloseşte pentru a şterge un director de pe disc şi primeşte ca parametru un
şir de caractere care reprezintă numele directorului care va fi şters. Directorul care se doreşte
a fi şters trebuie să nu conţină nici un fişier sau subdirector. Funcţia returnează valoarea logică
TRUE în caz de succes şi valoarea logică FALSE în caz de eşec.

Funcţia basename
Această funcţie returnează numele de bază al unui fişier sau director sub forma unui şir de
caractere. Funcţia are doi parametri de tip şir de caractere. Primul parametru reprezintă o cale
către un fişier sau director, iar al doilea este opţional şi reprezintă sufixul fişierului. În
continuare este prezentat un exemplu de utilizare a acestei funcţii:

Cod:

<?php
$cale= "c:\\test.html";
echo "Numele fisierului cu sufix:<BR>";
echo basename($cale)."<BR>";
echo "Numele fisierului fara sufix: <BR>";
echo basename($cale,".html");
?>

Funcţia dirname
Această funcţie returnează numele directorului părinte al unui fişier sau director sub forma
unui şir de caractere. Funcţia are un singur parametru de tip şir de caractere care reprezintă o
cale către un fişier sau director. În continuare este un exemplu de utilizare a acestei funcţii:

Cod:

<?php
$cale = "c:\\test.html";
echo "Directorul parinte pentru ";
echo $cale." este ".dirname($cale);
?>

Funcţia pathinfo
Aceasta funcţie se foloseşte pentru a afia informaţii referitoare la o cale către un fişier sau
director. Funcţia pathinfo primeşte ca parametru un şir de caractere care reprezintă calea
către un fişier sau director. Funcţia returnează un tablou ale cărui valori sunt de tipul şir de
caractere şi care conţine elementele " dirname ", "basename" şi "extension". Elementele
"dirname" şi "basename" au valori identice cu cele returnate de funcţiile cu acelasi nume, iar
elementul "extension" conţine extensia fişierului. Exemplu:

Cod:

<?php
$cale = "c:\\test.html";
$info = pathinfo($cale);
echo "Informatii despre $cale:<BR>";
echo "Director: ";
echo $info["dirname"]."<BR>";
echo "Nume fisier: ";
echo $info["basename"]."<BR>";
echo "Extensie: ";
echo $info["extension"]."<BR>";
?>

Funcţia file_exists
Această funcţie se foloseşte pentru a determina dacă un fişier există sau nu pe disc. Funcţia
file_exists are un singur parametru de tip şir de caractere care reprezintă numele fişierului
pentru care se verifică existenţa fizică pe disc. Funcţia returnează valoarea logică TRUE în caz
de succes şi valoarea logică FALSE în caz de eşec. Această funcţie nu poate fi folosită pentru
fişiere aflate la distanţă decât dacă sunt partajate de pe o platformă Microsoft Windows pe
care a fost configurată componenta File and Print Sharing sau dacă sunt partajate pe o
platformă *nix pe care a fost instalat pachetul Samba.

Funcţia copy
Această funcţie se foloseşte pentru a copia un fişier şi are doi parametri de tip şir de caractere.
Primul dintre aceştia reprezintă numele fişierului sursă şi cel de-al doilea reprezintă numele
fişierului destinaţie. Funcţia returnează valoarea logică TRUE în caz de succes şi valoarea
logică FALSE în caz de eşec.

Funcţia rename
Această funcţie se foloseşte pentru a redenumi un fişier şi are doi parametri de tip şir de
caractere. Primul parametru reprezintă numele fişierului şi cel de-al doilea reprezintă noul
numele al acestuia. Funcţia returnează valoarea logică TRUE în caz de succes şi valoarea
logică FALSE în caz de eşec.

Valori scalare şi tablouri

Majoritatea cumpărătorilor preferă să cumpere ouăle în ambalaje de câte 10, nu unul câte
unul. Similar, deseori este convenabilă stocarea mai multor valori într-o variabilă. O asemenea
variabilă se numeşte tablou, iar valorile individuale se numesc elementele tabloului. Variabilele
care au o singură valoare se numesc scalare. Pentru a fi posibil accesul individual la fiecare
element al unui tablou, fiecare element are o cheie asociată. Combinaţia dintre numele
tabloului şi valoarea unei chei identifică un element al tabloului. Pentru a crea un tablou, se
atribuie unui element al tabloului o valoare şi o cheie:

Cod:

<?php
$variabila[1] = "valoarea_a";
?>

Această instrucţiune creează un tablou denumit $variabila şi un element cu valoarea


"valoarea_a" identificat prin cheia 1. Pentru a stoca în tablou o a doua valoare, puteţi folosi
următoarea instrucţiune de atribuire:

Cod:

<?php
$variabila[2] = "valoarea_b";
?>

Pentru a obţine acces la un element al tabloului, specificaţi numele tabloului şi valoarea cheii:

Cod:

<?php
echo $variabila[1];
?>

Cheile folosite pentru identificarea elementelor unui tablou nu trebuie să fie numere
consecutive; nici macăr nu trebuie să fie numere.

Cod:

<?php
$preferinte["vizitator1"] = "scripturi free";
$preferinte["vizitator2"] = "articole";
?>

Elementele unui tablou cu chei non-numerice sunt accesibile în acelaşi mod ca şi elementele
unui tablou cu chei numerice. De exemplu:

Cod:

<?php
$specialitatea_zilei = $preferinta["vizitator1"];
?>

atribuie variabilei $specialitatea_zilei valoarea "scripturi free".

Crearea tablourilor
Se poate crea un tablou PHP în două moduri principale. Puteţi atribui o valoare unei variabile
dintr-un tablou sau puteţi invoca funcţia array().
Crearea unui tablou folosind atribuiri
Modalitatea cea mai simplă de a crea un tablou este de a atribui o valoare unei variabile de tip
tablou. De exemplu:

Cod:

<?php
$variabila[] = "valoare A";
$variabila[] = "valoare B";
$variabila[] = "valoare C";
?>

Parantezele drepte care urmeaza după numele variabilei indică limbajului PHP că variabila
$variabila este o variabilă de tip tablou. PHP stocheaza în mod automat valorile atribuite
tabloului în celule numerotate succesiv, începând de la $variabila[0]. Iată rezultatul tabloului:

Citat:

0 => valoare A
1 => valoare B
2 => valoare C

Simbolul => arată că unei valori îi este asociată o cheie. În acest caz, cheia 0 este asociată cu
valoarea "valoare A", cheia 1 este asociată cu valoarea "valoare B", iar cheia 2 este asociată
cu valoarea "valoare C". Puteţi asocia tabloul cu un tabel, caz în care exemplul anterior arată
astfel:

0 valoare A
1 valoare B
2 valoare C

Dacă doriţi, puteţi scrie o instrucţiune de atribuire care specifică o valoare cheie, astfel încât să
puteţi asocia o valoare cu un anumit element al tabloului. De exemplu:

Cod:

<?php
$variabila[0] = "valoare A";
$variabila[1] = "valoare B";
$variabila[] = "valoare C";
?>

Observaţi că instrucţiunea finală de atribuire nu include nici o valoare de index. PHP asociază
valoarea "valoare C" cu următorul element consecutiv al tabloului:

Citat:

0 => valoare A
1 => valoare B
2 => valoare C
Elementele unui tablou nu trebuie asociate unor chei consecutive. Iată un exemplu:

Cod:

<?php
$variabila[10] = "valoare A";
$variabila[15] = "valoare B";
$variabila[] = "valoare C";
?>

Rezultatul va fi:

Citat:

10 => valoare A
15 => valoare B
16 => valoare C

Remarcaţi că la fel ca în exemplul anterior că valoarea "valoare C" este asociată următorului
element consecutiv din tablou. În PHP nu trebuie să folosiţi numere întregi pe post de chei.
Puteţi crea un tablou asociativ, cunoscut şi sub numele de tablou indexat cu siruri, prin
specificarea drept chei a unor şiruri:

Cod:

<?php
$variabila['a'] = "ceva 1";
$variabila['cc'] = "ceva 2";
$variabila['d'] = "ceva 3";
?>

Prin instrucţiunile de mai sus, următoarele chei au fost atribuite următoarelor valori:

Citat:

a => ceva 1
cc => ceva 2
d => ceva 3

Semnificaţia utilizării pe post de chei a unor valori întregi consecutive este aceea că puteţi
folosi o buclă for simplă pentru a parcurge iterativ tabloul, cu alte cuvinte, pentru a examina
valorile fiecăruia dintre elementele sale.

Utilizarea funcţiei array()


Dincolo de utilizarea instrucţiunilor de atribuire, cealaltă modalitate principală de creare a unui
tablou PHP constă în utilizarea funcţiei array(). Iată un exemplu care creează un tablou având
drept chei valori întregi consecutive:

Cod:
<?php
$o_variabila = array("ceva", "php", "ceva html");
?>

Acest script creeaza un tablou care conţine:

Citat:

0 => ceva
1 => php
2 => ceva html

Dacă doriţi să asociaţi unei valori o anumită cheie, puteţi folosi operatorul =>, astfel:

Cod:

<?php
$o_variabila = array(10=>"ceva", "php", "ceva html");
?>

Care va creea următorul tablou:

Citat:

10 => ceva
11 => php
12 => ceva html

Ca şi în cazul utilizării unei instrucţiuni de atribuire pentru creearea unui tablou, valorile cheilor
nu trebuie să fie consecutive şi nici măcar întregi:

Cod:

<?php
$o_variabila = array("a"=>"ceva", "cc"=>"php", "d"=>"ceva html");
?>

Această instrucţiune creează următorul tablou:

Citat:

a => ceva
cc => php
d => ceva html

Un tablou multi-dimensional poate fi asimilat, pur şi simplu, unui tablou ale cărui celule conţin
valori ale unui tablou; cu alte cuvinte, un tablou de tablouri. De exemplu un tablou
asemănător:

Pagina Trafic Procent


pagina 1 mic 10
pagina 2 mediu 20
pagina 3 mare 30

Puteţi reprezenta aceste date sub forma unui tablou PHP denumit $date, prin instrucţiunile de
mai jos:

Cod:

<?php
$date["pagina 1"] = array("mic", "10");
$date["pagina 2 "] = array("mediu", "20");
$date["pagina 3 "] = array("mare", "30");
?>

Sau puteţi scrie astfel cu acelaşi rezultat:

Cod:

<?php
$date = array("pagina 1" => array("mic", "10"), "pagina 2" =>
array("mediu", "20"), "pagina 3" => array("mare", "30"));
?>

Parcurgerea iterativă a unui tablou


Când aţi stocat date într-un tablou, puteţi obţine acces la valoarea unui element al tabloului
sau îi puteţi modifica valoarea prin intermediul cheii asociate elementului. De exemplu, avem:

Cod:

<?php
$a[0] = 1;
$a[1] = 10;
$a[2] = 1000;
?>

Puteţi obţine acces la valoarea asociată cheii 1 prin intermediul unei instrucţiuni
asemănătoare:

Cod:

<?php
$y = 3 * $a[1];
echo $y;
echo $a[1];
?>

Similar, puteţi modifica valoarea asociată cheii 2 prin intermediul unei instrucţiuni ca aceasta:

Cod:

<?php
$a[2] = 100;
?>

Uneori, în loc de a obţine accesul la un singur element al unui tablou sau de a-l modifica, doriţi
să obţineti accesul la mai multe elemente ale tabloului. De exemplu, să presupunem că doriţi
să determinaţi dacă în tablou există o anumită cheie sau valoare. Să presupunem că tabloul
reprezintă salarii şi doriţi să măriţi fiecare valoare cu 10 procente. Operaţii de acest gen
implică parcurgerea iterativă a tabloului sau, altfel spus, accesul la fiecare element al
tabloului. În continuare o să încerc o scurtă prezentare a modului de iteraţie prin tablouri
secvenţiale şi non-secvenţiale.

Parcurgerea iterativă a unui tablou secvenţial


Un tablou al cărui chei sunt valori întregi consecutive se numeşte tablou secvenţial. În general,
valoarea cea mai mică a unei chei dintr-un tablou secvenţial este zero; totuşi, puteţi crea un
tablou secvenţial folosind valoarea unu sau orice altă valoare întreagă ca valoare minimă a
cheii. În cazul în care cunoasteţi valoarea minimă a cheii unui tablou secvenţial, puteţi
parcurge iterativ tabloul folosind o buclă for. Pentru aceasta, iniţializaţi variabila de buclă la
valoarea cea mai redusă a cheii. Folosiţi funcţia count() pentru a forma expresia de test a
buclei. Funcţia count() returnează numărul elementelor dintr-un tablou. Iată un exemplu:

Cod:

<?php
$test = array(0=>"valoare a", 1=>"valoare b", 2=>"valoare 3");
$maxim = count($test);
for ($w=0;$w<$maxim;$w++)
{
echo "<br>$w => $test[$w]";
}
?>

Prima instrucţiune creează tabloul. Cea de-a doua instrucţiune obţine numărul elementelor din
tablou. Instrucţiunea for foloseşte variabila buclă $w pentru a parcurge iterativ tabloul; corpul
instrucţiunii include o instrucţiune echo care afişează cheia şi valoarea fiecărui element din
tablou. Datele de ieşire arată astfel:

Citat:

0 => valoarea 1
1 => valoarea 2
2 => valoarea 3

Căutarea într-un tablou secvenţial


Exemplu:

Cod:

<?php
$test = array(0=>"valoare a", 1=>"valoare b", 2=>"valoare 3");
$cautare = "valoare b";
// se cauta in tabloul $test valoarea $cautare
$maxim = count($test);
echo "<br>Se cauta cuvantul $cautare in tabloul test.";
for ($w=0; $w < $maxim; $w++)
{
echo "<br>Se compara cuvantul cu $test[$w]";
if ($cautare == $test[$w])
{
echo "<br>A fost gasit cuvantul $cautare in tabel la nr. $w";
}
}
?>

Prima instrucţiune creează tabloul în care se va căuta. Desigur, într-o aplicaţie iterativă reală,
tabloul nu va fi iniţializat cu valori literale imediat anterior operatiei de căutare. Într-o aplicaţie
reală, conţinutul tabloului este supus la variaţii. Cea de-a doua instrucţiune atribuie valoarea
"valoare b" variabilei $cautare; în exemplu, se caută în tablou valoarea stocată în variabila
$cautare. După comentariu, următoarea instrucţiune obţine numărul elementelor din tablou şi
stochează această valoare în variabila $maxim. Instrucţiunea for funcţioneaza ca mai înainte;
de data aceasta însă, corpul ei conţine alte instrucţiuni şi se execută o altă operaţie. O
instrucţiune echo afişează valoarea fiecărui element al tabloului pe masură ce bucla for
avansează. Instrucţiunea if testează fiecare element şi afişează un mesaj dacă valoarea
elementului este una şi aceeaşi cu valoarea variabilei $cautare. Iată rezultatul acestui
exemplu:

Citat:

Se cauta cuvantul valoare b in tabelul test


Se compara cuvantul cu valoare a
Se compara cuvantul cu valoare b
A fost gasit cuvantul valoare b in tabel la nr. 1
Se compara cuvantul cu valoare 3

Instrucţiunea break
Observaţi în exemplul dat mai sus că se continuă căutarea chiar şi după stabilirea unei
identităţi. Când se caută într-un tablou, execuţia căutării poate fi sistată după găsirea
elementului dorit; continuarea căutării în tablou nu face decât să irosească resursele
calculatorului, fără a afecta rezultatele operaţiei. Pentru a oprii execuţia puteţi folosi
instructiunea break, care determină încheierea imediată a buclei care o conţine. Iată cum ar
arăta exemplul anterior cu o instrucţiune break:

Cod:

<?php
for ($w=0; $w < $maxim; $w++)
{
echo "<br>Se compara cuvantul cu $test[$w]";
if ($cautare == $test[$w])
{
echo "<br>A fost gasit cuvantul $cautare in tabel la nr. $w";
break;
}
}
?>

Acum, după stabilirea unei identităţi, instrucţiunea break provoacă sistarea buclei for. Datele
de ieşire vor arăta astfel:

Citat:

Se cauta cuvantul valoare b in tabelul test


Se compara cuvantul cu valoare a
Se compara cuvantul cu valoare b
A fost gasit cuvantul valoare b in tabel la nr. 1

Instrucţiunea continue
O instrucţiune corelată cu instrucţiunea break este continue. Instrucţiunea continue sistează
rularea curentă a buclei, determinând evaluarea imediată a expresiilor de incrementare şi de
test. Ca un exemplu, să presupunem că doriţi să cautaţi în tabloul $test pentru a determina
numărul valorilor cu nume scurte, adică nume alcatuite din maxim 4 caractere. Iată un
exemplu:

Cod:

<?php
$test = array(0=>"a", 1=>"bbb", 2=>"ccccc");
// numara numele scurte
$scurt = 0;
$limita = count($test);
for ($w = 0; $w < $limita; $w++)
{
$n = strlen($test[$w]);
echo "<br>$test[$w] are $n caractere lungime.";
if ($n > 4) continue;
$scurt++;
}
echo "<br> Au fost gasite $scurt cuvinte cu nume scurte.";
?>

O instrucţiune de atribuire stabileste valoarea iniţială a variabilei $scurt, folosită pentru a


număra numele scurte găsite, la zero. Instrucţiunea for se aseamănă celor folosite anterior.
Corpul acestei instrucţiuni diferă, desigur, de cele folosite anterior. Valoarea variabilei $n este
stabilită ca fiind egală cu numărul caracterelor care compun cuvântul, folosind funcţia strlen(),
care calculează lungimea unui sir. Dacă instrucţiunea if stabileşte că elementul curent al
tabloului face referire la un cuvânt lung, se execută instrucţiunea continue. Instrucţiunea
continue determină trecerea căutării la următorul element din tablou; dacă nu au mai rămas
elemente în tablou, bucla for îşi încheie execuţia. La finalizarea căutării, o instrucţiune echo
afişează numărul cuvintelor scurte găsite în tablou. Iată rezultatul:

Citat:

a are 1 caractere lungime


bbb are 3 caractere lungime
ccccc are 5 caractere lungime
Au fost gasite 2 cuvinte cu nume scurte.

Parcurgerea iterativă a unui tablou non-secvenţial


În unele limbaje de programare, parcurgerea unui tablou non-secvenţial este o operaţie
complicată. Cu toate acestea, PHP 4 include o instrucţiune foreach care simplifică căutările de
acest gen. Instrucţiunea foreach are următoarea formă generală:

Cod:

<?php
foreach ($tablou as $cheie => $valoare) {corp}
?>

Instrucţiunea parcurge în mod iterativ tabloul denumit $tablou, stabilind valori adecvate
pentru valorile variabilelor $cheie şi $valoare aferente fiecărui element al tabloului. Iată un
exemplu:

Cod:

<?php
$test = array(10=>"mere", 20=>"metal", 21=>"Nume");
foreach ($test as $index => $continut)
{
echo "<br>$index => $continut";
}
?>

Pentru a căuta într-un tablou multi-dimensional, se folosesc instrucţiuni foreach îmbricate. Să


luăm de exemplu tabloul următor:

Pagina Trafic Procent


pagina 1 mic 10
pagina 2 mediu 20
pagina 3 mare 30

Tabloul poate fi creat folosind următoarele instrucţiuni PHP:

Cod:

<?php
$date["pagina 1"] = array("mic", "10");
$date["pagina 2 "] = array("mediu", "20");
$date["pagina 3 "] = array("mare", "30");
?>

Comanda care afişează conţinutul tabloului este:

Cod:

<?php
foreach ($date as $continut => $valoare)
{
foreach ($valoare as $cheie => $rezultat)
{
echo "<br>$continut: $rezultat";
}
}
?>

Instrucţiunea foreach exterioară obţine tabloul asociat cu fiecare pagină (pagina 1, 2 etc...);
instrucţiunea foreach interioară parcurge iterativ conţinutul. Iată rezultatul:

Citat:

pagina 1: mic
pagina 1: 10
pagina 2: mediu
pagina 2: 20
pagina 3: mare
pagina 3: 30

Lucrul cu formulare

Utilizarea scripturilor php în formulare


Odată am avut nevoie într-un formular să fie afişată iniţial data din ziua completării
formularului. Mă gândesc că uneori o să aveţi şi voi nevoie de anumite date (de exemplu la o
comandă într-un formular să apară într-un câmp doar ceea ce există în acel moment pe stoc,
care stoc se găseşte în baza de date mysql de pe server). Iată ce trebuie să faceţi:

Cod:

<form name="form1" method="post" action="pagina_de_test.php">


Data curenta:
<input name="data" type="text" id="data"
value="
<?php
$data=date("d-h-Y",time()); echo $data;
?>
">
<br>
<br>
<input type="submit" name="Submit" value="Trimite">
</form>

După cum observaţi, la valoarea câmpului "data" am introdus un mic script php care citeşte
data curentă de pe server şi o timite browserului, acesta o afişează în câmpul de text
corespunzător. Puteţi încerca şi voi să citiţi anumite date dintr-un fişier txt sau din baza de
date şi să le afişaţi în formular.
Dacă doriţi să apară un mesaj în interiorul câmpului dar să dispară când un utilizator vrea să
introducă propriul lui text, codul ar fi cam aşa:

Cod:

<form>
<INPUT name=test id="test"
onclick="this.value='';" value=cauta size=15 maxLength=30>
<INPUT name="submit" type=submit id="submit" value=GO>
</form>

Dacă cineva încearcă să scrie ceva, textul "caută" va dispare şi va fi înlocuit cu mesajul
introdus de utilizator.

Preluarea şi verificarea datelor dintr-un formular în aceeaşi pagină cu formularul


De curând cineva mi-a cerut să fac un formular cu un grup de butoane radio care să trimită
datele pe e-mail. Simplu spun eu şi mă apuc de treabă. Problema pe care însă am întâmpinat-
o a fost că un grup de butoane radio trimite doar o valoare, indiferent ce buton e selectat. Mai
jos aveţi codul de la script cu una din rezolvări (eu am gasit 3 variante de rezolvare a acestui
script, dar probabil sunt mult mai multe)

Cod:

<?php
if (isset($_POST['Submit']))
// deoarece verificarea se face in aceeasi pagina cu formul
// se verifica inainte daca a fost apasat butonul submit
{
// preluare variablile (daca sunt trimise)
@$vot = $_POST['vot'];
// verificare
if ($vot == "") // aici se verifica daca a fost selectat ceva
{
echo "<br>Nu ai votat. Incearca din nou.";
}
if ($vot == "vot_1") // daca e selectat vot 1 afiseaza si eventual
trimite pe e-mail...
{
echo "<br>Ai votat numarul 1.";
}
if ($vot == "vot_2") // daca e selectat vot 2 afiseaza si eventual
trimite pe e-mail...
{
echo "<br>Ai votat numarul 2.";
}
if ($vot == "vot_3") // daca e selectat vot 3 afiseaza si eventual
trimite pe e-mail...
{
echo "<br>Ai votat numarul 3.";
}
// afisare continutul variabilei vot
echo "<br>Continutul casutei de vot este: ".$vot;
}
?>

<html>
<head>
<title>Formular de vot</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-
1">
</head>
<body>
<!-- aici incepe formul de votare -->
<form name="formular_vot" method="post" action="test_vot.php">
<p>
<label>
<input type="radio" name="vot" value="vot_1">
vot a</label>
<br>
<label>
<input type="radio" name="vot" value="vot_2">
vot b</label>
<br>
<label>
<input type="radio" name="vot" value="vot_3">
vot c</label>
<br>
<input type="submit" name="Submit" value="Voteaza">
<br>
</p>
</form>
<!-- aici se incheie formularul de vot -->
</body>
</html>

După cum observaţi, scriptul este împărţit în 2 părţi. Prima parte este codul php care verifică
dacă a fost apăsat butonul "Submit" şi dacă a fost apăsat se preia valoarea butonului radio şi
se verifică. Dacă nu a fost apăsat butonul "Submit" se sare peste codul php şi se trece direct
la partea html unde se afişează butoanele radio.
Lucrând recent cu câteva formulare am întâmpinat unele dificultăţi pe care vreau să le descriu
mai jos pentru a avea un punct de plecare în cazul în care mai am astfel de probleme. Pentru
început o să explic cum se trimit şi cum se preiau datele din formular în aceeaşi pagină. Avem
următorul formular:

Cod:

<?php
// aici se verifica daca a fost trimis un camp din formular
if (isset($_POST['camp1'])) // daca a fost trimis
{
// se preiau datele trimise
$camp1 = $_POST['camp1'];
// se verifica daca a fost scris ceva
if (empty($camp1))
{
echo "<br>Nu a fost introdus nimic";
}
else
{
echo "<br>A fost introdus: ".$camp1;
}
}
if (!isset($_POST['camp1'])) // daca nu a fost trimis
{
// se initializeaza variabilele
$camp1 = '';
}
?>
<form name="form1" method="post" action="
<?php $_SERVER['PHP_SELF'] ?>
">
<div align="center">
<input name="camp1" type="text" id="camp1" value="
<?php echo $camp1; ?>
">
textfield<br>
<input type="submit" name="Submit" value="Trimite">
</div>
</form>

Să explic puţin codul de mai sus.


Prima oară când se accesează pagina este logic că nu se trimite nici o valoare din formular.
Dacă nu ar fi făcută verificarea de setare a unei valori din formular (rândul
if(isset($_POST['camp1']) ) şi s-ar fi încercat preluarea direct a valorii (rândul $camp1 =
$_POST['camp1']; ) ar fi dat o eroare (dacă aveţi configurat serverul să vă arate toate erorile)
În schimb, aşa aţi evitat o eventuală eroare şi scriptul rulează corect indiferent de setările
serverului... Observaţi că la preluarea variabilei trimise prin post se foloseşte un mic truc şi
anume numele variabilei este acelaşi cu numele câmpului trimis prin POST. În cazul când
serverul are setat register_global = off este mai sigur să folosiţi astfel preluarea variabilelor
pentru a nu vâ da eroare. Puteţi lucra şi direct cu valoarea POST dar personal prefer să scriu
mai puţin folosind de fiecare dată numele variabilei ( $camp1 ) nu tot şirul dat de valoarea
POST ( $_POST['camp1'] ) E mai puţin de scris iar dacă folosesc variabila în alte locuri evit
erorile generate de lipsa unei ghilimele
(de genul echo 'ceva aici $_POST['camp1']; // aceasta comanda nu va merge pentru ca am
uitat sa inchid ghilimelele pe cand asa echo '$camp1'; va merge intotdeauna).
În continuare următorul rând verifică dacă valoarea preluata din formular conţine ceva sau nu.
Dacă există ceva atunci afişeaza mesajul împreună cu ceea ce a fost introdus. Mai departe, în
caz că se încarcă pagina prima data şi formularul încă nu a fost trimis se iniţializează valoarea
variabilei pentru câmpul respectiv. În cazul în care nu se iniţializează valoarea şi se încearcă
afisarea ei directă va apărea un mesaj de eroare (dacă serverul e setat să afişeze mesajele de
eroare).
Acum, dacă sunteţi lămuriţi ce se întâmplă acolo să trecem mai departe (iar dacă nu, atunci
recitiţi articolul şi vedeţi încă odată sursa până înţelegeţi :-P )

Afişarea unui text într-un câmp în form care dispare în cazul în care se introduce
ceva în acel câmp
De multe ori, am un formular în care vreau să scriu ceva într-un anumit câmp iar dacă
vizitatorul doreste să completeze acel câmp să nu stea să şteargă mesajul meu ci să dispară
automat textul introdus de mine şi să rămână doar ce a introdus vizitatorul. Aşa ceva se poate
face simplu cu o scurtă funcţie javascript:

Sursa: Exemplu:
<form name="form2" method="post" action="pagina.php">
<input name="textfield" type="text"
value="acest text dispare" onmousedown=" this.value='' ">

</form>

Preluarea datelor dintr-un câmp cu select multiplu


În cazul în care în formular trebuie să existe şi un textfield din care se pot selecta simultan
mai multe câmpuri, preluarea datelor poate părea mai complicată, dar în realitate este la fel
de simplu ca şi până acum, şi anume:
Cod:

<?php
if (isset($_POST['select']))
{
foreach ($_POST['select'] as $cheie => $valoare)
{
echo "<br>A fost selectata valoarea ".$valoare;
}
}
?>

<form name="form3" method="post" action="


<?php $_SERVER['PHP_SELF'] ?>
">
<div align="center">
<select name="select[]" size="5" multiple>
<option value="1">valoarea 1</option>
<option value="2">valoarea 2</option>
<option value="3">valoarea 3</option>
<option value="4">valoarea 4</option>
<option value="5">valoarea 5</option>
</select>
Selectati mai multe valori<br>
<br>
<input type="submit" name="Submit2" value="Submit">
</div>
</form>

Momentan mă opresc aici cu prezentarea trucurilor în lucrul cu formulare, dacă mai aveţi
întrebări discutăm în forum.

Conversia tipurilor de variabile

PHP este ceea ce se numeste un limbaj de programare cu tipuri dinamice. O consecinţă a


caracterului dinamic al tipurilor de variabile aferente limbajului PHP este aceea că nu trebuie
să specificaţi tipul variabilelor. PHP determină tipul variabilei în funcţie de tipul ultimei valori
atribuite variabilei. Cu toate acestea, caracterul dinamic al tipurilor nu vă scuteşte de
problemele legate de tipuri. În continuare este o descriere a tipurilor acceptate şi ceea ce se
întâmplă când în cadrul expresiilor se folosesc două sau mai multe tipuri.

Conversia automată de tip

Să luăm ca exemplu următorul script:

$x = 1;
$y = 2.5;
$z = $x + $y;
echo $z;

Când o expresie aritmetică foloseşte mai multe tipuri, PHP execută conversia automată de tip.
Dacă oricare dintre operanzi este de tip dublu, PHP tratează ceilalti operanzi ca şi cum ar fi de
tip dublu, execută calculele şi returnează rezultatul ca valoare de tip dublu. Dacă toti operanzii
unei expresii sunt întregi, PHP execută calculul şi returnează rezultatul sub forma de întreg. În
exemplul de mai sus, rezultatul va fi 3.5 o valoare de tip dublu. Este important de reţinut că
prin conversia de tip nu se modifică tipurile operanzilor unei expresii; aceştia sunt pur şi
simplu trataţi ca şi cum ar fi fost de alt tip. În cadrul exemplului, variabila $x rămâne de tip
întreg, chiar dacă PHP o tratează ca o valoare de tip dublu pentru a executa calculele.
Şirurile pot fi de asemenea supuse unei conversii de tip. Să examinăm următorul exemplu:

$x = 1;
$y = $x + "1 more";
echo $y;

Valoarea afişata este 2, adică suma dintre valoarea variabilei $x şi valoarea numerică a şirului
text, care este 1. Valoarea numerică şi tipurile unui şir sunt determinate prin respectarea
următoarelor reguli:
1. Dacă şirul începe cu o valoare numerică, valoarea şirului este dată de valoarea numerică
respectivă; în caz contrar, valoarea şirului este zero.
2. Dacă un punct zecimal sau un exponent (e sau E), este asociat cu valoarea numerică, tipul
variabilei rezultate este dublu; în caz contrar, tipul valorii rezultante este un întreg.

Conversia manuală de tip

Dacă preferaţi, puteţi prelua controlul conversiei de tip sau puteţi modifica tipul unei variabile.
Pentru a prelua controlul conversiei de tip, puteţi converti forţat un operand de la un tip la
altul, proces cunoscut sub numele de conversie forţată de tip sau pur şi simplu conversie
forţată. În continuare aveţi un exemplu de conversie de tip:

$x = 1;
$y = 2.5;
$z = $x + (integer) $y;
echo $z;

Conversia forţată de tip, şi anume (integer), determină tratarea variabilei $y ca pe un întreg,


iar valoarea acesteia devine 2, în loc de 2.5, care este valoarea reală a variabilei $z. Tabelul
următor indică şi alte conversii forţate de tip care se pot folosi:

Conversia forţată Rezultat


(int), (integer) Conversie forţată la întreg
(real), (double), (float) Conversie forţată la dublu
(string) Conversie forţată la şir
(array) Conversie forţată la tablou
(object) Conversie forţată la obiect

Numeroase funcţii furnizează înca o modalitate de a trata o variabilă ca şi cum ar fi de tip


specificat. Tabelul următor prezintă succint aceste funcţii.

Funcţie Operaţie
doubleval() Tratează argumentul ca fiind de tip dublu
intval() Tratează argumentul ca fiind de tip întreg
strval() Tratează argumentul ca fiind de tip şir.

Exemplu:
$x = 1.5;
$y = intval($x);
echo $x;
echo $y;

Valoarea 1.5 este afişată ca valoare a variabilei $x, iar valoarea 1 este afişată ca valoare a
variabilei $y.
Nici conversia normală şi nici cea forţată nu modifică tipul unui operand. Ambele mecanisme
determină tratarea operanzilor ca şi cum ar fi de un alt tip. Totuşi, modificarea tipului unei
variabile este posibilă prin utilizarea funcţiei settype(). Acest procedeu este ilustrat în
continuare:

$x = 1.5;
settype($x, "integer");
echo $x;

Valoarea afişata a variabilei $x este egală cu unitatea, deoarece fracţia zecimală se pierde
atunci când funcţia settype() converteşte valoarea dublă la o valoare întreagă. Puteţi obţine
acelaşi rezultat cu următoarea instrucţiune de atribuire, care foloseşte o conversie forţată:

$x = (integer) $x;

Valorile posibile pentru al doilea argument al funcţiei settype(), şi anume argumentul care
specifică tipul dorit, sunt:
- integer
- double
- string
- array
- object

O funcţie conexă, şi anume gettype(), returnează un şir care indică tipul variabilei specificate.
Scriptul următor afişeaza şirul "integer", care indică tipul variabilei $x:

$x = 1;
echo gettype($x);

Instrucţiuni de atribuire

În cazul în care doriţi o modalitate rapidă de a scrie o instrucţiune de atribuire, puteţi folosi
anumiţi operatori. Următoarele două instrucţiuni de atribuire, una normală şi una "rapidă", au
acelaşi efect:

$x += 1;
$x = $x + 1;

Această instrucţiune de atribuire "rapidă" vă scuteşte de efortul de a scrie o variabilă, $x în


cazul exemplului nostru, în ambii membri ai instrucţiunii de atribuire. Tabelul următor rezumă
operatorii "rapizi" de atribuire pentru operaţiile aritmetice şi pentru şiruri, furnizând un
exemplu pentru fiecare operator şi o instrucţiune de atribuire echivalentă.

Instrucţiune de atribuire "rapidă" Instrucţiune de atribuire normală


x += y x=x+y
x -= y x=x-y
x /= y x=x/y
x *= y x=x*y
x %= y x=x%y
x .= y x=x.y

Scrierea instrucţiunilor swich, break şi default

Instrucţiunea if vă permite să luaţi o decizie în două sensuri. Pentru a putea lua o decizie în
mai multe sensuri, puteţi folosi mai multe instrucţiuni if, else sau elseif. Cu toate astea, când
doriţi ca programul dvs. să aleagă dintr-un set de alternative care pot fi reprezentate prin
valori întregi, instrucţiunea switch este o opţiune mai convenabilă. De exemplu, să
presupunem că valoarea variabilei $numar este 1, 2 sau 3, reprezentând respectiv
dimensiunile mică, medie şi mare. Iată un mic program care afişează dimensiunile asociate
valorilor variabilei $numar:

Cod:

<?php
switch ($numar)
{
case(1):
echo "numar mic";
break;
case(2):
echo "numar mediu";
break;
case(3):
echo "numar mare";
break;
default:
echo "Acesta nu este un numar valabil";
}
?>

Acţiunea unei instrucţiuni switch este determinată de valoarea unei expresii întregi, nu de
valoarea unei expresii condiţionale. Numele variabilei este dat între parantezele care urmează
după cuvântul cheie switch. Parantezele acolade delimitează o serie de instrucţiuni case şi o
instrucţiune default opţională, fiecare dintre instrucţiunile cuprinse între paranteze putând
avea instrucţiuni asociate.
Când este executată, instrucţiunea switch încearcă să stabilească o identitate între valoarea
variabilei sale asociate şi valoarea asociată unei instrucţiuni case. Se vor executa instrucţiunile
asociate primei instrucţiuni case pentru care identitatea respectivă este valabilă. Dacă
valoarea variabilei din instrucţiunea switch nu corespunde nici uneia dintre valorile asociate
instructiunilor case, se vor executa instrucţiunile asociate instrucţiunii default, dacă există o
asemenea instrucţiunie.
Un procedeu de programare indicat constă în aceea că fiecare instrucţiune case din cadrul unei
instrucţiuni switch să se încheie cu o instrucţiune break. Instrucţiunea break determină
încheierea exeuţiei instrucţiunii switch, transferând controlul următoarei instrucţiuni
secvenţiale care succede instrucţiunii switch.(adică se continuă cu restul codului din script) În
absenţa instrucţiunii break, execuţia trece la următoarea instrucţiune case sau default, fapt
nedorit în majoritatea cazurilor. Nu este necesar să folosiţi numere întregi consecutive în
instrucţiunile case. Se pot folosi numere întregi non-consecutive, numere cu virgulă mobilă
sau şiruri.
În exemplul următor aveţi o instrucţiune switch care testează valoarea variabilei $meniu.
Instrucţiunea atribuie variabilei $submeniu o valoare după cum urmează:
dacă $meniu este 1, $submeniu primeste valoarea 5;
dacă $meniu este 2, $submeniu primeste valoarea 10;
altfel, $submeniu primeşte valoarea 0.

Cod:

<?php
switch ($meniu)
{
case 1:
$submeniu = 5;
break;
case 2:
$submeniu = 10;
break;
default:
$submeniu = 0;
}
?>

PHP include numeroase instrucţiuni condiţionale, incluzând instrucţiunile if, else, elseif şi
switch. Mai există însă şi alt mecanism de luare a deciziilor - operatorul condiţional ?:, denumit
uneori şi operator ternar sau operator întrebare-două puncte. El constituie o altă modalitate de
a scrie decizii în PHP. Operatorul condiţional formează o expresie care se poate folosi în multe
contexte PHP.
Iată sintaxa de utilizare a acestuia:

expresie-conditionala ? valoare-adevarat : valoare-fals

Se observă cum semnul întrebării este separat de caracterul două puncte prin valoarea
valoare-adevarat. Operatorul condiţional îşi evaluează expresia condiţionala. Dacă expresia
este evaluată la valoarea true (adevărat), operatorul condiţional returnează valoarea valoare-
adevarat; în caz contrar, returnează valoarea valoare-fals. Operatorul condiţional vă permite
să specificaţi deciziile într-o manieră foarte concisă. De exemplu, să luăm următoarea
instrucţiune de atribuire:

$a = ($b > $c) ? 1 : 2

Această instrucţiune de atribuire compară valorile variabilelor $b şi $c. Dacă valoarea


variabilei $b este mai mare decât aceea a variabilei $c, atunci variabilei $a îi este atribuită
valoarea 1; în caz contrar, variabilei respective îi este atribuită valoarea 2.

Scrierea instrucţiunilor for

Revin în acest articol la detalierea instrucţiunii for, pe care o folosesc destul de des în ultima
vreme. Instrucţiunea for este o instrucţiune buclă sau o instrucţiune iterativă; cu alte cuvinte,
o instrucţiune care execută în mod repetat instrucţiunile asociate. Iată un exemplu de utilizare
a unei instrucţiuni for:
Cod:

<?php
$suma = 0;
for ($n = 1; $n <= 3; $n++)
$suma += $n;
echo "<br>Suma intregilor de la 1 la $numar este $suma.";
?>

În exemplul de mai sus se calculează suma întregilor cuprinşi între 1 şi 3. Pentru aceasta, mai
întâi se iniţializează variabila $suma la valoarea 0. Apoi, se execută o instrucţiune for care
incrementează în mod repetat valoarea variabilei $suma.
Pentru a vedea cum funcţionează mecanismul aestei instrucţiuni, să examinăm componentele
instrucţiunilor for. Instrucţiunea for include trei expresii, care apar între paranteze; fiecare
expresie este separată de vecina sa printr-un caracter punct şi virgulă. De asemenea,
instrucţiunea for include o instrucţiune sau un grup de instrucţiuni, cunoscute sub numele de
corpul instrucţiunii for. În exemplul de mai sus, instrucţiunea $suma += $n este corpul
instrucţiunii for.

Să examinăm mai amănunţit cele trei expresii:


- Prima expresie este expresia de iniţializare. Aceasta se execută atunci când PHP ajunge la
instrucţiunea for. În exemplu, expresia de iniţializare atribuie valoarea 1 variabilei $n, variabilă
denumită variabila de ciclare sau index.
- A doua expresie este expresia de test. Aceasta este o expresie condiţională care indică dacă
se execută sau nu corpul instrucţiunii. În general, face referire la variabila de ciclare. În cadrul
exemplului, expresia de test compară valoarea variabilei $n cu valoarea 3. Expresia de test
este evaluată pentru prima data imediat după evaluarea expresiei de iniţializare.
- Cea de-a treia expresie este expresia pas. În general, aceasta modifică una sau mai multe
variabile la care se face referire în expresia test. În cadrul exemplului, expresia pas
incrementeaza valoarea variabilei $n.

Secvenţa de execuţie a unei instrucţiuni for este următoarea:


1. Se evalează expresia de iniţializare.
2. Se evaluează expresia test.
3. Dacă rezultatul evaluării expresiei test este false, se execută etapa 7.
4. Se execută corpul buclei.
5. Se evaluează expresia pas.
6. Se trece la etapa 2.
7. Se încheie execuţia instrucţiunii for, prin executarea următoarei instrucţiuni secvenţiale.

Instrucţiunea for este utilă pentru numărare şi executarea în mod repetat a unor acţiuni. În
acest site de exemplu am folosit instructiunea for pentru a trimite către fiecare user înscris la
newsletter căte un e-mail de fiecare dată când este actualizat acest site.

Scrierea instrucţiunilor while şi do while

Practic, instrucţiunile while şi do while reprezintă versiuni "manuale" ale instrucţiunii for. Dacă
o instrucţiune for are trei expresii, o instrucţiune while sau do while are una singură, şi anume
expresia de test. Aşa cum se întâmplă de obicei, expresiile unei instrucţiuni for sunt opţionale;
fără o expresie de iniţializare sau o expresie pas, o instrucţiune for operează în acelaşi mod ca
o instrucţiune while. În consecinţă, următoarele două instrucţiuni sunt echivalente:
Cod:

<?php
for ( ; $i <= 3; ) $suma += $i;

while ($i <= 3) $suma += $i;


?>

Când folosiţi o instrucţiune while, trebuie să furnizaţi un mecanism oarecare, analog expresiei
de incrementare a instrucţiunii for, care actualizează variabilele la care se face referire în
expresia de test. De asemenea, sunteţi responsabil cu iniţializarea tuturor valorilor folosite în
expresia de test.

Secvenţa de execuţie a unei instrucţiuni while este următoarea:


1. Se evaluează expresia test.
2. Dacă rezultatul este false, se trece la etapa 5.
3. Se execută corpul buclei.
4. Se trece la etapa 1.
5. Se părăseşte bucla, prin executarea următoarei instrucţiuni secvenţiale.

Iată un exemplu care utilizează instrucţiunea while:

Cod:

<?php
$n = 0;
$suma = 0;
while ($n <= 3)
{
$suma = $suma + $n;
$n++;
}
echo "Suma este $suma.";
?>

Remarcaţi că instrucţiunea $n = 0; iniţializează bucla şi că instrucţiunea $n++; incrementează


valoarea variabilei bucla $n. Instrucţiunea while este cea mai utilă atunci când un alt program
necesar execută deja aceste funcţii; în asemenea situaţii, instrucţiunea while este mai clară
decât o instrucţiune for degenerată, căreia îi lipsesc una sau mai multe dintre expresiile sale
obişnuite.

Instrucţiunea do while este oarecum asemănătoare instrucţiunii while. Diferenţa este aceea că
instrucţiunea do while îşi execută corpul înainte de a-şi evalua expresia de test. Astfel, corpul
buclei unei instrucţiuni do while este întotdeauna executată cel puţin o dată; corpul unei
instrucţiuni while este omis dacă expresia de test are iniţial valoarea false.

Secvenţa de execuţie a unei instrucţiuni do while este următoarea:


1. Se execută corpul buclei.
2. Se evaluează expresia de test.
3. Dacă rezultatul este adevărat, se trece la etapa 1.
4. Se încheie execuţia buclei, prin executarea următoarei instrucţiuni secvenţiale.

Iată un exemplu care foloseşte o instrucţiune do while. Observaţi că amplasarea expresei de


test imediat după corpul buclei vă reaminteşte faptul că executarea corpului are loc înainte de
evaluarea expresiei de test:
Cod:

<?php
$suma = 0;
$n = 1;
do
{
$suma += $n;
$n++;
}
while ($n <= $numar);
echo "<br>Suma intregilor cuprinsi intre 1 si $numar este $suma.";
?>

Instrucţiunile while şi do while sunt foarte asemănătoare. Utilizarea instrucţiunii do while este
o chestiune de comoditate, nu de necesitate. Se pot scrie aplicaţii php folosind doar
instrucţiuni while.

Introducere în Clase PHP

Când începi să lucrezi cu PHP, îţi dai seama că sunt multe locuri în care trebuie să scrii aceaşi
bucată de cod. Unii dintre voi probabil s-au prins că aceasta se poate rezolva cu o funcţie, asta
economisind ceva timp atunci când veţi vrea să refolosiţi codul. Pur şi simplu declaraţi o
funcţie şi îi spuneţi acelei funcţii ce informaţie vreţi să folosească. Metoda este similară celei
de mai jos:

Cod:

<?php
function Functia_Mea($variabila)
{
// Foloseste $variabila aici:
echo $variabila;
}
?>

Şi apoi doar apelezi funcţia atunci când ai nevoie de ea:

Cod:

<?php
Functia_Mea("Salut, bine ai venit pe site");
?>

şi funcţia va afişa la ieşire "Salut, bine ai venit pe site"


Ei bine, după un timp se vor aduna prea multe funcţii şi te vei aglomera. Folosind Clase PHP,
poţi începe să pui acele funcţii în nişte "cutii" unde sunt stocate şi folosite. Clasele PHP s-au
dovedit a fi foarte valoroase, atunci când sunt gândite şi când e scris codul bine. Vă voi face o
introducere în Clase şi vă voi da câteva exemple unde pot fi folosite. Sper ca la sfârşitul
acestui tutorial te vei gândi să implementezi nişte clase proprii economisind astfel timp în
viitoarele proiecte.

Dar haideti să lăsăm vorbăria şi să începem să ne stocăm funcţiile în interiorul Claselor.

Structura Clasei

Când vă gândiţi la clase v-aş încuraja să vă gândiţi ca la "codul din spate". Codul va fi stocat în
spatele site-ului, iar în faţă va fi un bloc de cod foarte uşor de înţeles. Voi pune toate rutinele
complicate în clasa ta, iar scriptul care foloseşte acea clasă va fi mai uşor de înţeles pentru că
va avea un cod "curat". Acesta nu este singurul motiv pentru care poţi folosi clasele, dar este
motivul pentru care eu le folosesc.

OK, să aruncăm o privire pe clasă:

Cod:

<?php
class Clasa_mea
{
var $email;
// folosim o functie fara variabile
function verifica_email()
{
if (ereg("^.+@.+\..+$", $this -> email))
return(true);
else
return(false);
}
// Folosim o functie cu variabile
function scoate_imag($cevahtml)
{
$cevahtml = preg_replace("/(<img)(.*?)(>)/si", "", $cevahtml);
return $cevahtml;
}
}
?>

Clasa de mai sus a fost compusă din 2 funcţii simple. Vom analiza funcţiile pentru a înţelege
despre ce este vorba aici.

Mai întâi trebuie să declarăm o clasă:

class Clasa_mea {

Vom crea nişte variabile ce pot fi folosite în oricare din funcţiile din interiorul clasei fără să
trebuiască să fie specificate pentru fiecare funcţie. Vom face asta prin "var $nume_var", priviti
mai jos pentru exemplul $email pe care îl vom folosi.
var $email;

În continuare, să analizăm prima funcţie. Funcţia aceasta validează mail-ul introdus de


utilizator. Caută text în ambele părţi ale simbolului "@" care este structura unei adrese de
email. Această funcţie va prelua variabila $email definită în scriptul nostru care apelează clasa
şi verifică validitatea email-ului. Dacă adresa de email trece de această verificare şi este o
adresă validă, vom returna "TRUE", altfel vom returna "FALSE". Voi explica asta puţin mai
târziu.

Cod:

<?php
// folosim o functie fara variabile
function verifica_email()
{
if (ereg("^.+@.+\..+ $ " , $this -> email))
return ( true );
else
return ( false );
}
?>

Uitându-vă la funcţia de mai sus, aţi remarcat că am folosit " $this->email " unde $this-> e un
constructor special care indică în interiorul clasei către o variabilă sau o altă funcţie. La început
am definit var $email, acum avem $this->email . Veţi vedea cum să atribuiţi o valoare lui
$this->email când vom folosi "efectiv" scriptul ce apelează clasa .

Nota: puteţi de asemenea folosi în interiorul unei funcţii dintr-o clasă, o altă funcţie ce se află
în aceeaşi clasă. Doar introduceţi $this->numele_functiei($vars); şi funcţii din interiorul
aceleiaşi clase se pot folosi reciproc.

Pentru a vă da un exemplu că puteţi pune aproape orice doriţi în interiorul unei clase, am făcut
această clasă "cu scop general" ce poate fi utilizată în mai multe scopuri. Mai jos veţi vedea o
funcţie pe care am introdus-o în această clasă, funcţie care elimină tag-urile unei imagini
dintr-un string (şir de caractere). Am vrut să vă arăt această clasă şi pentru că este o metodă
diferită de a apela funcţia, această funcţie va accepta o variabilă ca parametru şi trebuie să
aibă acea variabilă definită atunci când o apelezi. Voi explica şi acest lucru mai încolo. Iată
funcţia mai jos:

Cod:

<?php
// Folosim o functie cu variabile
function scoate_imag($cevahtml)
{
$cevahtml = preg_replace( "/(<img)(.*?)(>)/si" , "" , $cevahtml);
return $cevahtml;
}
?>

Acum, închidem clasa noastră şi suntem gata s-o folosim!


}

Să numim acest fişier: "clsClasa_Mea.php" şi să vedem cum îl vom folosi în pagina următoare.

Folosirea acestei Clase în Scripturile voastre PHP

Primul lucru pe care trebuie să-l facem este să includem clasa. Nu este mare lucru, doar
includeţi-o folosind:

<?
include "Clasa_Mea.php";

Acum putem începe distractia :)


Avem clasa noastră inclusă în script şi trebuie să iniţializăm un obiect pe care să-l atribuim
unei variabile. Iată cum se face:

$clasa_mea = &New Clasa_Mea;

Am creat un obiect numit $clasa_mea şi acum putem accesa elementele din interiorul clasei
Clasa_Mea pe care am creat-o mai devreme. Astea fiind făcute, avem variabila "$email" ce stă
degeaba în Clasa_Mea, aşa ca îi vom atribui o valoare:

$clasa_mea -> email = "tu@undeva.com" ;

Tineţi minte că puteţi face: $clasa_mea->email = $_POST['email']; sau orice vreţi cu ea.

Să rulăm funcţia verifica_email în interiorul clasei Clasa_Mea:

Cod:

<?php
$verifica_email = $clasa_mea -> verifica_email();
if (!$verifica_email)
{
echo "Adresa de email nu este valida!";
}
else
{
echo "Adresa de email este valida!";
}
?>

Tot ce am făcut este să atribuim o variabilă funcţiei verifica_email() şi apoi am făcut nişte
verificări de erori pe baza acelei variabile. Tineţi minte ce a spus mai devreme, dacă
verifica_email returnează TRUE, adresa conţinută în variabila $email pe care i-am spus s-o
verifice a trecut testul, dacă nu a trecut testul va returna FALSE. Privind instrucţiunea if de
mai sus, vei vedea că dacă un "!" sau "Eroare" este detectat pe şirul de caractere din
$verifica_email, vom afişa "Adresa de email este valida!".

Haideţi să ne uităm cum folosim funcţia scoate_imag. Întâi vom crea un string cu HTML în
interior.
$html_vechi = '<strong>Am o imagine aici: <img src="/imaginea_mea.jpg" height="100"
width=" 200" >' ;

Acum că avem $html_vechi şi ştim că are o imagine în interiorul HTML-ului, să scoatem acea
imagine afară şi să returnăm rezultatul:

$html_nou = $clasa_mea -> scoate_imag($html_vechi);


echo "Aici este html-ul vechi $html_vechi <br /><br />" ;
echo "Aici este html-ul nou $html_nou <br /><br />" ;

Când veţi privi $html_vechi şi $html_nou, veţi vedea că imaginea a fost eliminată cu succes.

Dacă ai înţeles ce s-a întâmplat până acum, felicitările mele, tocmai ai învăţat noţiunile
elementare ale claselor! Dacă nu, te sfătuiesc să mai citeşti acest tutorial încă o dată. Îl vei
înţelege până la urmă.

Aşa cum am spus mai devreme, clasele s-au dovedit a fi foarte eficiente. Ele sunt calea câtre
"Object Oriented Programming" sau "Programarea Orientata pe Obiecte" - OOP. Cu OOP puteţi
economisi foarte mult timp şi puteţi crea o arhivă de obiecte sau clase pe care le puteţi folosi
mereu.

Referinte:

Iată câteva link-uri pe care le puteţi vizita când vă dezvoltaţi clasele:

PHP Manual - Classes and Objects


PHP Manual - Extends
PHP Manual - Exending Classes Using Parents
PHP Manual - Classes using :: operator
PHP Manual - Serialize and Unserialize Objects

Închei aici această introducere în Clasele PHP.

Toate cele bune!

Sesiuni în PHP

În mod normal, o variabilă locală declarată într-o pagina .php este valabila doar în acea
pagină, dacă nu intervenim într-un fel pentru a o transfera şi pe alte pagini unde avem nevoie
de ea. Modalităţile de păstrare a informaţiilor pe tot parcursul aplicaţiei sunt:
- variabile globale
- sesiuni
- cookies
- transferul variabilelor locale prin forme sau în header-ul unei alte pagini

Ce este o sesiune?
O sesiune reprezintă una din căile de a păstra datele de lucru ale unei aplicaţii atunci când se
face transferul de la o pagină la alta. PHP foloseşte în mod nativ sesiuni, aşa cum fac şi
limbajele ASP şi ColdFusion. Lucrul cu sesiuni nu este complicat. Fiecare sesiune trebuie
declarată la începutul paginii, cu ajutorul funcţiei:
session_start();

Această funcţie face ca PHP să înregistreze un identificator unic al sesiunii (ID), iar acel
identificator este trimis utilizatorului printr-un cookie. Totodată, pe server se crează un fişier
care va reţine valorile variabilelor folosite în această sesiune. Fişierul are numele la fel cu
identificatorul ID al sesiunii. Apoi trebuie declarată variabila (sau variabilele) cu care lucrăm în
cadrul acestei sesiuni. Pot fi create oricâte variabile.

session_register('sesiunea_mea');

Variabila $sesiunea_mea poate fi o variabilă simplă sau un tablou (array). Exemplu:

$sesiunea_mea = "Lucian"; // variabila simplă

sau

$sesiunea_mea["id"] = 1; // cazul unui array


$sesiunea_mea["nume_utilizator"] = "Lucian";
$sesiunea_mea["adresa"] = "Str.Florilor nr.14"; // etc.

Variabilele definite în acest mod pot fi folosite pe toate paginile unei aplicaţii, definite pe un
domeniu dat, atât timp cât cookie alocat acelei sesiuni este activ (nu expiră). Folosirea
sesiunilor este o cale mult mai uşoara de lucru decât să transferăm variabilele de la pagină la
pagină. În php.ini pot fi setate diferite valori pentru parametri legaţi de sesiune cum ar fi
(după semnul egal am pus valorile implicite) :

session.cookie_path = "/";
session.cookie_domain = "";
session.cookie_lifetime = "0"; // valoarea 0 înseamnă că cookie pentru sesiune e valabil până
când browserul se va închide.
session.name = "PHPSESSID";

şi altele .
Există posibilitatea ca un utilizator să nu accepte setarea de cookies pe computerul său. În
acest caz, pentru identificarea unei sesiuni se poate folosi identificatorul acesteia. Putem
adăuga acest identificator în stringul care aplează o pagină:

<a href = "pagina_mea.php?<?=SID?">Click catre pagina mea</a>

<?= este un mod mai scurt de a scrie comanda echo. <?= se poate folosi cu orice variabilă,
nu doar cu sesiuni. Un identificator PHPSESSID arată ca o înşirurire aleatoare de caractere
alfanumerice:

PHPSESSID = 02993ab99sac988da9753330af72201

Dacă PHP este compilat cu opţiunea enable-trans-id, atunci identificatorul sesiunii este
adăugat automat la fiecare pagină. Iată un exemplu de definire al unei sesiuni:

<?
session_start();
session_register("variabila_mea");
$variabila_mea = "Aceasta este cursul online de PHP";
?>

$variabila_mea va putea fi folosită apoi pe toate paginile aplicaţiei respective.


Observaţie importantă:
Variabilele definite în sesiuni pot fi folosite într-o pagină doar după ce a fost executată comada
session_start(); Această comandă îi spune PHP-ului să verifice dacă există o sesiune şi atunci
să folosească variabilele acelei sesiuni ca variabile globale. Funcţiile session_start(), ca şi
setcookie() trebuie folosite întotdeauna chiar la începutul fişierului. Dacă se trimite altceva
către browser înainte de folosirea lor atunci vor exista erori la folosirea sesiunii sau a cookie-
urilor.

Articol scris de Curs http://php.intercer.net (preluat de la phpromania.net)

Crearea şi utilizarea funcţiilor

Procesul de executare a unei funcţii se numeşte utilizarea, apelarea sau invocarea funcţiei.
Pentru a folosi o funcţie, scrieţi numele funcţiei, urmat de o pereche de paranteze.
De exemplu, funcţia rand(), care generează un număr întreg aleator, poate fi apelată astfel:

rand();

Majoritatea funcţiilor preiau argumente, reprezentând valori de intrare care influenţează


operarea şi rezultatul funcţiei. Pentru a specifica argumente, acestea se inserează între
paranteze; dacă specificaţi mai mult de un argument, fiecare argument trebuie separat de
vecinul său prin intermediul unei virgule. Argumentul unei funţii poate fi o valoare literală, o
variabilă sau o expresie.
Unele funcţii PHP au argumente opţionale, care pot fi specificate sau omise, în conformitate cu
intenţiile dumneavoastră. De exemplu, funcţia rand() are două argumente opţionale. Primul
argument al funcţiei indică valoarea întreagă cea mai mică pe care o va returna funcţia; al
doilea argument indică valoarea cea mai mare. Dacă omiteţi ambele argumente, funcţia
returnează o valoare cuprinsă între 0 şi cel mai mare rezultat posibil. Dacă doriţi, puteţi
specifica primul argument, omiţându-l pe al doilea:

rand(100);

Astfel, funcţia este obligată să returneze o valoare cuprinsă între 100 şi cel mai mare rezultat
posibil.
Ca şi rand(), majoritatea funcţiilor returnează valori. Puteţi folosi într-o expresie valoarea
returnată de o funcţie. O situaţie foarte frecventă în care se procedează astfel o constituie
utilizarea valorii returnate de o funcţie într-o expresie de atribuire, astfel încât valoarea să fie
accesibilă în mod repetat fără a se invoca funcţia de mai multe ori.
De exemplu:

$test = rand(1, 15);

Când se produce o eroare în timpul execuţiei unei funcţii, PHP generează mesaje de eroare.
Uneori, asemenea mesaje de eroare sunt nedorite. În acest caz, puteţi suprima generarea
mesajelor de eroare prin prefixarea numelui funcţiei invocate cu ajutorul caracterului @.
De exemplu, pentru a ascunde mesajele de eroare care pot apărea în timpul execuţiei funcţiei
f(), invocaţi această funcţie astfel:

$a = @f(b);

Definirea unei funcţii

În afară de a utiliza funcţiile din biblioteca de funcţii a limbajului PHP, vă puteţi defini şi folosi
propriile funcţii. Pentru a defini o funcţie, respectaţi modelul următor:

function nume_functie(nume_argument)
{
// aici se introduce corpul functiei
}

În acest exemplu, nume_functie este numele funcţiei, iar nume_argument este numele
argumentului funcţiei. În PHP, numele funcţiilor nu prezintă sensibilitate la diferenţa între
majuscule şi minuscule; ca atare, f() şi F() reprezintă referiri la aceeaşi funcţie. Cuvântul cheie
function, numele funcţiei şi lista cu argumente alcătuiesc antetul funcţiei. Termenul de corp al
funcţiei se referă la instrucţiunile incluse între parantezele acolade care urmează după antetul
funcţiei. Înstrucţiunile din corpul funcţiei sunt executate atunci când funcţia este apelată. Dacă
doriţi să definiţi o funcţie care nu are argumente, puteţi omite nume_argument; dacă doriţi să
definiţi o funcţie cu mai multe argumente, puteţi include argumente suplimentare după
nume_argument, fiecare argment fiind separat de vecinul său prin intermediul unei virgule.
Parantezele şi numele argumentelor incluse între acestea poartă numele de lista cu
argumente. Ca exemplu, iată o funcţie care calculează aria unui dreptunghi:

function calculeaza_aria($inaltime, $latime)


{
return $inaltime * $latime;
}

Lista cu argumente a funcţiei calculeaza_aria include argumentele $latime şi $inaltime. Corpul


funcţiei este alcătuit dintr-o singură instrucţiune; cu toate acestea, corpul unei funcţii poate
conţine un număr arbitrar de instrucţiuni. Dacă doriţi ca funcţia să returneze o valoare, trebuie
să determinaţi funcţia să execute o instrucţiune return care furnizează valoarea respectivă.
Instrucţiunea return determină sistarea executării funcţiei; nu este necesar ca aceasta să fie
ultima instrucţiune fizică din corpul funcţiei. Dacă definiţi o funcţie care nu are nici o
instrucţiune return, funcţia va returna valoarea specială NULL.

Apelarea unei funcţii

O funcţie definită de utilizator poate fi apelată în acelaşi mod ca o funcţie încorporată. De


exemplu:

$aria = calculeaza_aria(2,4);

Valorile argumentelor efective 2 şi 4 le înlocuiesc pe acelea ale argumentelor formale din


corpul funcţiei calculeaza_aria, care se comportă ca şi cum ar fi fost scrisă astfel:

return 2 * 4;

Atenţie!!
În PHP3, definiţia unei funcţii trebuie să preceadă linia de program care apelează funcţia.
În PHP4, definiţia unei funcţii poate fi plasată fie anterior liniei de program care apelează
funcţia, fie după aceasta.

Terminarea execuţiei unei funcţii

O instrucţiune return determină sistarea execuţiei funcţiei care o conţine. În cazul în care doriţi
să sistaţi prelucrarea unui întreg script, puteţi invoca funcţia exit(). Iată un exemplu:

function stop()
{
exit();
}
echo "Prima linie<br>";
echo "Linia 2<br>";
stop();
echo "Linia 3<br>";

Rezultatul acestui script este afişarea primelor 2 linii, dar nu şi a liniei 3. Prin apelarea funcţiei
stop() se execută corpul funcţiei respective; la invocarea funcţiei exit(); execuţia scriptului se
încheie.

Funcţii recursive

Este posibil ca o funcţie din PHP să se auto-apeleze. O funcţie care procedează astfel se
numeşte functie recursiva. Este recomandat să nu scrieţi funcţii recursive. Cu toate acestea,
puteţi scrie accidental o asemenea funcţie şi de aceea recomand să citiţi în continuare.
Exemplu:

function recursor()
{
return recursor();
}
$a = recursor();

La invocarea funcţiei recursor(), aceasta invocă imediat funcţia recursor(), care se auto-invoca
instantaneu. Astfel, funcţia recursor() este invocată în mod repetat, până când se produce o
eroare cunoscută sub numele de depăşire în sens pozitiv a stivei (stack overflow). Dacă
programul dvs. se încheie cu o depăşire în sens pozitiv a stivei, o posibilă cauză poate consta
într-o recursie incorectă.

Definirea argumentelor prestabilite

PHP4 va permite să definiţi funcţii cu argumente prestabilite. Dacă invocaţi o funcţie care are
un argument prestabilit, dar nu furnizaţi nici o valoare pentru argumentul respectiv,
argumentul ia o valoare prestabilită specificată. Exemplu:

function impozit_vanzari($cantitate, $rata=0.07)


{
echo "Cantitate = $cantitate<br>";
echo "Rata = $rata";
return $suma * $rata;
}

$cumparaturi = 123.45
echo "Cumparaturi = $cumparaturi<br>";
$impozit = impozit_vanzari($cumparaturi, 0.08);
echo "Impozit = $impozit<br>";

$cumparaturi = 123.45;
echo "Cumparaturi = $cumparaturi<br>";
$impozit = impozit_vanzari($cumparaturi);
echo "Impozit = $impozit<br>";

Funcţia impozit_vanzari preia două argumente: un argument obligatoriu, denumit $cantitate,


şi un argument prestabilit, denumit $rata. Dacă apelaţi funcţia şi furnizaţi un singur argument,
valoarea argumentului respectiv se consideră ca fiind valoarea argumentului $cantitate, iar
valoarea 0.07 se foloseste ca valoare a argumentului $rata. Astfel, la prima invocare a
funcţiei, $rata are valoarea 0.08, specificată drept al doilea argument al funcţiei. Cu toate
acestea, la a doua invocare a funcţiei, $rata are valoarea 0.07, deoarece este specificată
valoarea unui singur argument.
Este posibil ca o funcţie să aibă mai multe argumente prestabilite, dar rezultatul este deseori
confuz. Exemplu:

function test($valoare1 = 1, $valoare2 = 2)

Care credeţi că va fi rezultatul dacă este invocată următoarea funcţie?

x=test(3);

Cu alte cuvinte, argumentul trebuie folosit ca valoare a variabilei $valoare1 sau ca valoare a
variabilei $valoare2? PHP are reguli care controlează asemenea situaţii, dar regulile respective
pot fi derutante. Ca atare, cel mai bine este să evitaţi problema prin definirea unui singur
argument prestabilit şi prin poziţionarea unui argument prestabilit pe ultima poziţie în lista cu
argumente.

Utilizarea fişierelor incluse

Funcţiile PHP vă permit să obţineţi accesul la programe PHP scrise anterior. Una din variante o
constituie instrucţiunea require, care are următoarea formă:

require(numele_fisierului);

De exemplu dorim să accesăm datele din fişierul numit valori.inc. Pentru aceasta folosim
următoarea comandă:

require("valori.inc");

Când este încărcat un script PHP care conţine o instrucţiune require, conţinutul fişierului
specificat - cunoscut sub numele de fişier de includere - este inserat în script, înlocuind
instrucţiunea require. Dacă fişierul de includere conţine linii de program PHP, trebuie să
includă etichetele <?php şi ?>, amplasate în locaţiile adecvate.
Deşi se obişnuieşte ca un fişier de includere să primească extensia de fişier inc, nu este
obligatoriu să procedaţi astfel. Unii programatori PHP preferă să folosească extensia de fişier
php pentru toate fişierele pe care le creează.
Instrucţiunea require vă poate scuti de un mare volum de muncă. De exemplu, să
presupunem ca scrieţi o aplicaţie PHP care este alcătuită din mai multe scripturi, iar fiecare
script afişează o pagina HTML care conţine informaţii standard în partea de sus a paginii.
Puteţi crea un fişier script special, denumit antet.inc, care conţine doar partea de sus a pagini
(pentru exemplificare citiţi şi vedeţi scriptul de la articolul "Contruieste un site cu php") Prin
inserţia instrucţiunii:

require ("antet.inc");

la începutul fiecărui script, determinaţi programul PHP să includă conţinutul acelui fişier ca şi
cum conţinutul respectiv ar face parte din acel script. Acest procedeu poate simplifica
intreţinerea programului, deoarece informaţiile standard pot fi rezidente într-un singur fişier,
ceea ce le face uşor de localizat şi revizuit.

Atentie!!!
Instrucţiunea require este prelucrată la încărcarea scriptului PHP asociat, înaintea legrii
valorilor la variabilele corespunzătoare. În consecinţă, nu puteţi folosi o expresie pentru a
specifica numele fişierului care urmează a fi inclus de către o instrucţiune require. Totuşi,
puteţi folosi instrucţiunea include, care este o instrucţiune executabilă ce determină evaluarea
scriptului PHP dintr-un fişier specificat. De exemplu, instrucţiunea include din următorul
program evaluează fişierul pagina1.inc

$fisier = 1;
include ("pagina".$fisier.".inc");

La evaluarea fişierului de includere, instrucţiunile PHP pe care le conţine sunt executate ca şi


cum ar fi apărut în textul scriptului apelant.
Instrucţiunea corelată require_once asigură faptul că fişierul specificat este inclus o singură
dată într-un script dat. În cazul în care creaţi fişiere de includere care folosesc instrucţiunea
require pentru a include conţinutul altor fişiere de includere, puteţi găsi instrucţiunea
require_once utilă.

Funcţii PHP pentru expresii regulate

Funcţie Descriere
ereg execută o identificare cu o expresie regulată
ereg_replace înlocuieşte un sub-şir care corespunde unei expresii regulate
execută o identificare cu o expresie regulată insensibilă la diferenţa între
eregi
majuscule şi minuscule
înlocuieşte un sub-şir care corespunde unei expresii regulate insensibile la
eregi_replace
diferenţa între majuscule şi minuscule
split divide un şir într-un tablou folosind o expresie regulată
divide un şir într-un tablou folosind o expresie regulată (insensibilă la diferenţa
spliti
între majuscule şi minuscule)
crează o expresie regulată insensibilă la diferenţa între majuscule şi minuscule
sql_regcase
dintr-un şir care conţine o expresie regulată.

Sintaxa:

function ereg

Semnificaţia caracterelor ce se pot afla în şablon:

^ - Început de şir
$ - Sfârşit de şir
* - zero sau mai multe caractere
+ - unul sau mai multe caractere
? - zero sau un character
{x,y}, unde x şi y sunt doi întregi reprezentând limita inferioară şi superioară a numărului de
caractere necesare. x trebuie întotdeauna definit.
( ) - Secvenţe de caractere
| - operatorul SI (OR)
. (punct) - reprezintă orice caracter
[ ] - orice caracter din intervalul specificat
^ în [ ] - orice altceva decât caracterele din interval
^.[$()|*+?{\ - nu trebuiesc precedate de backslash (\) în expresii regulate dacă sunt în
interiorul parantezelor pătrate [ ]

Exemple:
ab* - "a","ab","abb","abbb", etc.
ab+ - "ab","abb","abbb", etc.
ab? - doar "a","ab"
ab{2} - doar "abb"
ab{2,} - "abb","abbb", "abbbb", etc.
ab{2,4} - doar "abb","abbb", "abbbb"
a(bc)* - "abc","abcbc","abcbcbc", etc.
a(bc){1,3} - doar "abc","abcbc","abcbcbc"
(a|b) - "a" sau "b"
hi|hello - "hi" sau "hello"
(b|cd)ef - "bef" sau "cdef"
"^.{3}$" - orice şir cu exact 3 caractere
[_a-zA-Z] - underscore sau orice literă din alfabetul latin
[^a-zA-Z] - orice altceva înafară de litere
[1-6] - număr cuprins între 1 şi 6
[c-h] - minuscul cuprins între c şi h
[D-M] - majusculă cuprinsa între D şi M

Un exemplu mai complicat:

^.{2}[a-z]{1,2}_?[0-9]*([1-6]|[a-f])[^1-9]{2}a+$

Exemplul de mai sus se traduce prin:

Un şir care începe cu oricare 2 caractere... ^.{2}


urmat de 1 sau 2 litere minuscule... [a-z]{1,2}
urmat de un underscore opţional... _?
urmat de zero sau mai multe cifre... [0-9]
urmat de fie un număr între 1 şi 6 sau o literă minusculă cuprinsă între a şi f... *([1-6]|[a-f])
urmat de 2 caractere care nu sunt cifre... [^1-9]{2}
urmat de unul sau mai multe litere "a" la sfârşitul şirului... a+$

Echivalenţe:

* - {0,}
+ - {1,}
? - {0,1}

Forma simplă a funcţiei ereg() preia două argumente: un şir care conţine o expresie regulată
şi un şir subiect. Funcţia returnează true dacă expresia regulată corespunde unui sub-şir al
şirului subiect; în caz contrar, returnează false.
Iată un exemplu mai simplu:

$model="[sml]at";
$subiect="La noi in sat";
$rezultat=ereg($model, $subiect);

Variabila $rezultat primeşte valoarea true, deoarece şirul subiect conţine sub-şirul "sat", care
corespunde expresiei regulate.
Forma mai complexă a funcţiei ereg() include un al treilea argument, un tablou care primeşte
sub-şiruri ce corespund porţiunilor scrise între paranteze ale modelului. În scriptul de mai jos,
este reprezentat modul de utilizare a acestei forme a funcţiei ereg(), pe care o foloseşte
pentru a determina dacă un şir conţine o adresă de e-mail corect formată.
Cod:

// formularul html
<form method="post" action="script_2.php">
Sir:
<input type="text" name="sir">
<br>
Expresie regulata:
<input type="text" size=64 name="model"
value="^([_a-zA-Z0-9-]+)@([a-zA-Z0-9-]+(.[a-zA-Z0-9-]+)*)$">
<br>
<input type="submit">
</form>

<?php
// preluare valori din formular
$sir = $_POST['sir'];
$model = $_POST['model'];
// Afisare date
echo "<br>Sir: ".$sir;
echo "<br>Expresie regulata: ".$model;
// verificare
if (get_magic_quotes_gpc())
{
echo "<br>Eliminarea ghilimelelor magice";
$sir = stripslashes($sir);
$model = stripslashes($model);
echo "<br>Sir: ".$sir;
echo "<br>Expresie regulata: ".$model;
}
$gasit = ereg($model, $sir, $echivalente);
echo "<br>";
if ($gasit)
{
echo "<br>Valabil: true";
echo "<br>Componente: ";
for ($i=0;$i<count($echivalente);$i++)
{
echo "<br>$echivalente[$i]";
}
}
else
echo "<br>Valabil: false";
?>

Funcţia PHP sscanf(), adăugată în versiunea PHP 4.01, este complementară funcţiei printf().
Dacă funcţia printf() generează date de ieşire formatate, funcţia sscanf() citeşte un şir, îl
interpretează prin referirea la un şir de formatare şi stabileşte valorile variabilelor specificate
în funcţie de conţinutul şirului.
Exemplu:

Cod:

<?php
$subiect = "01, 31, 2005";
$n = sscanf($subiect, "%d, %d, %d", &$luna, &$zi, &$an);
echo "<br>Au fost gasite $n valori:";
echo "<br>luna=$luna";
echo "<br>zi=$zi";
echo "<br>an=$an";
?>

Datele de ieşire ale acestui exemplu sunt:

Citat:

Au fost gasite 3 valori:


luna=1
zi=31
an=2005

Utilizarea referinţelor în PHP

În mod prestabilit, argumentele transferate unei funcţii PHP sunt transmise prin valoare, ceea
ce înseamnă că valorile argumentelor sunt copiate şi funcţiile utilizează copii ale valorilor
argumentelor lor, nu argumentele în sine. Ca o consecinţă, o funcţie PHP nu poate modifica
valorile argumentelor sale. Acest fapt este în general util, deoarece astfel funcţiile devin mai
uşor de înţeles dacă se limitează la a returna o valoare, fără a modifica valori.
Totuşi, puteţi stabili ca o funcţie să aibă posibilitatea de a modifica valoarea unui argument,
specificând ca argumentul să fie transferat prin referinţă. Când un argument este transferat
prin referinţă, valoarea sa nu este copiată; funcţia lucrează cu valoarea argumentului şi are
libertatea de a modifica acea valoare. Pentru a specifica faptul că un argument urmează a fi
transferat prin referinţă, argumentul va fi prefixat cu un caracter ampersand (&) (mai
cunoscut ca AND). Puteţi ataşa acest prefix la argument în antetul funcţiei sau în apelul la
funcţie. Iată un exemplu care prezintă apelul prin valoare şi apelul prin referinţă:

Cod:

<?php
function prin_valoare($x)
{
$x = 1;
}
function prin_referinta(&$x)
{
$x = 1;
}
$y = 0;
prin_valoare($y);
echo "<br>\$y=$y";
$y = 0;
prin_valoare(&$y);
echo "<br>\$y=$y";
$y=0;
prin referinta($y);
echo "<br>\$y=$y;
?>

Dacă rulaţi acest script, veţi obţine următoarele date de ieşire:

Citat:

$y=0
$y=1
$y=1

Reţineţi că scriptul conţine două funcţii, şi anume prin_valoare() şi prin_referinta(). Fiecare


funcţie preia un singur argument, denumit $x. Antetul funcţiei prin_referinta() specifică faptul
că argumentul sau este transferat prin referinţă; argumentul funcţiei prin_valoare() este
transferat prin valoare, în conformitate cu practica prestabilită folosită în limbajul PHP. Fiecare
funcţie încearcă să modifice valoarea argumentului său.
Primul paragraf al programului invocă funcţia prin_valoare(), transferând argumentul prin
valoare. În consecinţă, funcţia lucrează cu o copie a argumentului său, iar valoarea variabilei
$y nu se modifică.
Cel de-al doilea paragraf al programului invocă de asemenea funcţia prin_valoare(); cu toate
acestea, foloseşte un caracter ampersand pentru a determina transferul prin referinţă al valorii
variabilei $y. În consecinţă, funcţia modifica valoarea argumentului său, care se transforma
din 0 în 1.
Cel de-al treilea paragraf al programului invocă funcţia prin_referinta(). Antetul funcţiei
respective foloseşte un caracter ampersand pentru a specifica faptul că valoarea argumentului
sau este transferată prin referinţă. În consecinţă, funcţia modifică valoarea argumentului sau,
care se transformă din 0 în 1.
Prin utilizarea referinţelor se evită suprasarcina de copiere a valorilor argumentelor şi implicit
se obţine o viteză mai mare de execuţie a programului. Cu toate acestea, programele devin
astfel mai dificil de înţeles, iar referinţele sau apelurile prin referinţă pot cauza erori de
program. Cel mai indicat este să evitaţi referinţele, acolo unde este posibil, şi să definiţi funcţii
care returnează valori, şi nu funcţii care modifică valorile propriilor argumente.

Lucrul cu funcţii listă

În afară de modalităţile de parcurgere iterativă a tablourilor, PHP oferă numeroase funcţii care
permit traversarea tablourilor, deplasându-vă înainte sau înapoi, după dorinţă. Prima dintre
aceste funcţii este current(), care returnează valoarea curentă a tabloului. Funcţia current()
foloseşte un pointer intern de tablou pe care PHP îl creează pentru fiecare tablou. Când creaţi
un tablou, pointerul intern de tablou este configurat astfel încât să facă referire la primul
element al tabloului. Funcţiile next() şi prev() modifică pointerul intern al tabloului şi se pot
folosi alături de funcţia current() pentru a parcurge un tablou. Funcţia next(), aşa cum îi arată
şi numele, modifică pointerul intern al tabloului astfel încât acesta să facă referire la următorul
element, în timp ce funcţia prev() modifică pointerul intern al tabloului astfel încât acesta să
facă referire la elementul anterior. Iată un exemplu care prezintă modul de operare al celor 3
funcţii:

Cod:
<?php
$test = array(10=>"aaa", 20 => "bbb", 21 => "ccc");
$curent = current($test);
echo "<br>functia current() a returnat $curent";
$urmator = next($test);
echo "<br>functia next() a returnat $urmator";
$urmator = next($test);
echo "<br>functia next() a returnat $urmator";
$anterior = prev($test);
echo "<br>functia prev() a returnat $anterior";
?>

Datele de ieşire sunt:

Citat:

functia current() a returnat aaa


functia next() a returnat bbb
functia next() a returnat ccc
functia prev() a returnat bbb

Funcţia key()

Funcţia key() este corelată cu funcţia current(). Dacă funcţia current() returnează valoarea
asociată elementului curent, funcţia key() returnează cheia asociată elementului curent.
Exemplu:

Cod:

<?php
$test = array(10=>"aaa", 20 => "bbb", 21 => "ccc");
$curent = current($test);
$cheie = key($test);
echo "<br>functia current() a returnat $curent";
echo "<br>functia key() a returnat $cheie";
?>

Datele de ieşire sunt:

Citat:

functia current() a returnat aaa


functia key() a returnat 10

Funcţia each()

O altă funcţie utilă în parcurgerea tablourilor este each(). Funcţia each() returnează
următoarea pereche cheie-valoare din tabloul specificat. Perechea cheie-valoare este returnată
sub forma unui tablou asociativ cu patru elemente, după cum urmează:

Cheie Valoare
0 Componenta cheie a perechii cheie-valoare curentă
1 Componenta valoare a perechii cheie-valoare curentă.
"key" Componenta cheie a perechii cheie-valoare curentă
"value" Componenta valoare a perechii cheie-valoare curentă.

Observaţi că puteţi folosi valoarea cheie "0" sau "cheie" pentru a obţine accesul la componenta
cheie a perechii cheie-valoare; similar, puteţi folosi valoarea cheie "1" sau "valoare" pentru a
obţine accesul la componenta valoare a perechii cheie-valoare. Iată mai jos un exemplu al
funcţiei each():

Cod:

<?php
$test = array(10=>"aaa", 20 => "bbb", 21 => "ccc");
$fiecare = each($test);
$zero = $each[0];
$unu = $each[1];
$cheie = $each['key'];
$valoare = $each['value'];
echo "<br>zero = $zero";
echo "<br>unu = $unu";
echo "<br>cheie = $cheie";
echo "<br>valoare = $valoare";
?>

Datele de ieşire sunt:

Citat:

zero = 10
unu = aaa
cheie = 10
valoare = aaa

Funcţia list()

O altă funcţie utilă în lucrul cu tablouri este funcţia list(), care vă permite să atribuiţi valori la
numeroase variabile în cadrul unei instrucţiuni. Funcţia list() este deseori folosită cu funcţia
each(), deoarece funcţia list() facilitează accesul separat la cheia şi la valoarea returnate de
funcţia each(). Forma generala de utilizare a funcţiei list() este:

list($var1, $var2, ..., $varn) = valoare_tablou;

Fiecare dintre variabilele specificate, de la $var1 la $varn, primeşte o valoare din tabloul
valoare_tablou. Într-un fel, funcţia list() este opusă funcţiei array(), deoarece funcţia list()
împarte un tablou într-o serie de valoari scalare, în timp ce funcţia array() construieşte un
tablou dintr-o serie de valori scalare. Iată un exemplu de utilizare a funcţiei list():

Cod:

<?php
$test = array(10=>"aaa", 20 => "bbb", 21 => "ccc");
list($cheie, $valoare) = each($test);
echo "<br>cheie = $cheie, valoare = $valoare";
$urmator = $next($test);
echo "<br>urmator = $urmator";
?>

Datele de ieşire sunt:

Citat:

cheie = 10, valoare = aaa


urmator = bbb

PHP conţine peste 40 de funcţii pentru lucrul cu tablourile. De exemplu, funcţia array_search()
facilitează căutarea într-un tablou.

Sortarea tablourilor

Sortarea reprezintă o altă operaţie frecvent aplicată tablourilor. PHP furnizează o suită de
funcţii care facilitează sortarea unui tablou. De exemplu, un tablou poate fi creat după cum
urmează:

$limbaje = array(1=>"Perl", 2=>"PHP", 4=>"Python");

Apoi, doriţi să sortaţi tabloul în funcţie de numele limbajului de programare. Pentru aceasta,
pur şi simplu invocaţi funcţia sort():

sort($limbaje);

După sortare, conţinutul tabloului apare aşa:

0 => PHP
1 => Perl
2 => Python

Observaţi că secvenţa de sortare sau secvenţa de aranjare (cum este numită uneori) este
sensibilă la diferenţa dintre majuscule şi minuscule. Deoarece litera H mare este sortata
anterior literei e mic, PHP apare înainte de Python în datele de ieşire sortate. Tabelul de mai
jos prezintă pe scurt funcţiile de sortare ale limbajului PHP, inclusiv rezultatul aplicării fiecărei
funcţii tabloului folosit în exemplul anterior.

Operaţie Funcţie Rezultat


0 => PHP
1 => Perl
Sortarea unui tablou în funcţie de valoare sort()
2 =>
Python
2 => PHP
1 => Perl
Sortarea unui tablou asociativ în funcţie de valoare asort()
4 =>
Python
0 =>
Python
Sortarea unui tablou după valoare, în ordine descendentă rsort()
1 => Perl
2 => PHP
4 =>
Python
Sortarea unui tablou asociativ după valoare, în ordine descendentă Arsort()
1 => Perl
2 => PHP
1 => Perl
2 => PHP
Sortarea unui tablou sau a unui tablou asociativ în funcţie de cheie ksort()
4 =>
Python
4 =>
Sortarea unui tablou sau a unui tablou asociativ în funcţie de cheie, în Python
Krsort()
ordine descendentă 2 => PHP
1 => Perl

Dacă doriţi să efectuaţi o căutare fără sensibilitate la diferenţa între majuscule şi minuscule, o
modalitate ar fi utilizarea funcţiei natcasesort(), care sortează un tablou folosind o "ordine
naturală", care nu este sensibilă la diferenţa între majuscule şi minuscule. O altă modalitate
constă în a utiliza funcţia usort() sau una dintre funcţiile sale conexe, în speţă uksort() şi
uasort(). Aceste funcţii vă permit să definiţi o secvenţă de aranjare personalizată, pe care o
specificaţi prin desemnarea unei funcţii care compară valorile în conformitate cu secvenţa de
aranjare. Funcţia usort() sortează valorile din tablou şi returnează un tablou secvenţial; funcţia
uksort() sortează cheile tabloului, iar funcţia uasort() sortează un tablou asociativ. De
exemplu, următoarele instrucţiuni creează un tablou şi îl sortează într-o manieră insensibilă la
diferenţa între majuscule şi minuscule:

$limbaje = array("Perl", "PHP", "Python");


usort($limbaje, "strcmpcase");

Funcţia strcmpcase() este o funcţie din biblioteca PHP care compară două şiruri fără a ţine
cont de mărimea literelor (majuscule sau minuscule). Funcţia returnează o valoare negativă
dacă primul şir este mai mic decât al doilea, zero dacă şirurile sunt identice, respectiv o
valoare pozitivă dacă primul şir este mai mare decât ala doilea. Puteţi implementa o secvenţă
de aranjare personalizată scriind propria dumneavoastră funcţie şi specificând numele acesteia
ca argument al funcţiei usort() sau al uneia din funcţiile sale conexe. Pur şi simplu scrieţi o
funcţie care preia două argumente şir şi returnează -1, 0 sau =1, în funcţie de rezultatul
comparaţiei între valorile şir.

Interoperabilitate PHP-Java

Un aspect important al limbajului PHP este acela că realizatorii de pagini web pot folosi în
script-uri o mare parte a facilităţilor oferite de limbajul Java prin intermediul unei biblioteci de
funcţii numită php_java. Pentru a utiliza facilităţile oferite de limbajul Java în cadrul script-
urilor PHP este necesară o platformă Java care poate fi găsită la adresa http://java.sun.com/
şi pachetul php_java care conţine două fişiere: biblioteca php_java.dll (pe platforme Windows)
şi pachetul php_java.jar care conţine o clasă care se ocupă de încărcarea celor folosite în
script-urile PHP. Această clasă este utilizată de către PHP pentru a executa funcţii din clase
Java şi pentru a rula clase noi. Limbajul PHP poate utiliza cel puţin următoarele versiuni de
Java: 1.2.x, 1.3.x, 1.4.2. Eu am testat cu Java 2 SDK, Standard Edition 1.4.2_04
Cele două fişiere ale pachetului php_java pot fi găsite în versiunea integrală a limbajului PHP
(în directorul php/extensions/ de pe hdd)

Instalare:

Pentru a utiliza această facilitate trebuie instalată platforma Java şi cele două fişiere ale
pachetului php_java trebuie copiate în directorul extensions care poate fi găsit în directorul în
care a fost instalat limbajul PHP.

Configurare:

Pentru a putea accesa clasele Java în cadrul script-urilor PHP trebuie configurată biblioteca
php_java. Configurarea se realizează prin intermediul fişierului php.ini localizat pe platforme
Windows în directorul sistemului de operare (în directorul Windows de obicei). În acest fişier
trebuie adăugată valoarea php_java.dll variabilei extension. Există mai multe posibilităţi
pentru a face acest lucru. Una dintre ele este eliminarea caracterului ";" de la începutul liniei:

;extension=php_java.dll

dacă o astfel de linie există în fişierul php.ini, iar o altă varianta este adăugarea liniei:

extension=php_java.dll

la sfârşitul fişierului. În continuare trebuie setate valori pentru următoarele patru variabile:

- java.class.path - reprezintă o listă de directoare, arhive zip sau alte tipuri de pachete
suportate de limbajul java (jar, ejb, war etc.) separate între ele prin caracterul ";" această
listă ar trebui să conţină calea către pachetul php_java.jar, altfel nu se pot utiliza clase Java;
- java.home - reprezintă numele directorului în care este instalată platforma Java;
- java.library - reprezintă calea către maşina virtuală Java care se doreşte a fi încărcată;
- java.library.path - reprezinta o listă de directoare în care pot fi găsite anumite pachete de
clase Java, în plus decât cele cu care este configurată platforma Java; directoarele din această
listă sunt separate între ele prin caracterul ";"
Valorile pentru aceste variabile se setează în fişierul php.ini în cadrul sectiunii [Java].
(in cazul meu am setat astfel valorile:

[Java]
java.class.path=c:\php\extensions\php_java.jar
java.home=c:\j2sdk1.4.2_04
java.library=C:\j2sdk1.4.2_04\jre\bin\server\jvm.dll
java.library.path=c:\php\extensions\

Cu aceste setări făcute, maşina virtuală Java poate fi încărcată şi clasele pot fi utilizate în
cadrul script-urilor PHP.

Utilizare

Clasele Java se instanţiaza în PHP folosind constructorul clasei Java explicat mai jos. Metodele
şi proprietăţile statice sau dinamice ale claselor instanţiate se accesează folosind operatorul de
indirectare "->". De exemplu, dacă avem o variabilă $clasa căreia i-a fost ataşată ca valoare o
clasă Java, atunci pentru a afişa reprezentarea textuală a acesteia trebuie să utilizăm metoda
toString() (metodă specifică tuturor claselor Java) vom utiliza o instrucţiune de forma:

echo $clasa->toString();

Clasa Java

Această clasă se foloseşte pentru a rula o clasă a limbajului Java şi reprezintă, de fapt, o clasă
derivată din clasa java.lang.Object a limbajului Java. Constructorul acesteia primeşte mai
mulţi parametrii, dintre care primul este un şir de caractere care reprezintă numele clasei Java
care se instanţiază, iar restul de parametrii reprezintă parametrii pentru care se va apela
constructorul clasei respective. În cazul în care nu se reuşeşte rularea unei clase a limbajului
Java este generată o excepţie Java, iar pentru a verifica dacă a fost generată o astfel de
excepţie se foloseşte funcţia java_last_exception_get care este prezentată mai jos. În
continuare este un exemplu de utilizare a clasei Java, cu care puteţi verifica dacă aţi instalat şi
configurat corect clasele Java.

Cod:

<?php
$system = new Java("java.lang.System");
echo "Versiunea Java este: ";
echo $system -> getProperty("java.version")."<br>";
echo "Sistem de operare: ";
echo $system -> getProperty("os.name")."<br>";
echo "Versiunea: ";
echo $system -> getProperty("os.version")."<br>";
?>

Funcţia java_last_exception_get

Această funcţie returnează o clasă Java derivată din clasa java.lang.Exception care reprezintă
ultima exceptie care a fost generată sau valoarea logică false dacă nu a fost generată nici o
excepţie de la începutul execuţiei script-ului sau de la ultimul apel al funcţiei
java_last_exception_clear. Funcţia java_last_exception_get nu are parametri.

Cod:

<form action = "test.php" metod=post>


Introduceti un sir de caractere:
<input type = text name = "sir">
<input type = submit value = "verificare">
</form>

<?php
if (isset($_POST['sir']))
{
echo "<hr>";
$int = new Java ("java.lang.Integer");
$sir = $_POST['sir'];
$i = $int->parseInt($sir);
$error = java_last_exception_get();
if ($error)
{
echo "Sirul \"".$sir."\" nu este un numar intreg.";
java_last_exception_clear();
}
else
{
echo "Sirul \"".$i."\" este un numar intreg.";
}
}
?>
Funcţia java_last_exception_clear

Această funcţie nu are nici un parametru şi nu returnează nici o valoare, în schimb efectul
aplicării ei este acela că este anulată ultima excepţie Java care a fost generată de către
maşina virtuală Java în timpul executării de cod. Apelul acestei funcţii este necesar, deoarece,
în cazul în care a fost generată o excepţie şi nu a fost tratată, se poate întâmpla ca după
apelul unei funcţii să tratam excepţia greşită.

Importanţa librăriei php_java

Pentru programatorii de pagini web care cunosc atât limbajul Java, cât şi limbajul PHP,
prezenţa acestei librării are o foarte mare importanţă. Funcţiile scrise în Java sunt executate
de către procesor mult mai repede decât cele scrise în PHP, iar utilizarea codului Java oferă o
mai mare siguranţă creatorilor de pagini web dinamice.

Transmiterea mesajelor prin e-mail folosind PHP şi PEAR

Limbajul PHP are integrat un client pentru protocolul SMTP (Simple Mail Transfer Protocol) şi
un set de funcţii necesare pentru prelucrarea mesajelor primite de către un server de mail în
vederea utilizării datelor conţinute. Cu ajutorul acestor funcţii se pot realiza aplicaţii
interesante cum sunt administrarea listelor de discuţii, transmiterea unor ştiri tuturor
utilizatorilor înscrişi pe o anumită listă, difuzarea de noutăţi cu privire la diverse apariţii etc.

Despre configurarea php

Pentru a putea utiliza funcţiile oferite de limbajul PHP pentru a trimite mesaje de poştă
electronică, pe sistemele de operare din familia Windows sau *NIX este necesar să se seteze
corect interpretorul PHP prin intermediul fişierului php.ini localizat în directorul în care este
instalat sistemul de operare, respectiv în directorul /etc pe sistemele *NIX.
Funcţia mail() trimite mesajele prin intermediul unui server SMTP (Simple Mail Transfer
Protocol) care poate fi găzduit de server-ul pe care este instalat interpretorul PHP sau de către
un alt server accesibil interpretorului.
În fisierul php.ini trebuie adăugate variabilele având numele SMTP, smtp_port, sendmail_from
si sendmail_path, dacă acestea nu există, sau trebuie modificate valorile acestora.
- Variabila SMTP reprezintă ip-ul sau adresa server-ului de mesaje electronice. Dacă această
variabilă lipseste, atunci, pentru sistemele de operare din familia Windows se va încerca
folosirea sistemului pe care se află instalat interpretorul pentru a transmite mesaje
electronice, iar pentru sistemele de operare din familia *NIX se vor folosi setările implicite ale
sistemului.
- Variabila smtp_port reprezintă portul pe care răspunde server-ul de mesaje electronice şi are
valoarea implicită 25, pentru sistemele de operare din familia Windows sau setarea implicită a
sistemului, pentru sistemele de operare din familia *NIX.
- Variabila sendmail_from reprezintă adresa de mail a expeditorului. Valoarea acestei variabile
este folosită numai pentru sistemele de operare din familia Windows, iar pe sistemele de
operare din familia *NIX se foloseşte setarea implicită a sistemului.
- Variabila sendmail_path reprezintă calea către aplicaţia care se ocupă de transmiterea
mesajelor pe sistemele de operare din familia *NIX.

Funcţia mail

Această funcţie se foloseşte pentru a transmite un mesaj de poştă electronică la una sau mai
multe căsuţe poştale. Funcţia mail are cinci parametri de tip şir de caractere, dintre care
ultimii doi sunt opţionali.

- Primul parametru reprezintă o listă a tuturor căsuţelor poştale, separate prin caracterul ","
care reprezintă destinatarii mesajului ce se va transmite. O căsuţă poştală din lista
destinatarilor poate fi specificată utilizând unul dintre următoarele formate: "nume_destinatar
<adresa_email>" sau "adresa_email", unde nume_destinatar reprezintă numele proprietarului
căsutei poştale adresa_mail şi poate fi şirul vid, iar adresa_email reprezintă adresa căsuţei
poştale şi are formatul "nume_utilizator@domeniu", unde domeniu reprezintă numele server-
ului care găzduieşte căsuţa poştala a utilizatorului nume_utilizator. În cazul utilizării primului
format, pentru a specifica un destinatar pentru mesajul care se va trimite, este obligatorie
folosirea caracterelor "<" şi ">" înainte, respectiv după câmpul adresa_email, iar dacă
valoarea câmpului nume_destinatar conţine caracterul spaţiu este necesară utilizarea
caracterului " înaintea acestuia şi după acesta. De exemplu, adresa "Alex <php4@as.ro>" este
o adresă validă pentru un mesaj de poştă electronică.

- Al doilea parametru reprezintă subiectul mesajului care se va transmite.

- Cel de-al treilea parametru reprezintă conţinutul mesajului ce va fi transmis. Pentru a putea
trimite mesaje care conţin ataşamente sau care au un tip de continut altul decat text (exemplu
pagini HTML) este necesar ca valoarea acestui parametru sa fie în format MIME (Multi-porpose
Internet Mail Extension).

- Cel de-al patrulea parametru reprezintă o listă de linii de antet suplimentare, separate prin
şirul de caractere "\r\n" (sfârşit de linie), pentru mesajul care va fi transmis.

- Ultimul parametru reprezintă o listă de opţiuni suplimentare pentru aplicaţia care va fi


folosită pentru a efectua trimiterea mesajului şi este dependent de aceasta.

Funcţia returnează valoarea logică TRUE dacă s-a reuşit trimiterea mesajului şi valoarea logică
FALSE în caz contrar. Un exemplu este prezentat mai jos:

mail('"Alex" <php4@as.ro>', "Mesaj de test", "Acesta este un mesaj de test") or die("Nu se


poate trimite mesajul");

PEAR

PEAR (PHP Extension and Application Repository) reprezintă un proiect demarat de echipa de
programatori PHP. Scopul acestui proiect este de a oferi o bibliotecă structurată de clase
open-source tuturor utilizatorilor limbajului PHP. Această bibliotecă oferă, printre multe altele,
un set de clase care pot fi folosite pentru a putea transmite mesaje electronice care să conţină
atasamente şi al căror conţinut poate fi în format HTML în loc de text. Acest set de clase poate
fi descărcat de la adresa http://pear.php.net/package/Mail_Mime Pentru a putea folosi setul
de clase Mail_Mime trebuie instalat mai întâi pachetul PEAR de bază care poate fi găsit la
adresa http://pear.php.net/ În continuare este prezentată clasa Mail_Mime, cea mai
importantă clasă necesară pentru a codifica în format MIME astfel de mesaje.

Clasa Mail_Mime

Această clasă se foloseşte pentru a construi mesaje electronice în format MIME. Clasa
Mail_Mime are şase funcţii membru a căror funcţionalitate este prezentată în continuare şi un
constructor. Constructorul Mail_Mime crează o instanţă a clasei şi are un singur parametru de
tip şir de caractere, care este opţional. Acest parametru reprezintă terminatorul de linie care
va fi utilizat de către clasa pentru a încheia fiecare linie din mesaj şi are valoarea implicită
"\r\n".
Funcţia Mail_Mime::setTxtBody

Această funcţie setează conţinutul text al unui mesaj pentru ca acesta să poată fi vizualizat în
cadrul unui client de mail de tip text cum este cazul aplicaţiei mail prezentă pe sistemele de
operare din familia *NIX. Această funcţie are doi parametri.

- Primul parametru este de tip şir de caractere şi reprezintă conţinutul mesajului sau numele
fişierului care conţine mesajul în format text.
- Cel de-al doilea parametru este de tip logic şi este opţional. Dacă acest parametru are
valoarea TRUE, atunci se va considera că primul parametru reprezintă numele unui fişier, iar
dacă are valoarea FALSE, atunci se va considera că primul parametru reprezintă conţinutul
mesajului. Valoarea implicită a acestui parametru este FALSE. Funcţia setTxtBody returnează
valoarea logică TRUE dacă a reuşit să adauge la mesaj conţinutul şi o instanţă a clasei
PEAR_Error în caz contrar.

Funcţia Mail_Mime::setHTMLBody

Această funcţie setează conţinutul HTML al unui mesaj pentru ca acesta să poată fi vizualizat
în cadrul unui client de mail de tip HTML cum este cazul aplicaţiei OUTLOOK prezentă pe
sistemele de operare din familia Windows. Această funcţie are doi parametri.
- Primul parametru este de tip şir de caractere şi reprezintă conţinutul mesajului sau numele
fişierului care conţine mesajul în format HTML.
- Cel de-al doilea parametru este de tip logic şi este opţional. Dacă acest parametru are
valoarea TRUE, atunci se va considera că primul parametru reprezintă numele unui fişier, iar
dacă are valoarea FALSE, atunci se va considera că primul parametru reprezintă conţinutul
mesajului. Valoarea implicită este FALSE. Funcţia setHTMLBody returnează valoarea logică
TRUE dacă a reuşit să adauge la mesaj conţinutul şi o instanţă a clasei PEAR_Error în caz
contrar.

Funcţia Mail_Mime::addHTMLImage

Această funcţie se foloseşte pentru a adăuga o imagine în corpul unui mesaj, în cazul în care
conţinutul în format HTML utilizează imagini integrate. Această funcţie are patru parametri.
- Primul parametru este de tip şir de caractere şi reprezintă conţinutul imagini sau numele
fişierului care conţine imaginea.
- Al doilea parametru este de tip şir de caractere, este opţional şi reprezintă tipul conţinutului.
Acest parametru are valoarea implicită "application/octet-stream". De exemplu, dacă imaginea
este de tip GIF, acest parametru poate primi valoarea "image/gif".
- Cel de-al treilea parametru este de tip şir de caractere, este opţional şi reprezintă numele
care va fi dat imaginii. În cazul în care primul parametru conţine imaginea, atunci este necesar
ca acest parametru să apară, în caz contrar se va folosi numele fişierului transmis ca valoare
pentru primul parametru.
- Cel de-al patrulea parametru este de tip logic şi este opţional. Dacă acest parametru are
valoarea TRUE, atunci se va considera că primul parametru reprezintă numele unui fişier, iar
dacă are valoarea FALSE, atunci se va considera că primul parametru reprezintă conţinutul
unei imagini. Valoarea implicită a acestui parametru este TRUE.
Funcţia addHTMLImage returnează valoarea logică TRUE dacă a reuşit să adauge la mesaj
conţinutul şi o instanţă a clasei PEAR_Error în caz contrar.

Funcţia Mail_Mime::addAttachement

Această funcţie se foloseşte pentru a adăuga un fişier la un mesaj şi are cinci parametri, dintre
care primii patru au aceaşi semnificaţie cu cei de la funcţia precedentă. Ultimul parametru este
de tip şir de caractere, este opţional şi reprezinta tipul codificării care va fi utilizată. Acest
parametru are valoarea implicită "base64". Pentru fişiere ataşate care nu sunt binare (ex.
fişiere executabile, arhive...) se poate folosi valoarea "quoted-printable".
Functia Mail_Mime::headers

Această funcţie se foloseşte pentru a adăuga linii de antet suplimentare la mesajul constituit
de această clasă. Funcţia headers are un singur parametru de tip listă, care are ca şi chei
numele câmpurilor antetelor şi ca valori, valorile acestor câmpuri. Funcţia returnează o
referinţă la o listă de acelaşi tip care conţine, pe lângă elementele transmise ca parametru, şi
elementele adăugate de această clasă, pentru ca mesajul să fie recunoscut cum trebuie de
către un client de mail. Această funcţie nu poate fi apelată după apelul funcţiei
Mail_Mime::get.

Functia Mail_Mime::get

Această funcţie se foloseşte pentru a obţine conţinutul mesajului electronic în format MIME,
după ce acesta a fost construit. Funcţia get nu are nici un parametru şi returnează un şir de
caractere care reprezintă conţinutul mesajului electronic codificat în format MIME.

Pentru a transmite un mesaj folosind funcţia mail prezentată şi această clasă, trebuie prelucrat
şirul liniilor de antet returnat de funcţia Mail_Mime::headers astfel încât să se obţină un şir de
caractere, iar conţinutul mesajului va fi constituit de şirul de caractere rezultat în urma apelării
funcţiei Mail_Mime::get.

Informaţii despre clasele încărcate

În continuare sunt prezentate un set de funcţii cu ajutorul cărora se pot afla informaţii despre
clasele încărcate într-un script.

Funcţia get_declared_classes

Această funcţie returnează un tablou care conţine numele tuturor claselor definite în momentul
execuţiei unui script PHP.

Funcţia class_exists

Această funcţie primeşte ca parametru un şir de caractere şi returnează valoarea logică TRUE
dacă există o clasă care să aibă numele identic cu şirul de caractere primit ca parametru şi
valoarea logică FALSE în caz contrar.

Funcţia get_parent_class

Această funcţie are un parametru care poate fi de tip şir de caractere sau obiect. În cazul în
care parametrul este de tipul şir de caractere, atunci funcţia get_parent_class returnează un
şir de caractere care reprezintă numele clasei care este părintele direct al clasei al cărui nume
este dat de parametru. În cazul în care parametrul este de tip obiect, atunci funcţia returnează
un şir de caractere care reprezintă numele părintelui direct al clasei a cărei instanţă este
reprezentată de obiectul dat ca parametru.

Funcţia is_a
Această funcţie are doi parametri. Primul parametru este de tip obiect, iar al doilea este de tip
şir de caractere. Funcţia is_a returnează valoarea logică TRUE dacă primul parametru este de
tipul reprezentat de al doilea parametru sau de tip derivat din cel de-al doilea parametru şi
valoarea logică FALSE în caz contrar. De exemplu, dacă avem clasele cls1, cls2 şi cls3 iar cls3
este derivată din cls2 iar cls2 este derivată din cls1, atunci, dacă obj reprezintă o instanţă a
clasei cls3, în urma apelurilor is_a(obj, "cls1"), is_a(obj, "cls2") şi is_a(obj, "cls3") se obţine
valoarea logică TRUE.

Funcţia is_subclass_of

Funcţia is_subclass_of are aceiaşi parametri cu funcţia anterioară. Funcţionalitatea ei diferă


faţă de funcţia precedentă prin faptul că valoarea logică TRUE este returnată numai în cazul în
care primul parametru este o instanţă a unui tip derivat din tipul a cărui nume este dat de cel
de-al doilea parametru. În condiţiile exemplului anterior, în urma apelului is_subclass_of(obj,
"cls3") se va obţine valoarea logică FALSE.

Funcţia get_class_methods

Această funcţie are un parametru care poate fi de tip şir de caractere care reprezintă numele
unei clase sau de tip obiect. Funcţia get_class_methods returnează un tablou ale cărui
elemente sunt de tipul şir de caractere şi care reprezintă numele metodelor definite în cadrul
clasei cu numele primit ca parametru sau în cadrul clasei care este reprezentată de obiectul
primit ca parametru. În cazul în care parametrul este de tip şir de caractere şi nu este definită
nici o clasă cu acest nume, atunci funcţia returnează valoarea logică FALSE.

Functia get_class_vars

Această funcţie are un singur parametru de tip şir de caractere care reprezintă numele unei
clase şi returnează un tablou ale cărui elemente sunt de tip şir de caractere şi care reprezintă
valorile implicite ale variabilelor definite în cadrul clasei. Tabloul rezultat în urma apelului
acestei funcţii este indexat după numele variabilelor definite în cadrul clasei.

Funcţia get_class

Această funcţie primeşte ca parametru un obiect şi returnează numele clasei care reprezintă
tipul obiectului primit ca parametru.

Funcţia get_object_vars

Această funcţie are un singur parametru de tip obiect şi returnează un tablou ale cărui
elemente sunt de tip şir de caractere şi care reprezintă valorile variabilelor definite în cadrul
acestuia. Tabloul rezultat în urma apelului acestei funcţii este indexat după numele variabilelor
definite în cadrul obiectului. Funcţia get_object_vars se aseamănă foarte mult cu funcţia
get_class_vars.

Functia call_user_method

Această funcţie realizează apelul unei metode care aparţine unei clase sau unui obiect cu
parametrii specificaţi. Funcţia call_user_method are mai mulţi parametri. Primul parametru
este de tip şir de caractere şi reprezintă numele metodei care se va apela. Al doilea parametru
este de tip obiect sau de tip şir de caractere şi reprezintă numele unei clase. În cazul în care
acest parametru este de tip obiect, metoda dată de primul parametru este apelată pentru
obiect, iar dacă parametrul este de tip şir de caractere, atunci metoda este apelată pentru
clasa al cărui nume este dat de acest parametru. Restul parametrilor reprezintă parametrii cu
care se va apela metoda al cărui nume este dat de primul parametru.

Funcţia call_user_method_array

Această funcţie are aceeaşi funcţionalitate cu funcţia anterioară cu diferenţa că are doar trei
parametri, iar al treilea parametru este un tablou unidimensional care conţine parametrii cu
care se va apela metoda dată de primul parametru pentru clasa sau obiectul reprezentat de
cel de-al doilea parametru.

Funcţia eval

Această funcţie primeşte ca parametru un şir de caractere care reprezintă o secvenţă de cod
PHP şi realizează execuţia acestuia.

Funcţia dl

Această funcţie realizează încărcarea în timpul execuţiei script-ului a unor extensii externe,
dacă acest lucru este permis de setările interpretorului PHP. Funcţia dl primeşte ca parametru
un şir de caractere care reprezintă calea către extenşia care trebuie încărcată şi returnează
valoarea logică TRUE dacă s-a reuşit încărcarea extensiei şi valoarea logică FALSE în caz
contrar.

Funcţia extension_loaded

Această funcţie verifică dacă o anumită extensie este încarcată. Funcţia primeşte un
parametru de tip şir de caractere care reprezintă numele unei extensii şi returnează o valoare
logică corespunzătoare.

Funcţia get_declared_classes

Funcţia get_declared_classes nu are nici un parametru şi returnează un tablou unidimensional


care conţine numele tuturor claselor încărcate în mediul de execuţie în momentul apelării
acesteia.

Prelucrarea dinamică a imaginilor

Un aspect important al limbajului PHP este acela că oferă programatorilor posibilitatea de a


crea şi publica în cadrul paginilor web imagini dinamice cum ar fi de exemplu, o aplicaţie care
monitorizează accesările unei pagini web şi afişează rezultatul sub forma unei imagini. Pentru
a profita de această facilitate în limbajul PHP trebuie activată mai întâi biblioteca php_gd2.
Acest lucru se face prin adăugarea următoarei linii (dacă nu există deja) în fişierul de
configurare php.ini (pentru sistemele Windows):

extension = php_gd2.dll

În acest moment sunt disponibile funcţiile de prelucrare şi generare dinamică de imagini.


Această librărie permite adăugarea de text în cadrul imaginilor generate şi oferă suport pentru
imagini în mai multe formate. Pentru a obţine imagini de calitate foarte bună, această
bibliotecă oferă suport integrat pentru bibliotecile FreeType 1, FreeType 2 şi T1Lib, care au ca
scop încărcarea şi desenarea font-urilor independent de platformă.

Formate de imagini suportate

Pentru a afla ce formate de imagini suportă biblioteca instalată (în funcţie de versiunea PHP)
se poate executa funcţia gd_info().

Cod:

<?php
var_dump(gd_info());
?>

Citat:
array(12) {
["GD Version"]=>
string(27) "bundled (2.0.28 compatible)"
["FreeType Support"]=>
bool(true)
["FreeType Linkage"]=>
string(13) "with freetype"
["T1Lib Support"]=>
bool(true)
["GIF Read Support"]=>
bool(true)
["GIF Create Support"]=>
bool(true)
["JPG Support"]=>
bool(true)
["PNG Support"]=>
bool(true)
["WBMP Support"]=>
bool(true)
["XPM Support"]=>
bool(false)
["XBM Support"]=>
bool(true)
["JIS-mapped Japanese Font Support"]=>
bool(false)
}

Rezultatul returnat de această funcţie îl reprezintă un vector cu mai multe componente. Se


poate observa că printre aceste componente se află versiunea bibliotecii şi facilităţile oferite.
Formatele de imagini suportate de biblioteca php_gd2 sunt GIF, JPG, PNG, WBMP şi XBM
(XPM). Se observă că biblioteca folosită nu permite salvarea imaginilor în format GIF.

Crearea dinamica a imaginilor

Pentru a crea imagini în mod dinamic avem la dispoziţie două opţiuni. Putem crea o imagine
care este bazată pe o paletă de culori (pentru acest tip de imagini avem la dispoziţie doar 256
de culori cu care putem opera) sau putem crea o imagine cu un număr neprecizat de culori
(true color). Funcţiile cu ajutorul cărora putem crea imagini sunt:

- imagecreate - această funcţie crează o imagine goală care este bazată pe o paletă de culori;
primeşte ca parametru două numere întregi care reprezintă dimensiunile imaginii (lăţimea şi
înălţimea) şi returnează o variabilă de tipul resource care reprezintă identificatorul de acces la
imaginea nou creată;
- imagecreatetruecolor - această funcţie crează o imagine care are fundalul negru şi un număr
nedefinit de culori; primeşte ca parametri două numere întregi care reprezintă dimensiunile
imaginii (lăţimea şi înălţimea) şi returnează o variabilă de tipul resource care reprezintă
identificatorul de acces la imaginea nou creată.

Trebuie avut în vedere, că pentru a afişa o imagine dinamică pe o pagină web trebuie realizată
o pagină care are un element IMG al cărui atribut src să indice calea către script-ul PHP care
creează imaginea.

Cod:

// pagina web contine:


<HTML>
<TITLE>
Imagine dinamica
</TITLE>
<BODY>
<IMG src="imagine.php">
</BODY>
</HTML>

<?php
// pagina imagine.php contine:
header("Content-type: image/png");
$img = imagecreate(100,100);
$fundal = imagecolorallocate($img, 150, 200, 100);
imagepng($img);
imagedestroy($img);
?>

Mai jos aveţi un exemplu al scriptului prezentat mai sus:

Încărcarea imaginilor

Biblioteca permite, de asemenea, citirea de imagini aflate la o anumită locaţie şi încărcarea


acestora în memorie pentru prelucrare şi, eventual, publicare. Funcţiile care încarcă imagini
deja existente sunt:

- imagecreatefromgif - această funcţie primeşte ca parametru o cale spre un fişier, care se


poate afla şi la distanţă, şi returnează o variabilă de tipul resource care reprezintă
identificatorul de acces la imaginea de tipul GIF încărcată;
- imagecreatefromjpeg - această funcţie primeşte ca parametru o cale spre un fişier, care se
poate afla şi la distanţă, şi returnează o variabilă de tipul resource care reprezintă
identificatorul de acces la imaginea de tipul JPG încărcată;
- imagecreatefrompng - această funcţie primeşte ca parametru o cale spre un fişier, care se
poate afla si la distanţă, şi returnează o variabilă de tipul resource care reprezintă
identificatorul de acces la imaginea de tipul PNG încărcată;
- imagecreatefromwbmp - această funcţie primeşte ca parametru o cale spre un fişier, care se
poate afla şi la distanţă, şi returnează o variabilă de tipul resource care reprezintă
identificatorul de acces la imaginea de tipul WBMP încărcată;
- imagecreatefromxbm - această funcţie primeşte ca parametru o cale spre un fişier, care se
poate afla şi la distanţă, şi returnează o variabilă de tipul resource care reprezintă
identificatorul de acces la imaginea de tipul XBM încărcată;
- imagecreatefromxpm - această funcţie primeşte ca parametru o cale spre un fişier, care se
poate afla şi la distanţă, şi returnează o variabilă de tipul resource care reprezintă
identificatorul de acces la imaginea de tipul XPM încărcată;
- imagecreatefromstring - această funcţie primeşte ca parametru un şir de caractere care
conţine reprezentarea binară a unei imagini, şi returnează o variabilă de tipul resource care
reprezintă identificatorul de acces la imaginea încărcată.

Cod:

<?php
header("Content-type: image/png");
$im=imagecreatefrompng("images/logo.png");
imagepng($im);
imagedestroy($im);
?>

Şi exemplul concret îl vedeţi mai jos:

Desenarea de imagini

Pentru a desena pe o imagine creată dinamic sau încărcată dintr-un fişier avem la dispoziţie
mai multe funcţii:

- imagearc - desenează pe o imagine un arc de elipsă; primeşte ca parametri identificatorul de


acces la imaginea pe care se va desena, coordonata x a centrului elipsei, coordonata y a
centrului eclipsei, lungimea şi înălţimea elipsei, unghiurile de start şi de stop ale arcului şi
culoarea cu care se va desena; desenarea se face în sens trigonometric;
- imagefilledarc - desenează pe o imagine un arc de elipsă haşurat; are aceeaşi parametri cu
funcţia anterioară la care se mai adaugă unul care reprezintă stilul haşurii şi care poate avea
valorile: IMB_ARC_PIE, IMG_ARC_CHORD, IMG_ARC_NOFILL, IMG_ARC_EDGED;
- imageline - desenează o linie pe imagine; primeşte ca parametri identificatorul de acces al
imaginii pe care se va desena, coordonata x a primului capăt de linie, coordonata y a primului
capăt de linie, coordonata x a celui de-al doilea capăt, coordonata y a celui de-al doilea capăt
şi culoarea cu care se va desena linia;
- imagedashedline - desenează o linie punctată pe o imagine; are aceeaşi parametri ca funcţia
anterioară şi va folosi stilul implicit sau cel setat de utilizator.
- imagesetthickness - setează grosimea cu care se vor trasa liniile pentru o anumită imagine;
primeşte ca parametri identificatorul de acces al imaginii şi un număr întreg care reprezintă
grosimea cu care se vor desena liniile pe imagine;
- imageellipse - desenează o elipsă pe o imagine; primeşte ca parametri identificatorul de
acces al imaginii pe care se va desena, coordonata x şi y a centrului elipsei, lungimea şi
înălţimea elipsei şi culoarea cu care se va desena;
- imagefilledellipse - desenează o elipsă plină; are aceeaşi parametri cu funcţia anterioară;
- imagepolygon - desenează un poligon pe o imagine; primeşte ca parametri identificatorul de
acces al imaginii pe care se va desena poligonul, un tablou ale cărui elemente sunt numere
întregi şi reprezintă coordonatele punctelor poligonului care se va desena, numărul de puncte
ale poligonului şi culoarea cu care se va desena; tabloul cu punctele poligonului conţine pe
pozitiile pare coordonatele x ale punctelor, iar pe pozitiile impare coordonatele y ale punctelor;
- imagefilledpolygon - desenează un poligon plin; are aceeaşi parametri cu funcţia anterioară;
- imagerectangle - desenează un dreptunghi pe o imagine; primeşte ca parametri
identificatorul de acces al imaginii pe care se va desena, coordonata x şi y a colţului din partea
stângă-sus a dreptunghiului, coordonata x şi y a colţului din partea dreapta-jos a
dreptunghiului şi culoarea cu care se va desena;
- imagefilledrectangle - desenează un dreptunghi plin; are aceeaşi parametri cu funcţia
anterioară;
- imagefill - umple cu o culoare o zonă de pe imagine care are aceeaşi culoare cu cea a
punctului care se află la coordonatele specificate ca parametru; primeşte ca parametri
identificatorul de acces al imaginii pe care se va face umplerea, coordonata x a unui punct din
zona care se va umple cu culoare, coordonata y a punctului şi culoarea cu care se va umple.
- imagefilltoborder - umple cu o culoare o zonă de pe imagine care este mărginită de o culoare
specificată ca parametru; primeşte ca parametri identificatorul de acces al imaginii pe care se
va face umplerea, coordonata x a unui punct din zona care se va umple cu culoare,
coordonata y a punctului, culoarea punctelor cu care este mărginită zona şi culoarea cu care
se va umple;
- imagesetpixel - schimbă culoarea unui punct de pe o imagine; primeşte ca parametri
identificatorul de acces al imaginii, coordonata x a punctului a cărui culoare se va schimba,
coordonata y a punctului şi noua culoare a acestuia;
- imagecolorat - returnează culoarea unui anumit punct de pe imagine; primeşte ca parametri
identificatorul de acces al imaginii, coordonata x a punctului şi coordonata y a punctului;
- imagecolorallocate - primeşte ca parametri identificatorul de acces al unei imagini, o valoare
pentru componenta roşu a unei culori, o valoare pentru componenta verde a unei culori şi o
valoare pentru componenta albastru a unei culori şi returnează un număr întreg care
reprezintă culoarea având cele trei componente; în cazul în care imaginea se bazează pe o
paletă de culori, atunci se returnează indicele culorii din paletă; dacă în paleta de culori nu
există o culoare care să aibă toate cele trei componente, atunci ea este adaugată la paleta de
culori a imaginii;
- imagecolordeallocate - primeşte ca parametri identificatorul de acces al unei imagini şi o
culoare; în cazul în care imaginea specificată ca parametru se bazează pe o paletă de culori,
atunci culoarea este eliminată din paletă.

Cod:

<?php
header("Content-type: image/png");
$im = imagecreate(250,250);
$red = imagecolorallocate ($im,255,0,0);
$blue = imagecolorallocate ($im,0,0,255);
$green = imagecolorallocate ($im,0,255,0);
$yellow = imagecolorallocate ($im,255,255,0);
$cyan = imagecolorallocate ($im,0,255,255);
$magenta = imagecolorallocate ($im,255,0,255);
imagefill($im,229,229,$cyan);
imagefill($im,30,100,$magenta);
imagefill($im,80,160,$yellow);
imagefilledrectangle($im,0,0,50,100,$red);
imagefilledellipse($im,100,100,50,50,$green);
imagesetthickness($im,3);
$poly = array(10,10,200,50,255,100,150,200,100,75,50,50);
imagefilledpolygon($im,$poly,6,$blue);
imageline($im,0,229,229,0,$red);
imagepng($im);
imagedestroy($img);
?>

Rezultatul exemplului îl vedeti mai jos:

Scrierea textului pe imagini

În continuare sunt prezentate câteva funcţii utilizate pentru a scrie un text sau un caracter pe
o imagine.

Funcţia imagechar

Această funcţie scrie pe o imagine primul caracter al unui şir de caractere. Funcţia imagechar
are şase parametri:
- primul parametru este identificatorul de acces la imaginea pe care se va desena
- cel de-al doilea parametru reprezintă identificatorul de acces la font-ul care va fi folosit
pentru a scrie caracterul pe imagine. Acest identificator este de tip număr întreg şi poate avea
valorile predefinite 1, 2, 3, 4 sau 5 sau poate fi un număr returnat de o funcţie care încarcă un
font de pe disc.
- cel de-al treilea parametru reprezintă coordonata x a colţului stânga-sus de unde va începe
scrierea caracterului;
- cel de-al patrulea parametru reprezintă coordonata y a colţului stânga-sus de unde va începe
scrierea caracterului;
- al cincilea parametru reprezintă şirul de caractere din care va fi scris doar primul caracter;
- cel de-al şaselea parametru reprezintă culoarea cu care se va scrie pe imagine.

Cod:

<?php
header("Content-type: image/png");
$im = imagecreate(100,100);
$fundal = imagecolorallocate($im, 0, 0, 225);
$verde = imagecolorallocate ($im,0,255,0);
imagechar($im, 5, 15, 10, 'a', $verde);
imagepng($im);
imagedestroy($im);
?>

Rezultatul este:

Funcţia imagecharup

Această funcţie scrie un caracter vertical pe o imagine. Are aceeaşi parametri ca funcţia
anterioara.

Cod:

<?php
header("Content-type: image/png");
$im = imagecreate(100,100);
$fundal = imagecolorallocate($im, 0, 0, 225);
$verde = imagecolorallocate ($im,0,255,0);
imagecharup($im, 5, 15, 10, 'a', $verde);
imagepng($im);
imagedestroy($im);
?>

Rezultatul codului de mai sus:

Funcţia imagestring

Această funcţie scrie un text pe o imagine şi are aceeaşi parametri ca funcţia imagechar.

Cod:

<?php
header("Content-type: image/png");
$im = imagecreate(100,100);
$fundal = imagecolorallocate($im, 0, 0, 225);
$verde = imagecolorallocate ($im,0,255,0);
imagestring($im, 5, 15, 10, 'test', $verde);
imagepng($im);
imagedestroy($im);
?>

Rezultatul:

Funcţia imagestringup

Această funcţie scrie vertical un text pe o imagine şi are aceeaşi parametri ca funcţia
imagechar.

Cod:

<?php
header("Content-type: image/png");
$im = imagecreate(100,100);
$fundal = imagecolorallocate($im, 0, 0, 225);
$verde = imagecolorallocate ($im,0,255,0);
imagestringup($im, 5, 15, 40, 'test', $verde);
imagepng($im);
imagedestroy($im);
?>

Rezultatul este:

Funcţia imagerotate

Această funcţie realizează rotirea unei imagini în sens trigonometric cu un unghi primit ca
parametru. Imaginea rezultată în urma rotirii va avea dimensiunile egale cu dimensiunile celui
mai mic dreptunghi ale cărui laturi sunt paralele cu axele Ox şi Oy şi care conţine imaginea
rotită. Funcţia are trei parametri:
- primul reprezintă identificatorul de acces la imagine;
- al doilea este de tip real şi reprezintă unghiul cu care se va roti imaginea;
- al treilea parametru este de tip întreg şi reprezintă culoarea cu care se va umple
dreptunghiul care va conţine imaginea rotită.
Funcţia imagerotate returnează un identificator de acces la imaginea rotită.
Cod:

<?php
header("Content-type: image/png");
$im = imagecreate(100,100);
$fundal = imagecolorallocate($im, 0, 0, 225);
$verde = imagecolorallocate ($im,0,255,0);
imagestringup($im, 5, 55, 40, 'test', $verde);
$imrot = imagerotate($im, 45, $verde);
imagepng($imrot);
imagedestroy($imrot);
?>

Şi rezultatul din exemplul de mai sus este:

Funcţia imagetruecolorpalette

Această funcţie realizează transformarea unei imagini care nu foloseşte o paletă de culori într-
o imagine care foloseşte o paletă de culori. Funcţia imagetruecolorpalette are trei parametri:
- primul reprezintă identificatorul de acces al imaginii care va fi transformată;
- cel de-al doilea parametru este de tip logic şi reprezintă modul în care se va face
transformarea: dacă imaginea va fi fără zgomot (valoarea logică FALSE implică o aproximare
mai slabă a culorilor); dacă imaginea va fi cu zgomot (valoarea TRUE implică o aproximare
mai bună a culorilor);

Funcţia jpeg2wbmp

Această funcţie transformă o imagine din formatul JPEG în formatul WBMP. Funcţia are cinci
parametri. Primul parametru reprezintă calea spre fişierul de tip JPEG care va fi transformat.
Al doilea parametru reprezintă calea spre fişierul care va conţine rezultatul transformării.
Următorii doi parametri sunt de tip întreg şi reprezintă înălţimea şi lăţimea noii imagini, iar
ultimul parametru, tot de tip întreg, reprezintă pasul cu care se va parcurge imaginea pentru a
fi transformată.

Funcţia png2wbmp

Această funcţie transformă o imagine din formatul PNG în formatul WBMP. Are aceeaşi
parametri ca funcţia anterioară, cu observaţia că primul parametru reprezintă calea spre un
fişier de tipul PNG.

Funcţia imageinterlace

Această funcţie setează proprietatea interlace a unei imagini la valoarea logică precizată ca
parametru sau la valoarea logică TRUE dacă acest parametru lipseşte. Această funcţie este
foarte importantă în cazul în care doriţi ca site-ul vostru să aibă o navigabilitate bună, chiar
dacă nu s-au încărcat integral toate elementele grafice prezente în cadrul lui. În cazul în care
aveţi o viteză de acces la internet mică sau imaginea pe care doriţi să o încărcaţi este mare,
nu este nevoie să aşteptaţi încărcarea întregii imagini pentru a vedea ce este în ea. O astfel de
imagine se încarcă adaptiv, şi în momentul în care s-a încheiat transferul imaginii către
browser, pe imagine se pot observa toate detaliile. De fapt, teoretic vorbind, o imagine este
împărţită în subimagini de aceeaşi dimensiune şi calitate diferită (din ce în ce mai bună), care
suprapuse dau ca rezultat imaginea iniţială. Practic nu se întâmplă chiar aşa, dar efectul
obţinut este cel precizat anterior. Funcţia are doi parametri. Primul parametru reprezintă
identificatorul de acces la imaginea pentru care se doreşte setarea proprietăţii interlace, iar al
doilea parametru este de tip logic şi reprezintă valoarea pe care o va avea această proptietate.
Cel de-al doilea parametru poate lipsi, dar proprietatea interlace atribuită unei imagini va primi
valoarea TRUE.

Publicarea în diverse formate

Pentru a publica o imagine generată dinamic se poate utiliza una dintre funcţiile: imagegif,
imagepng, imagejpeg sau imagewbmp. Aceste funcţii primesc ca parametru un identificator de
imagine şi tipăresc la ieşirea standard imaginea în format GIF, PNG, JPEG sau WBMP. Primele
trei funcţii se folosesc pentru a genera o imagine care să poata fi vizualizată într-un browser
încărcat de pe un calculator, iar ultima se foloseşte pentru ca imaginea generată să poata fi
vizualizată în cadrul unui browser care suportă WAP.

Funcţii PHP utilizate pentru accesarea şi interogarea bazelor de date MySQL

În acest articol voi încerca să prezint cele mai folosite comenzi PHP pentru lucrul cu bazele de
date MySQL.

Funcţia mysql_connect

Această funcţie realizează conectarea la un server MySQL. Funcţia mysql_connect primeşte


cinci parametri opţionali:

- primul reprezintă numele server-ului MySQL şi dacă lipseşte se încearcă conectarea la


calculatorul curent.
- cel de-al doilea reprezintă numele utilizatorului şi în caz că acesta lipseşte se foloseşte
valoarea root ca nume de utilizator.
- al treilea parametru reprezintă parola utilizatorului şi în caz că lipseşte se foloseşte şirul vid
în momentul conectării la server.
- al patrulea parametru este de tip logic şi are rolul de a indica motorului PHP că în cazul în
care există o conexiune la acelaşi server să se mai creeze încă una în loc să se reutilizeze cea
existentă.
- ultimul parametru este de tip întreg şi reprezintă proprietăţile pe care le va avea conexiunea.
Acest ultim parametru poate fi o combinaţie a valorilor:
a) MYSQL_CLIENT_COMPRESS - indică server-ului că va trebui să trimită date comprimate.
b) MYSQL_CLIENT_IGNORE_SPACE - indică server-ului MySQL faptul că va trebui să ignore
spaţiile care urmează după numele funcţiilor.
c) MYSQL_CLIENT_INTERACTIVE - indică server-ului MYSQL să nu închidă conexiunea după
scurgerea unui anumit interval de timp în care script-ul nu a emis cereri către acesta.
Funcţia mysql_connect returnează valoarea logică FALSE în cazul în care a eşuat conectarea la
server-ul de baze de date şi un identificator de acces la conexiunea către server-ul MySQL în
cazul în care conectarea a reuşit. În continuare sunt prezentate 2 modalităţi de conectare la
un server MySQL:

Cod:

<?php
// varianta 1
$conectare = mysql_connect("nume_server", "user", "parola");
if ($conectare === FALSE)
{
echo "Conectare esuata.";
}
else
{
echo "Conexiune stabilita.";
}
mysql_close($conectare);

// varianta 2
$conectare = mysql_connect("nume_server", "user", "parola") or die("Con
ectare esuata.");
mysql_select_db("nume_tabel", $conectare) or die("Nu se poate alege baza
de date!");
$interogare = "SELECT * FROM nume_tabel";
$resultat = mysql_query($interogare) or die("Nu se poate executa intero
garea!");
// afisare rezultat
// ...
// inchidere conexiune
mysql_close($conectare);
?>

Funcţia mysql_close

Această funcţie primeşte ca parametru un identificator de acces la o conexiune spre un server


MySQL şi realizează închiderea acesteia.

Funcţia mysql_ping

Funcţia mysql_ping verifică dacă server-ul de MySQL a închis conexiunea sau nu. Aceasta nu
are nici un parametru şi returnează valoarea logică TRUE în cazul în care conexiunea nu a fost
închisă şi valoarea logică FALSE în caz contrar.

Funcţia mysql_create_db

Această funcţie este utilizată pentru a crea o nouă bază de date pe server-ul MySQL. Funcţia
are doi parametri. Primul este de tip şir de caractere şi reprezintă numele bazei de date care
va fi creată, iar cel de-al doilea parametru reprezintă identificatorul de acces la conexiunea
către server-ul MySQL. Funcţia returnează valoarea logică TRUE în cazul în care a reuşit să
creeze baza de date şi valoarea logică FALSE în caz contrar.

Funcţia mysql_drop_db
Această funcţie este folosită pentru a şterge o bază de date. Funcţia mysql_drop_db are doi
parametri. Primul este de tip şir de caractere şi reprezinta numele bazei de date care va fi
ştearsă, iar cel de-al doilea parametru reprezintă identificatorul de acces la conexiunea către
server-ul MySQL. Funcţia returnează valoarea logică TRUE în cazul în care s-a reuşit ştergerea
bazei de date şi valoarea logică FALSE în caz contrar.

Funcţia mysql_select_db

Această funcţie setează baza de date pentru o conexiune către un server MySQL pentru
interogările care vor urma. Funcţia mysql_select_db are doi parametri. Primul este de tip şir
de caractere şi reprezintă numele bazei de date care va fi folosită pentru interogările
ulterioare, iar cel de-al doilea parametru reprezintă identificatorul de acces la conexiunea către
serverul MySQL. Funcţia returnează valoarea logică TRUE în cazul în care s-a reuşit selectarea
bazei de date şi valoarea logică FALSE în cazul în care baza de date nu există sau utilizatorul
nu are drepturi de acces la aceasta.

Funcţia mysql_query

Această funcţie se foloseşte pentru a interoga o anumită baza de date. Funcţia are 3
parametri:

- primul este de tip şir de caractere şi reprezintă cererea emisă server-ului MySQL;
- al doilea parametru reprezintă identificatorul de acces al unei conexiuni către server;
- al treilea parametru este opţional şi de tip întreg şi reprezintă modul în care va fi returnat
rezultatul.
Ultimul parametru poate avea valorile MYSQL_USE_RESULT sau MYSQL_STORE_RESULT. În
cazul în care ultimul parametru lipseşte, pentru interogare se va folosi valoarea
MYSQL_STORE_RESULT, iar rezultatul primit va fi stocat în zone tampon până când va fi
utilizat. Dacă, pentru ultimul parametru, se foloseşte valoarea MYSQL_USE_RESULT, atunci
rezultatul primit nu va fi stocat, deoarece va fi procesat imediat după apelul funcţiei. Utilizarea
funcţiei folosind valoarea MYSQL_USE_RESULT pentru ultimul parametru are acelaşi efect cu
aplicarea funcţiei mysql_unbuffered_query fără a folosi ultimul parametru. Funcţia returnează
o valoare de tip resursă în cazul în care a fost apelată folosind o interogare care presupune
primirea unui rezultat cum sunt comenzile SELECT, SHOW, EXPLAIN şi DESCRIBE şi nu a
aparut nici o eroare, iar în cazul apariţiei unei erori, este returnată valoarea logică FALSE. În
cazul în care funcţia mysql_query este apelată pentru o interogare care nu presupune primirea
unui rezultat, este returnata valoarea logică TRUE şi valoarea logică FALSE în cazul apariţiei
unei erori. În continuare aveţi un exemplu de interogare a unei baze de date. În exemplu se
face selecţia primelor 10 înregistrări din tabel:

Cod:

<?php
$conectare = mysql_connect("localhost","root","parola") or die("Nu sa p
utut efectua conectarea la bd.");
mysql_select_db("nume_tabel", $conectare) or die("Nu se poate selecta t
abelul din bd!");
$interogare = "SELECT * FROM nume_tabel LIMIT 0,10";
$rezultat = mysql_query($interogare) or die("Nu se poate executa intero
garea!");
while ($rand = mysql_fetch_array($rezultat, MYSQL_BOTH))
{
echo '<br />'.$rand['coloana_X'];
}
mysql_free_result($rezultat);
mysql_close($conectare);
?>

Funcţia mysql_unbuffered_query

Această funcţie se foloseşte pentru a interoga o anumită bază de date şi are aceeaşi parametri
cu funcţia anterioară. Diferenţa dintre această funcţie şi mysql_query este aceea că, în cazul
funcţiei mysql_unbuffered_query, dacă ultimul parametru lipseşte, se foloseşte la interogarea
bazei de date valoarea MYSQL_USE_RESULT.

Funcţia mysql_real_escape_string

Această funcţie este utilă în momentul în care se doreşte introducerea în cadrul unei interogări
a unui şir de caractere care nu poate fi interpretat corect de către server-ul MySQL şi
realizează transformarea şirului într-unul care poate fi interpretat. Funcţia
mysql_real_escape_string are doi parametri. Primul este de tip şir de caractere şi reprezintă
şirul care va fi transformat, iar cel de-al doilea reprezintă identificatorul de acces la o
conexiune către un server MySQL. Funcţia returnează un şir de caractere care poate fi
interpretat corect de către server-ul MySQL. De exemplu, dacă apelăm această funcţie pentru
şirul de caractere "D'apoi" vom obţine rezultatul "D\'apoi", deoarece caracterul ' (apostrof) are
o altă semnificaţie pentru server-ul MySQL dacă nu e precedat de caracterul "\".

Funcţia mysql_free_result

Această funcţie se foloseşte pentru a elibera memoria alocată stocării unui rezultat primit în
urma unei interogari de la un server MySQL. Funcţia mysql_free_result are un singur
parametru, şi anume o variabilă de tip resursă a cărei valoare a fost setată folosind una dintre
funcţiile mysql_query sau mysql_unbuffered_query. Funcţia returnează valoarea logică TRUE
în cazul în care a reuşit să elibereze memoria utilizată de variabila de tip resursă primită ca
parametru şi valoarea logică FALSE în caz contrar.

Funcţia mysql_num_rows

Această funcţie returnează numărul de înregistrări conţinute de către un rezultat primit de la


server-ul MySQL. Funcţia mysql_num_rows are un singur parametru, şi anume o variabilă de
tipul resursă a cărei valoare a fost setată folosind una dintre funcţiile mysql_query sau
mysql_unbuffered_query. Funcţia returnează un număr întreg care reprezintă numărul de
înregistrări conţinute de variabila de tip resursă primită ca parametru. În continuare este un
exemplu de utilizare a acestei funcţii. În exemplu se afişează numărul total de înregistrări din
tabel.

Cod:

<?php
$conectare = mysql_connect("localhost", "user", "parola") or die("Nu se
poate conecta la server");
mysql_select_db("nume_bd", $conectare) or die("Nu se poate selecta baza
de date");
$rezultat = mysql_query("SELECT * FROM nume_tabel", $conectare)
or die("Nu se poate face interogarea la baza de date");
$total = mysql_num_rows($rezultat);
echo "In tabel exista ".$total." inregistrari in acest moment.";
mysql_free_result($rezultat);
mysql_close($conectare);
?>

Funcţia mysql_info

Această funcţie returnează un şir de caractere care conţine informaţii referitoare la ultima
interogare a unei baze de date în urma căreia nu s-a primit nici un rezultat, cum este cazul
funcţiilor INSERT sau UPDATE. Funcţia mysql_info are un singur parametru care reprezintă
identificatorul de acces al unei conexiuni spre un server MySQL.

Funcţia mysql_affected_rows

În cazul interogărilor în urma cărora nu se obţine nici un rezultat, se poate folosi funcţia
mysql_affected_rows pentru a verifica numărul de înregistrări care au fost actualizate la ultima
înterogare a bazei de date, pentru celelalte tipuri de interogări putându-se folosi funcţia
mysql_num_rows. Funcţia mysql_affected_rows are un singur parametru care reprezintă
identificatorul de acces al unei conexiuni spre un server MySQL şi returnează un număr întreg,
care reprezintă numărul de înregistrări actualizate la ultima interogare a bazei de date.

Funcţia mysql_fetch_array

Această funcţie transformă o înregistrare dintr-un rezultat primit de la server-ul MySQL într-o
listă. Funcţia mysql_fetch_array colectează datele referitoare la înregistrarea curentă şi le
returnează sub forma unei liste ale cărui elemente pot fi accesate folosind numele câmpurilor,
numărul lor de ordine sau folosind ambele moduri. Dacă nu mai sunt înregistrări de prelucrat,
funcţia returnează valoarea logică FALSE. Această funcţie are doi parametri:

- primul parametru este de tipul resursă, a cărui valoare a fost setată folosind una dintre
funcţiile mysql_query sau mysql_unbuffered_query;
- al doilea parametru este opţional, este de tip întreg şi reprezintă modul în care sa face
transformarea.
Cel de-al doilea parametru poate avea una din valorile următoare:
- MYSQL_ASSOC - elementele din lista rezultată pot fi accesate folosind doar numele
câmpurilor;
- MYSQL_NUM - elementele din lista rezultată pot fi accesate folosind doar numerele de ordine
ale câmpurilor;
- MYSQL_BOTH - elementele din lista rezultată pot fi accesate folosind ambele moduri
prezentate anterior;

Funcţia mysql_fetch_assoc

Această funcţie transformă o înregistrare dintr-un rezultat primit de la server-ul MySQL într-o
listă şi are acelaşi efect cu cel al folosirii funcţiei mysql_fetch_array, folosind pentru cel de-al
doilea parametru valoare MYSQL_ASSOC.

Funcţia mysql_fetch_num

Această funcţie transformă o înregistrare dintr-un rezultat primit de la server-ul MySQL într-o
listă şi are acelaşi efect cu cel al folosirii funcţiei mysql_fetch_array, folosind pentru cel de-al
doilea parametru valoarea MYSQL_NUM.

Funcţia mysql_stat
Această funcţie returnează un şir de caractere care reprezintă statusul server-ului MySQL şi
are un singur parametru care reprezintă identificatorul de acces la o conexiune către un server
MySQL.

Cod:

<?php
$conectare = mysql_connect("localhost", "user", "parola") or die("Nu se
poate conecta la server");
$stare = explode(' ', mysql_stat($conectare));
print_r($stare);
mysql_close($conectare);
?>

Utilizarea şirurilor

Secvenţe escape

Pentru a include caractere speciale în cadrul şirurilor trebuie să folosiţi anumite secvenţe
escape. În tabelul de mai jos este prezentat setul de secvenţe escape folosit în PHP.

Secvenţa escape Semnificaţie


\n salt la linie nouă
\r retur de car
\t caracter de tabulare pe orizontală
\\ backslaşh
\$ simbolul dolarului
\" ghilimele duble
caracterul asociat valorii ASCII xxx, exprimată sub forma unui număr în
\xxx
octal
caracterul asociat valorii ASCII xxx, exprimată sub forma unui număr în
\xnn
hexazecimal

În afară de ultimile două secvenţe din tabelul de mai sus, celelalte au fost prezentate în
articolul Câteva informaţii despre documentarea şi depanarea unui script. Fiecare dintre aceste
secvenţe escape foloseşte un cod ASCII (American Standard Code for Information
Interchange) pentru reprezentarea unui caracter. Codurile ASCII sunt valori întregi, care sunt
cuprinse între 0 şi 255; fiecare literă sau simbol folosit frecvent în limbile vest-europene are
asociat un cod ASCII. De exemplu, codul ASCII asociat literei A este 65, iar codul asociat cifrei
1 este 49.
Pentru \xxx puteti folosi reprezentarea în octal (baza 8) a unui cod ASCII pentru specificarea
caracterului corespunzător. De exemplu, valoarea zecimală 65 (care este codul ASCII al literei
A) poate fi reprezentată în octal sub forma 101. Ca atare, puteti reprezenta litera A folosind
secvenţa escape "\101".
Pentru \xnn puteţi folosi reprezentarea în hexazecimal (în baza 16). Pentru valoarea zecimală
65 poate fi reprezentată în hexazecimal cu nr 41. Deci puteţi scrie "\41".

Utilizarea codurilor ASCII

În tabelul de mai jos sunt prezentate câteva funcţii PHP folosite la utilizarea codurilor ASCII.
Iată un scurt exemplu de utilizare a funcţiei ord() pentru a determina codul ASCII
corespunzător unui anumit caracter:
$caracter="A";
$numar=ord($caracter);
echo "<br>Valoarea ASCII a caracterului ".$caracter." este ".$numar;

Datele de ieşire ale acestui exemplu sunt:

Valoarea ASCII a caracterului A este 65

Funcţie Descriere
chr(n) Returnează caracterul având codul ASCII dat de n.
Returnează valoarea hexazecimală echivalentă cu valoarea zecimală dată de
dechex(n)
n.
decoct(n) Returnează valoarea în octal echivalentă cu valoarea zecimală dată de n.
Returnează valoarea zecimală echivalentă cu valoarea hexazecimală dată de
hexdec(n)
n.
octdec(n) Returnează valoarea zecimală echivalentă cu valoarea în octal dată de n.
ord(c) Returnează codul ASCII echivalent caracterului c.

În continuare este un exemplu care afişează echivalenţele în zecimal, octal, respectiv


hexazecimal al caracterelor ASCII ale căror coduri sunt cuprinse între 32 şi 127:

Cod:

<?php
for ($i=32; $i<128; $i++)
{
$c=chr($i);
$octal=decoct($i);
$hex=dechex($i);
echo "<br>Nr. zecimal= $i - octal= $octal - hexa=$hex - caracter ec
hivalent=$c";
}
?>

Pentru caracterul cu nr 32 caracterul echivalent este un spaţiu.

Şirurile delimitate între ghilimele simple

Dacă doriţi, puteţi scrie un şir între ghilimele simple, nu neapărat duble. Un motiv în acest
sens îl constituie facilitatea posibilităţii de includere a ghilimelelor duble. Exemplu:

echo "<img src=\"pixel.php\" alt=\"\" height=\"1\" width=\"1\">";

Acest şir poate fi scris şi astfel:

echo '<img src="pixel.php" alt="" height="1" width="1">';

Şirurile delimitate între ghilimele simple se comportă într-un mod diferit faţă de şirurile
delimitate prin ghilimele duble:
- Singurele secvenţe escape permise în cadrul şirurilor delimitate prin ghilimele simple sunt \\
şi \'.
- Nu se execută substituţia variabilelor atunci când datele de ieşire sunt reprezentate printr-un
şir delimitat prin ghilimele simple. În consecinţă dacă folosiţi ghilimele simple ca în exemplul
următor:
$x = "test";
echo 'x este $x';

datele de ieşire vor arăta aşa:

x este $x.

Pentru a evita astfel de situaţi preferabil e să folosiţi ghilimele duble sau afişarea valorilor din
variabile în afara ghilimelelor simple, ca în exemplul următor:

$x = "test";
echo 'x este '.$x;

Crearea datelor de ieşire formatate

PHP include două funcţii utile pentru generarea datelor de ieşire formatate, în speţă printf()şi
sprintf(). Funcţia printf() afişează datele sale de ieşire, în timp ce funcţia sprint() returnează
datele sale de ieşire sub forma unor valori şir. În general, fiecare funcţie preia două sau mai
multe argumente. Primul argument este un şir, denumit şir de formatare, care specifică
formatul datelor de ieşire, iar celelalte argumente specifică valorile care vor constitui datele de
ieşire. Iată un exemplu simplu de utilizare a funcţiei printf():

printf("Valoarea lui n este: %d", $n);


$rezultat = sprintf(Valori: %d, %f", $n, $x);

Şirul de formatare constă dintr-o serie de caractere şi directive ordinare. Un caracter ordinar
este orice caracter, în afara caracterului %. Caracterele ordinare sunt pur şi simplu copiate la
ieşire. Directivele reprezintă secvenţe de caractere care încep cu simbolul % acestea
determină modul în care va fi formatat argumentul corespunzător. O directivă simplă, cum
este cea din exemplul precedent, poate consta dintr-un caracter % urmat de un specificator de
tip, precum d, care arată că argumentul trebuie tratat ca număr zecimal. Cu toate acestea, o
directivă mai sofisticată poate include următoarele componente, care trebuie să apară în
ordinea indicată:

- Specificator de completare (opţional): Un specificator de completare precizează caracterul


care se va folosi pentru a completa rezultatul până la dimensiunea cerută a şirului. În cazul în
care caracterul de completare este omis, rezultatul este completat cu spaţii. Specificatorul de
completare poate fi un caracter spaţiu sau un 0 (zero). Un specificator de completare de tip
spaţiu este folosit frecvent cu şirurile, iar un specificator de completare zero se foloseşte mai
ales alături de numere. Un alt caracter de completare poate fi specificat prin prefixarea
acestuia cu un singur semn ('). De exemplu, pentru a completa un rezultat cu liniuţe de
subliniere, specificaţi '_ drept caracter de completare.
- Specificator de aliniere (opţional): Un specificator de aliniere indică dacă rezultatul trebuie să
fie aliniat la stânga sau la dreapta. Dacă specificatorul de aliniere este omis, rezultatul va fi
aliniat la dreapta; dacă se indică o cratimă (-) drept specificator de aliniere, rezultatul va fi
aliniat la stânga.
- Specificator de lăţime (opţional): este un întreg care determină numărul minim de caractere
ale rezultatului; sau, dacă argumentul este de tip double, numărul minim de caractere situate
la stânga punctului zecimal. Dacă rezultatul conţine un număr mai redus de caractere, atunci
va conţine şi caractere de completare.
- Specificator de precizie (opţional): este un punct zecimal, urmat de un întreg care determină
numărul de cifre după punctul zecimal pe care trebuie sa le conţina rezultatul. Specificatorul
de precizie nu are nici un efect pentru alte tipuri decât double.
- Specificatorul de tip (obligatoriu): Specificatorul de tip determină modul de tratare şi afişare
a argumentului. Tabelul de mai jos rezumă specificatorii de tip disponibili.

Specificator de tip Descriere


b Tratează argumentul ca pe un întreg şi îl afişează ca valoare binară.
Tratează argumentul ca pe un întreg şi afişează caracterul cu aceeaşi
c
valoare ASCII ca şi argumentul.
d Tratează argumentul ca pe un întreg şi îl afişează ca valoare zecimală.
Tratează argumentul ca pe o valoare de tip double şi îl afişează ca valoare
f
cu virgulă mobilă.
Tratează argumentul ca pe un întreg şi îl afişează ca pe o valoare scrisă în
o
octal.
s Tratează argumentul ca pe un şir şi îl afişează.
Tratează argumentul ca pe un întreg şi îl afişează ca număr hexazecimal, cu
x
litere scrise cu minuscule.
Tratează argumentul ca pe un întreg şi îl afişează ca număr hexazecimal, cu
X
litere scrise cu majuscule..

Dacă doriţi să inseraţi simbolul procentului în datele de ieşire ale unui apel la funcţia printf()
sau sprintf(), inseraţi două caractere % în locul dorit. La apariţia a două caractere %, funcţiile
printf() şi sprintf() ştiu că doriţi să inseraţi un simbol al procentului, nu o directivă de
formatare. Tabelul de mai jos prezintă rezultatele aplicării a diferite şiruri de formatare
valorilor selectate. Remarcaţi că, în cazul omiterii cifrelor zecimale, se produce automat o
rotunjire. În tabelul de mai jos spaţiile au fost înlocuite prin caracterul ^, pentru a vedea mai
bine amplasarea acestora.

Valoare Format Rezultat


100 %d 100
100 %b 1100100
100 %o 144
100 %x 64
100 %f 100.000000
12.345 %'^-10f 12.345000^^^^^^^^
12.345 %'^10f ^^^^^^^^12.345000
12.345 %'^-10.2f 12.35^^^^^^^^
12.345 %'10.2f ^^^^^^^^12.35
"test" %'^-10s test^^^^^^
"test" %'^10s ^^^^^^test

Dacă preferaţi, puteţi folosi funcţia number_format(), care returnează o valoare de tip şir
conţinând un rezultat formatat. Puteţi apela funcţia cu unul, două sau patru argumente:

number_format(numar)
number_format(numar, zecimale)
number_format(numar, zecimale, punct_zecimal, separator_mii)

Argumentul numar specifică valoarea numerică pe care doriţi să o formataţi. Argumentul


zecimale specifică numărul dorit de cifre zecimale. Argumentul punct_zecimal precizează
caracterul ce se va folosi drept punct zecimal, iar argumentul separator_mii precizează
caracterul care se va folosi ca separator al miilor. În mod prestabilit, rezultatul este formatat
fără zecimale, este inserat un punct înaintea cifrelor care compun partea zecimală, respectiv
se foloşeste o virgulă pentru separarea miilor. Exemplu:

number_format(1.234, 2)

returnează valoarea 1.23

Manipularea şirurilor şi scrierea expresiilor regulate


PHP conţine peste 70 de funcţii care lucrează cu şiruri. Această pagină descrie cele mai
utilizate funcţii. Aceste funcţii vă permit să obţineţi lungimea unui şir, să eliminaţi dintr-un şir
caracterele de tip spaţiu şi să convertiţi caracterele unui şir în majuscule sau minuscule.

Obţinerea lungimii unui şir

Funcţia strlen() returnează lungimea şirului specificat ca argument al funcţiei. Iată un


exemplu:

$sir="ceva caractere";
$numar=strlen($sir);
echo "<br>Lungimea sirului este de $numar caractere";

Eliminarea caracterelor dintr-un şir

Numeroase funcţii PHP vă permit să eliminaţi caracterele de tip spaţiu alb de la una sau
ambele extremităţi ale unui şir. Caracterele de tip spaţiu alb sunt caractere precum spaţiu,
tabulator şi caracter de salt la linie nouă, care nu dispun de nici o reprezentare vizibilă. Aceste
funcţi sunt prezentate în tabelul de mai jos.

Funcţie Descriere
Returnează valoarea lui s, eliminând spaţiile albe de la extremitatea din
chop(s)
dreapta a şirului. Similar cu rtrim().
Returnează valoarea lui s, eliminând spaţiile albe de la extremitatea din
ltrim(s)
stânga a şirului.
Returnează valoarea lui s, eliminând spaţiile albe de la extremitatea din
rtrim(s)
dreapta a şirului. Similar cu chop().
trim(s) Returnează valoarea lui s, eliminând spaţiile albe de la ambele extremităţi.

Conversia şirurilor la majuscule sau minuscule

Funcţia strtoupper() returnează valoarea argumentului său, convertită la majuscule. Funcţia


conexa strtolower() returnează valoarea argumentului său, convertită la minuscule.

Compararea şirurilor şi căutarea în şiruri

PHP furnizează patru funcţii care sunt deosebit de utile pentru compararea şirurilor. Aceste
funcţii sunt enumerate mai jos. Fiecare funcţie returnează o valoare al cărei semn determină
rezultatul comparaţiei. Funcţia strncasecmp() a fost adăugată în versiunea PHP 4.0.2.

Funcţie Descriere
Execută o comparaţie fără sensibilitate la diferenţa între majuscule şi
minuscule. Returnează o valoare mai mică decât zero dacă s1 este mai mic
strcasecmp(s1, s2)
decât s2, o valoare mai mare decât zero dacă s1 este mai mare decât s2,
respectiv 0 în celelalte cazuri.
Execută o comparaţie cu sensibilitate la diferenţa între majuscule şi
minuscule. Returnează o valoare mai mică decât zero dacă s1 este mai mic
strcmp(s1, s2)
decât s2, o valoare mai mare decât zero dacă s1 este mai mare decât s2,
respectiv 0 în celelalte cazuri.
strncasecmp(s1, La fel ca strcasecmp() doar că la comparaţie sunt luate în considerare un
s2, n) număr de n caractere.
La fel ca strcmp() doar că la comparaţie sunt luate în considerare un număr
strncmp(s1, s2, n)
de n caractere.
Descoperirea şi extragerea sub-şirurilor

PHP include numeroase funcţii care găsesc şi extrag sub-şiruri, adică părţi dintr-un şir. Cele
mai importante funcţii de acest gen sunt rezumate mai jos:

Funcţie Descriere
Returnează toate şirurile s1 de la prima apariţie a şirului s2 şi până la
strchr(s1, s2) sfârşit. Dacă s1 nu este găsit, funcţia returnează FALSE. Funcţia strstr()
execută aceeaşi operaţie.
Returnează toate şirurile s1 de la prima apariţie a şirului s2 şi până la
sfârşit. Dacă s1 nu este găsit, funcţia returnează FALSE. Şirurile s1 şi s2
stristr(s1, s2)
sunt comparate fără a se ţine cont dacă literele sunt majuscule sau
minuscule.
Returnează poziţia întreagă a primei apariţii a şirului s2 în s1. Dacă s2 nu
strpos(s1, s2)
este găsit, funcţia returnează FALSE.
Returnează toate şirurile s1 de la ultima apariţie a şirului s2 şi până la
strrchr(s1, s2) sfârşit. Dacă s1 nu este găsit, funcţia returnează FALSE. La comparaţie este
folosit numai primul caracter al şirului s2.
Returnează toate şirurile s1 de la prima apariţie a şirului s2 şi până la
strstr(s1, s2) sfârşit. Dacă s1 nu este găsit, funcţia returnează FALSE. Funcţia strchr()
execută aceeaşi operaţie.
substr(s, start) Returnează porţiunea şirului s specificată de indexul întreg start,
substr(s, start,
respectiv de indexurile start şi lung. Prima poziţie a şirului este poziţia 0.
lung)

Mai jos este dat un exemplu care foloseşte funcţiile de mai sus:

Cod:

<?php
$s = "de la deal la vale si iar inapoi la vale mergand spre deal";
$b = "al";
$n = strpos($s, $b);
echo "<br>strpos(\"$s\", \"$b\"): $n";

$n = strchr($s, $b);
echo "<br>strchr(\"$s\", \"$b\"): $n";

$n = strrchr($s, $b);
echo "<br>strrchr(\"$s\", \"$b\"): $n";

$rezultat = substr($s, 6, 4);


echo "<br>substr(\"$s\", 6, 4): $rezultat";
?>

O potenţială dificultate în utilizarea funcţiei strpos() constă în aceea că poate fi greu de sesizat
diferenţa dintre valoarea returnată 0, care arată că sub-şirul a fost găsit în poziţia iniţiala a
şirului, şi valoarea returnată FALSE, care arată că sub-şirul nu a fost găsit. Mai jos este un
scurt exemplu care indică un mod adecvat de testare a valorii returnate de funcţia strpos(),
astfel încât să se poată face diferenţa între cele două rezultate:

$poz = strpos(s1, s2);


if ($poz === FALSE)
{
// sub-sirul nu a fost gasit...
}

Procedeul prezentat foloseşte operatorul de identitate (===) pentru a determina dacă


valoarea returnată este identică (nu doar aritmetic egală) cu valoarea FALSE. Dacă folosiţi în
schimb operatorul de egalitate (==), este posibil ca rezultatul să fie incorect; FALSE are
valoarea numerică 0, valoare returnată şi dacă sub-şirul este găsit în poziţia initială a şirului.
Acest procedeu presupune utilizarea versiunii PHP 4.0b3 sau a unei versiuni ulterioare; în
versiunile anterioare ale limbajului PHP, funcţia strpos() returna o valoare şir.

Înlocuirea unui sub-şir

O operaţie frecvent folosită în programare constă în găsirea unui sub-şir şi înlocuirea sa cu o


valoare nouă. PHP are două funcţii deosebit de utile pentru asemenea operaţii, şi anume
str_replace()şi substr_replace().

Funcţie Descriere
Se caută în şirul subiect sub-şirul cauta; dacă sub-şirul este găsit,
str_replace(cauta,
returnează valoarea subiect, înlocuindu-se prima apariţie a şirului cauta
inlocuire, subiect)
cu inlocuire.
substr_replace(subiect,
Returnează valoarea subiect, înlocuind sub-şirul care începe de la start
inlocuire, start,
şi având lungimea lungime cu şirul inlocuire.
lungime)

Remarcaţi că funcţia str_replace() notează sub-şirul prin valoarea sa, în timp ce funcţia
substr_replace() noteaza sub-şirul prin pozitia sa în interiorul şirului subiect. Mai jos aveţi un
exemplu de utilizare a acestor funcţii:

Cod:

<?php
$subiect = "de la deal la vale si iar inapoi la vale mergand spre deal"
;
$cauta = "deal";
$inlocuire = "DEAL";
$rezultat = str_replace($cauta, $inlocuire, $subiect);
echo "<br>str_replace(\"$cauta\", \"$inlocuire\", \"$subiect\"): $rezul
tat";

$rezultat = substr_replace($subiect, $inlocuire, 6, 4);


echo "<br>substr_replace(\"$subiect\", \"$inlocuire\", 6, 4): $rezultat"
;
?>

Scrierea expresiilor regulate

În articolul Funcţii PHP pentru expresii regulate am vorbit despre semnificaţia caracterelor care
se află într-un sablon. În continuare o să detaliez mai mult expresiile regulate.

- Să presupunem, de exemplu, că doriţi să specificaţi un şir care poate include litera b sau
litera c. Puteţi face aceasta folosind expresia regulată [bc]. Prin includerea valorilor posibile
între paranteze, formaţi o expresie regulată echivalentă cu formularea "alege oricare din
aceste valori".
- Să presupunem că doriţi să specificaţi un şir care poate include orice vocală; expresia
regulată [aeiou] vă poate fi de ajutor. Dacă doriţi să permiteţi şi utilizarea majusculelor, puteţi
scrie [aeiouAEIOU].
- Să presupunem că doriţi să specificaţi un şir care poate include orice caracter scris cu
majuscule. Puteţi scrie [abcdefghijklmnopqrstuvwxyz] sau puteţi folosi forma mai compactă
[a-z], unde prin cratimă se înţelege o serie de caractere consecutive.
- Să presupunem că doriţi să specificaţi şirurile sat, mat şi lat. Pentru aceasta, aveţi nevoie de
expresia regulată [sml]at. Semnificaţia acestei expresii regulate este următoarea: "alege
oricare dintre literele s, m şi l şi scrie după litera respectivă literele at".
- Dacă un caracter ^ este primul simbol menţionat între parantezele drepte, acesta are ca
efect inversarea semnificaţiei expresiei regulate plasate între paranteze. De exemplu, expresia
regulatî [^a-z] corespunde oricărui caracter diferit de un caracter scris cu minuscule.
- Pentru a specifica faptul că o expresie regulată se poate repeta, expresia regulată va fi
urmată de o pereche de paranteze acolade, care includ limitele superioară şi inferioară ale
repetiţiei. De exemplu, expresia regulată [aerou]{1,4} corespunde unui şir care este compus
din 1-4 vocale.
- Pentru a specifica repetarea mai multor părţi ale unei expresii regulate, includeţi părţile
respective între paranteze. De exemplu, expresia regulată ([sml]at){1,2} corespunde unui
număr de una sau două repetări ale oricăruia dintre şirurile "sat", "mat" sau "lat".
- Unele valori care se repetă sunt atât de frecvent folosite, încât au abrevieri:

Abreviere Semnificaţie
+ {1,n}, unde n este un număr arbitrar de mare
* {0,n}, unde n este un număr arbitrar de mare
? {0,1}

- Să presupunem că doriţi să reprezentaţi o înmulţire. Dacă folosiţi caractere minuscule pentru


operanzi, puteţi obţine ceva de genul [a-z]*[a-z]. Totuşi, această expresie regulată nu are
semnificaţia dorită, deoarece * este un factor de repetiţie, nu un caracter dintr-un şir. Pentru a
dezactiva semnificaţia specială a caracterului *, trebuie să îl prefixaţi cu un caracter
backslash: [a-z]\*[a-z].
- Pentru a specifica faptul că o expresie regulată corespunde numai unui sub-şir care include
caracterul iniţial al unui şir subiect, prefixaţi expresia regulată cu un caracter ^. De exemplu,
expresia regulată ^[sml]at corespunde sub-şirurilor "sat", "mat" sau "lat" numai dacă acestea
apar la începutul şirului subiect.
- Similar, pentru a arăta că o expresie regulată corespunde numai unui sub-şir care include
caracterul final al unui şir subiect, anexaţi la expresia regulată caracterul $. De exemplu,
expresia regulată [sml]at$ corespunde sirurilor "sat", "mat" sau "lat" numai dacă acestea apar
la sfârşitul şirului subiect.
- Expresia regulată ^[sml]at$ corespunde sub-şirurilor "sat", "mat" sau "lat" numai dacă şirul
subiect este identic cu unul dintre aceste sub-şiruri.

Pentru uşurinţa creeri unor expresii regulate puteţi utiliza şi un program de genul Regex Coach
cu care să va faceţi propria expresie pe care apoi să o folosiţi în scripturile dvs.

Utilizarea variabilelor cookie

Variabilele cookie sunt utile pentru stocarea preferinţelor utilizatorilor şi a altor informaţii care
trebuie reţinute atunci când utilizatorul trece la o nouă pagină web. Valorile majorităţii
variabilelor dispar atunci când scriptul PHP care le conţine îşi încheie execuţia. Spre deosebire
de acestea, valorile variabilelor cookie se pot păstra un timp indefinit. Browserul utilizatorului
stocheaza variabilele cookie în unitatea de hard-disk locală a utilizatorului.
La ce este utilă o variabilă cookie? De exemplu pentru păstrarea preferinţelor utilizatorului.
Când utilizatorul revine la pagina vizitată, variabilele cookie permit browserului să recunoască
utilizatorul şi să restaureze opţiunile selectate de utilizator. Din pacate, variabilele cookie nu
constituie soluţia perfectă pentru un mediu de stocare pe termen lung şi prezintă o serie de
dezavantaje cum ar fi:
- Un utilizator poate dezactiva variabilele cookie prin stabilirea unei opţiuni a browserului.
- În anumite situaţii, variabilele cookie pot fi vizualizate de alţi utilizatori.
- Un site poate stoca numai 20 de variabile cookie şi numai 4 KB de informaţii în unitatea de
hdd locală a utilizatorului.
- Numeroase versiuni ale browserelor frecvent folosite au erori care le împiedică sa folosească
variabilele cookie în mod adecvat.
În ciuda acestor dezavantaje, variabilele cookie rămân cea mai populara tehnică pentru
obţinerea unui mediu de stocare pe termen lung.

Accesul la o variabilă cookie

Dacă aţi creat o variabilă cookie, valoarea acesteia este automat pusă la dispoziţie ca variabilă
PHP având acelaşi nume cu acela al variabilei cookie. De exemplu, să presupunem că aţi creat
o variabilă cookie denumită "anotimp" şi că îi atribuiţi valoarea "vara". Această pereche nume-
valoare este apoi pusă la dispoziţia fiecărui script PHP asociat paginilor dvs de web. Deci puteţi
afişa valoarea variabilei cookie folosind următoarea instrucţiune:

echo "Valoarea variabilei cookie este $anotimp";

Această comandă va afişa:

Valoarea variabilei cookie este vara

Variabila PHP de tip tablou asociativ HTTP_COOKIE_VARS conţine numele şi valoarea fiecărei
variabile cookie curentă. Dacă doriţi să vizualizaţi fiecare variabilă cookie disponibilă şi
valoarea acesteia, puteţi invoca funcţia phpinfo(), care afişează valoarea tabloului
HTTP_COOKIE_VARS. De asemenea puteţi folosi şi următorul script pentru a afişa toate
numele şi valorile variabilelor cookies:

foreach ($HTTP_COOKIE_VARS as $nume => $valoare)


echo "<br>$nume => $valoare";

Crearea unei variabile cookie

Pentru a crea o variabilă cookie, trebuie invocată funcţia setcookie(), care are următoarea
sintaxă:

setcookie(nume, valoare, expirare)

Argumentul nume specifică numele variabilei cookie, iar argumentul valoare specifică valoarea
variabilei. Argumentul expirare indică momentul expirării variabilei cookie; după ora
specificată, variabila cookie nu mai este accesibilă. În general, este convenabil să se specifice
momentul expirării folosind funcţia time(), care returnează intervalul de timp (exprimat în
secunde) scurs de la 1 ianuarie 1970. Puteţi adăuga o valoare de tip decalaj (offset), care
specifică intervalul de timp pe durata căruia variabila cookie trebuie să fie accesibilă. De
exemplu:

setcookie ("anotimp", "vara", time()+3600);

Această instrucţiune creează o variabilă cookie denumită "anotimp", care are valoarea "vara".
Variabila cookie va fi disponibilă timp de o ora (3600 secunde) de la crearea sa. Dacă
preferaţi, puteţi specifica momentul expirării folosind funcţia mktime(). Această funcţie are
următoarea formă:

mktime (ore, minute, secunde, luna, zi, an)

De exemplu următoarea inscrucţiune creează o variabilă cookie care expiră la o secundă după
miezul nopţii primei zile a anului 2008:

setcookie("anotimp", "vara", mktime(0,0,1,1,1,2008));

Atenţie!!!
Valorile variabilelor cookie sunt trimise de către browser ca parte a antetelor HTTP. Ca atare,
valorile variabilelor cookie trebuie să fie stabilite anterior expedierii oricăror altor valori către
browser. Trimiterea chiar şi a unui singur spaţiu vă poate împiedica să configuraţi valoarea
unei variabile cookie. Pentru a evita problemele, asiguraţi-vă că un script PHP care stabileşte o
valoare a unei variabile cookie este plasat la începutul fişierului, înainte de a trimite alte taguri
html sau alte caractere către browser. De asemenea, stabiliţi valoarea variabilei cookie înainte
de a executa o instrucţiunie echo sau altă instrucţiune PHP care trimite browserului date de
ieşire. Aceste reguli se aplică la fel şi la crearea sesiunilor despre care am discutat în articolele
de pe acest site.

Ştergerea unei variabile cookie

Deoarece o variabilă cookie are o dată de expirare, aceasta va fi ştearsă automat la un


oarecare interval de timp după crearea sa. Totuşi, puteţi şterge o variabilă cookie imediat.
Pentru aceasta, fixaţi momentul expirării variabilei cookie la un moment de timp din trecut.
Exemplu:

setcookie("anotimp", "", time()-3600);

Această instrucţiune stabileşte timpul de expirare cu o oră (3600 de secunde) în urmă.


Remarcaţi că valoarea variabilei cookie este exprimată sub forma unui şir vid; din moment ce
variabila cookie nu va mai fi disponibilă, valoarea sa nu mai are importanţă.

Stocarea mai multor valori într-o variabilă cookie

Deoarece un site web poate stoca numai 20 de variabile cookie în sistemul unui utilizator,
capacitatea de a stoca mai multe valori într-o singură variabilă cookie este utilă. Pentru
aceasta, inseraţi valorile într-un tablou şi folosiţi funcţia serialize() pentru a "împacheta"
elementele tabloului într-un şir; ulterior, puteţi recupera valoarea tabloului folosind funcţia
unserialize(). Mai jos aveţi un exemplu:

Cod:

<?php
// se creeaza un tablou
for ($i = 0; $i < 30; $i++)
{
$tablou[$i] = $i;
}
// se impacheteaza intregul tablou intr-un sir
$s = serialize($tablou);
// se creeaza o variabila cookie
setcookie("cookies", $s);
if (isset($cookies))
{
// se despacheteaza valoarea variabilei cookie
$rezultat = unserialize(stripslashes($cookies));
// afiseaza elementele tabloului din variabila cookie
foreach ($rezultat as $i => $cookie)
{
echo "<br>$i => $cookie";
}
}
?>

Acest procedeu reuşeşte să ocolească limita celor 20 de variabile cookie dar nu poate depăşi
limita celor 4 KB de date stocate într-o variabilă cookie pentru fiecare site web în parte.

Specificarea accesului la o variabilă cookie

Funcţia setcookie() poate prelua maximum şase argumente, inclusiv trei argumente despre
care nu am discutat încă. Iată formatul complet al funcţiei setcookie():

setcookie(nume, valoare, expirare, cale, domeniu, sigur)

În afară de argumentele nume, valoare, expirare pe care le-am descris în acest articol, mai
este şi argumentul cale care vă permite să specificaţi calea URL asociată variabilei cookie. În
mod prestabilit, variabila cookie este disponibilă pentru scripturile din directorul care conţine
scriptul în care a fost configurată variabila respectivă, precum şi pentru scripturile din sub-
directoarele aferente directorului respectiv. În particular, scripturilor din directoarele părinte
ale directorului care conţine scriptul nu li se permite accesul prestabilit la variabila cookie.
Pentru a pune variabila cookie la dispoziţia scripturilor dintr-un anumit director şi din sub-
directoarele sale, specificaţi o valoare a argumentului cale. De exemplu, pentru a pune
variabila cookie la dispoziţia întregului arbore de directoare, specificaţi "/" ca valoare a
argumentului cale; pentru a face variabila cookie disponibilă în directorul /test şi în sub-
directoarele sale, specificaţi "/test/" ca valoare a argumentului cale. O complicaţie în utilizarea
argumentului cale o constituie modalitatea de identificare a numelor directoarelor. Specificând
"/test/" ca valoare a argumentului cale, variabila cookie va deveni disponibilă în /test1, /test2
şi în toate directoarele cu nume similare, pe lângă directorul /test şi sub-directoarele sale.
Dacă nu este specificat nici un argument domeniu, o variabilă cookie este disponibilă numai
pentru scripturile rezidente pe serverul web care a creat variabila respectivă. Argumentul
domeniu vă permite să specificaţi numele de domeniu asociat unei variabile cookie. În
consecinţa, variabila cookie va fi disponibilă numai pentru paginile web din cadrul domeniului
specificat.
De exemplu, să presupunem că un script din serverul web
http://www.subdomeniu.domeniu.com creează o variabilă cookie. În mod prestabilit, variabila
cookie este disponibilă numai pentru gazda respectivă. Cu toate acestea, puteţi face variabila
cookie disponibilă pe întreg domeniu subdomeniu.domeniu.com, specificând
"subdomeniu.domeniu.com" ca valoare a argumentului domeniu. Specificaţia Netscape pentru
variabile cookie (http://wp.netscape.com/newsref/std/cookie_spec.html) impune ca
argumentul domeniu să conţină minimum două caractere punct. Ca atare, nu trebuie să
specificaţi un şir de tipul "domeniu.com" ca valoare a argumentului domeniu.
Argumentul sigur este o valoare întreagă, care specifică dacă o variabilă cookie trebuie trimisă
prin intermediul unei conexiuni sigure (HTTPS). Specificaţi valoarea 1 pentru a împiedica
transmiterea variabilei cookie în cazul în care conexiunea nu este sigură; pentru a permite
transmiterea variabilei cookie prin conexiuni HTTP obişnuite, specificaţi valoarea 0.

Deoarece browserele stochează variabilele cookie în unitatea de hdd locală, utilizatorii unui
sistem pot obţine accesul la fişierele cookie şi pot citi sau chiar modifica informaţiile conţinute
în fişierele respective. O modalitate de a preveni situaţia prezentată constă în criptarea datelor
stocate în variabilele cookie. Pentru aceasta, puteţi folosi funcţiile Mcrypt din PHP. Funcţiile în
cauză sunt incluse în biblioteca libmcrypt, care nu face parte din versiunea instalată în mod
prestabilit a limbajului PHP.

Deşi argumentele expirareşi cale ale funcţiei setcookie() sunt opţionale, unele versiuni ale
principalelor browsere prezintă erori care le determină să refuze variabilele cookie dacă aceste
argumente nu sunt specificate. Ca atare, în general este recomandat să specificaţi aceste
argumente.

Menţiune:
Înainte de a trimite date HTML unui browser, un server web trimite, în general, unul sau mai
multe antete HTTP; aceste antete sunt cunoscute sub numele de antete de răspuns al
serverului. Similar, înainte de a trimite informaţii unui server web, un browser web trimite, în
general, unul sau mai multe antete HTTP; aceste antete sunt cunoscute sub numele de antete
de cerere. Antetele de răspuns ale serverului frecvent folosite descriu configuraţia serverului şi
furnizează informaţii referitoare la adresa URL solicitată de client. Antetele de cerere utilizate
de obicei descriu configuraţia clientului şi formatele de date acceptabile de către client. În
afară de antetele de răspuns ale serverului şi de antetele de cerere, protocolul HTTP foloseşte
antete generale şi antete de entitate. Antetele generale sunt folosite atât de către clienţi, cât
şi de către servere, pentru a specifica informaţii precum data curentă şi opţiunile de
conexiune. Antetele de entitate descriu formatul datelor schimbate de un client şi un server.

Expedierea mesajelor de poştă electronică

În articolul Transmiterea mesajelor prin e-mail folosind PHP şi PEAR am mai discutat depre
funcţia mail() şi cum se transmite un mesaj cu ajutorul acestei funcţii. În acest articol o să
încerc să aprofundez mai detaliat expedierea şi recepţionarea mesajelor de e-mail.
Configuraţia PHP standard acceptă expedierea mesajelor de e-mail prin intermediul SMTP
(abreviere de la Simple Mail Transfer Protocol). Acesta este protocolul standard folosit pentru
transferul mesajelor de e-mail de la un sistem la altul prin internet. Mesajele de e-mail sunt
alcătuite din două părţi: o serie de antete de mesaj şi un corp. Antetele de mesaj indică
adresa destinatarului şi subiectul mesajului, precum şi alte informaţii. Corpul conţine mesajul
în sine. Un exemplu de trimitere a unui mesaj prin intermediul funcţiei mail:

mail (destinatar, subiect, corp, antete)

unde destinatar indică adresa de e-mail a destinatarului, subiect specifică antetul de e-mail
care conţine subiectul mesajului, corp este corpul mesajului şi antete specifică adresele de e-
mail suplimentare, precum antetul from sau alte antete...
Exemplu:

mail ("adresa_mea@server.ro", "Mesaj de test", "Corpul mesajului", "From:


adresa_mea@server.ro");

Puteţi specifica mai mulţi destinatari prin separarea fiecărui destinatar de următorul prin
intermediul unie virgule:

mail ("adresa1@server1.ro, adresa2@server2.ro, adresa3@server3.ro", "Mesaj de test",


"Corpul mesajului", "From: adresa_mea@server.ro");

Funcţia mail() returnează TRUE dacă serverul SMTP acceptă mesajul; în caz contrar,
returnează FALSE. Reţineţi că acceptarea de către serverul SMTP nu garantează transmiterea
către destinatar a mesajului dvs. Nu există nici o modalitate 100% sigură de a verifica faptul
că mesajul a fost trimis, aşa cum nu există nici o modalitate absolut sigură de a garanta că
destinatarul a citit mesajul, l-a înţeles şi că a fost de acord cu el.
Unele servere SMTP refuză să accepte adrese şi antete care conţin spaţii albe la sfârşit. Pentru
aceasta folosiţi funcţia trim() înainte de a trimite mesajul.

Recepţionarea mesajelor de e-mail


Recepţionarea mesajelor de e-mail este un proces oarecum mai complex decât expedierea lor.
Deşi SMTP face parte din configuraţia PHP standard, IMAP (protocolul de recepţionare a
mesajelor Interim Mail Access Protocol) nu este o componentă a acestei configuraţii. Dacă
administratorul serverului nu a configurat serverul PHP astfel încât să lucreze cu IMAP,
exemplele următoare nu vor funţiona.
Un server IMAP este accesibil în acelaşi mod ca şi un fişier oarecare. Mai întâi, trebuie deschisa
o conexiune cu serverul, apoi se pot trimite cereri serverului şi se pot primi răspunsuri de la
acesta. După terminarea utilizării serverului, trebuie închisă conexiunea. Pentru a deschide o
conexiune cu un server IMAP, folosiţi funcţia imap_open():

imap_open (cutie_postala, identificator_utilizator, parola)

Argumentul cutie_postala specifică patru elemente:


- Numele gazdei sau adresa IP a serverului IMAP
- Protocolul care va fi utilizat (IMAP)
- Portul care se va folosi pentru conectarea serverului (în general 143)
- Cutia poştală care va fi deschisă (în general INBOX)
Argumentul foloseste numeroşi delimitatori pentru a separa un element de altul. Iată o valoare
caracteristică a argumentului:

{localhost/imap:143}INBOX

în cadrul acestui exemplu, numele gazdei este localhost; acest lucru este posibil când un
server PHP şi un server IMAP rulează pe acelaşi sistem gazdă. În caz contrar, trebuie să
specificaţi numele gazdei care rulează sistemul IMAP:

{mail.yahoo.com/imap:143}INBOX

Celelalte argumente ale funcţiei imap_open(), identificator_utilizator şi parola, specifică


identificatorul de utilizator şi parola folosite pentru a obţine accesul la serverul IMAP. Aşa cum
funcţia fopen() returnează un identificator pe care îl puteţi folosi pentru a obţine accesul la un
fişier, la fel şi funcţia imap_open() returnează un identificator pe care îl puteţi folosi pentru a
obţine accesul la serverul IMAP. Dacă PHP nu poate deschide o conexiune cu serverul IMAP,
funcţia imap_open() returneaza FALSE.
Dacă un script se încheie cu mesajul "Call to undefined function: imap_open", aceasta arată că
PHP nu a fost configurat pentru a folosi IMAP.
Exemplu:

Cod:

<?php
$server = "{mail.as.ro/imap:143}";
$utilizator = "php4";
$parola = "parola";
$identificator = imap_open($server."INBOX", $utilizator, $parola);
if ($identificator === false)
{
echo "Nu se poate deschide cutia poatala";
}
?>

În afară de directorul INBOX standard, IMAP permite unui utilizator să definească directoare,
care pot fi folosite pentru stocarea şi organizarea mesajelor primite. În orice moment, un
director IMAP - INBOX sau un alt director - este considerat ca fiind directorul curent. După ce
aţi stabilit o conexiune cu un server IMAP, puteţi cere serverului să desemneze alt dosar ca
dosar curent:

Cod:

<?php
$server = "{mail.as.ro/imap:143}";
$utilizator = "php4";
$parola = "parola";
$identificator = imap_open($server."INBOX", $utilizator, $parola);
if ($identificator === false)
{
echo "Nu se poate deschide cutia poatala";
}
else
{
// se schimba directorul curent
$prefix = "~/mail/";
$director = $server.$prefix."INBOX"."nume_director";
$schimba = imap_reopen($identificator, $director);
if ($schimba === false)
{
echo "Nu se poate deschide directorul specificat";
}
}
?>

De obicei, numele directoarelor IMAP sunt obţinute prin prefixarea numelui dosarului cu
particula "~/mail/" şi "INBOX", aşa cum am arătat în exemplu. Cu toate acestea, un
administrator de sistem poate configura o altă politică de atribuire a numelor.
Dacă doriţi să afişati directoarele existente în căsuţa de mail puteţi folosi următorul script:

Cod:

<?php
echo "Lista directoarelor";
$directoare = imap_listmailbox($identificator, $server, $prefix, "*");
if ($directoare == false)
{
echo "A aparut o eroare la afisarea directoarelor";
}
else
{
foreach ($directoare as $cheie=>$valoare)
{
echo "\n $cheie=>$valoare";
}
}
?>

Dacă doriţi să creaţi un director nou folosiţi funcţia imap_createmailbox() astfel:


Cod:

<?php
$director = "diverse";
$director = $server.$prefix."INBOX.".$director;
$creare = imap_createmailbox($identificator, $director);
if ($creare === false)
{
echo "Nu s-a putut crea directorul";
}
?>

Numele unui director IMAP trebuie să conţină numai litere, cifre şi caractere de subliniere.
Dacă doriţi să creaţi un sub-director, puteţi proceda astfel incluzând un punct în numele
directorului. Punctul se comportă ca separator de cale, analog caracterului slash folosit în căile
din cadrul sistemului de fişiere.
Pentru modificarea numelui unui director din căsuţa de email folosiţi funcţia
imap_renamemailbox() astfel:

Cod:

<?php
$director_vechi = $server.$prefix."INBOX.".$director_vechi;
$director_nou = $server.$prefix."INBOX.".$director_nou;
$modificare = imap_renamemailbox($identificator, $dosar_vechi, $dosar_n
ou);
if ($modificare === false)
{
echo "A aparut o eroare la modificarea numelui directorului";
}
?>

Pentru ştergerea unui director folosiţi funcţia imap_deletemailbox():

Cod:

<?php
$director = $server.$prefix."INBOX.".$director;
$stergere = imap_deletemailbox($identificator, $director);
if ($stergere === false)
{
echo "A aparut o eroare la stergerea directorului";
}
?>

Spre deosebire de mesajele IMAP care rămân în cutia poştală până când le ştergeţi, un
director IMAP şters este eliminat imediat şi în mod irevocabil. Fiţi atenţi atunci când scrieţi
programe care şterg directoare sau atunci când folosiţi scripturi care conţin asemenea
programe.
După deschiderea unei conexiuni IMAP, puteţi obţine acces la informaţii care descriu cutia
poştală curentă. De exemplu, pentru a afla câte mesaje sunt în cutia poştala se invocă funcţia
imap_num_msg():
imap_num_msg($identificator)

În continuare este o variantă prin care puteţi obţine diferite informaţii despre conţinutul cutiei
poştale:

Cod:

<?php
$nr_mesaje = imap_num_msg($identificator);
echo "Cutia postala contine $nr_mesaje mesaje";
$nr_mesaje_recente = imap_num_recent($identificator);
echo "Cutia postala contine $nr_mesaje_recente mesaje recente";
$obiect_cutie_postala = imap_mailboxmsginfo($identificator);
if ($obiect_cutie_postala)
{
$tablou_cutie_postala =&;nbsp;get_object_vars($obiect_cutie_postala
);
foreach ($obiect_cutie_postala as $cheie=>$valoare)
{
echo "\n $cheie: $valoare";
}
}
?>

Rezultatul de ieşire al scriptului va fi:

Citat:

Cutia postala contine x mesaje


Cutia postala contine y mesaje recente
Unread: 0
Deleted: 0
Nmsgs: x
Size: dimensiunea in octeti a mesajelor
Date: data
Driver: imap
Mailbox: numele cutiei postale
Recent: y

Se mai poate utiliza şi varianta următoare:

Cod:

<?php
echo "Afisarea starii cutiei postale";
$obiect_cutie_postala = imap_mailboxmsginfo($identificator);
print_r($obiect_cutie_postala);
?>
Funcţia PHP print_r() afişează valoarea unui obiect. Această metodă este cu mult mai simplă
decât cea folosită anterior, dar formatul datelor de ieşire este cu mult mai puţin inteligibil.
În continuare este un exemplu care afişează o listă de mesaje din directorul curent:

Cod:

<?php
echo "Antete de mesaje in cutia postala curenta:"
$antete = imap_headers($identificator);
if ($antete == false)
{
echo "A aparut o eroare la afisarea mesajelor";
}
else
{
foreach ($antete as $cheie=>$valoare)
{
echo "\n $valoare";
}
}
?>

Funcţia imap_headers() returnează un tablou unde fiecare element descrie un mesaj din
directorul curent.
O chestie ciudată a serviciului IMAP constă în aceea că fiecare mesaj dintr-un director are atât
un număr, cât şi un identificator. Numărul reprezintă poziţa mesajului în directorul respectiv;
această valoare se poate modifica la adăugarea mesajelor, respectiv la ştergerea mesajelor
din dosar. Pe de altă parte, identificatorul unui mesaj nu se modifică niciodată. IMAP
furnizează funcţii care vă permit să determinaţi identificatorul unui mesaj dacă este dat
numărul său şi invers. Iată funcţiile descrise mai jos:

imap_uid($identificator, $numar)

si

imap_msgno($identificator, $id)

O limitare a funcţiei imap_headers() este aceea că nu separă fiecare caracteristică a mesajului


în câmpuri distincte, astfel încât acestea să fie uşor accesibile pentru un script. Funcţia de
bibliotecă IMAP imap_fetch_overview() returnează un tablou asociativ care descrie un mesaj.
Iată un exemplu care afişează informaţiile despre mesaje:

Cod:

<?php
$nr_mesaj = 1;
$mesaje = imap_fetch_overview($identificator, $nr_mesaj, 0);
foreach ($mesaje as $mesaj)
{
foreach ($mesaj as $proprietate=>$valoare)
{
echo "\n $proprietate: $valoare";
}
}
?>

Al doilea argument al funcţiei imap_fetch_overview() vă permite să specificaţi o listă sau un


domeniu de mesaje pentru care funcţia returnează vederi de ansamblu. Datele de ieşire conţin
următoarele informaţii:

- subiectul mesajului
- numele şi adresa de e-mail ale expeditorului
- data la care a fost trimis mesajul
- numărul mesajului
- identificatorul mesajului
- dimensiunea mesajului în octeţi
- indicatoare care precizează dacă:
= mesajul este recent
= mesajul a fost citit
= mesajul a primit un răspuns
= mesajul a fost marcat în vederea ştergerii
= mesajul este o ciornă

Pentru a obţine corpul unui mesaj (care include conţinutul efectiv al mesajului) putem utiliza
scriptul de mai jos:

Cod:

<?php
// afisare dupa numar
$numar = imap_msgno($identificator, $id)
$corp = imap_body($identificator, $numar, FT_UID);
echo $corp;
?>

Antetele de mesaj conţin informaţii importante, care în general nu apar în corpul mesajului,
precum data şi subiectul mesajului. Mai jos este dată o variantă de afişare a acestor
informaţii:

Cod:

<?php
$n = 0;
$numar = 0;
$obiect_antet = imap_header_info($identificator, $numar);
$antete = get_object_vars($obiect_antet);
foreach ($antete as $proprietate=>$valoare)
{
if (!is_array($valoare))
{
echo "\n $proprietate: $valoare";
}
else
{
foreach ($valoare as $sub_valoare)
{
echo "\n $proprietate: ";
$sub_valori = get_object_vars($sub_valoare);
for_each ($sub_valoare as $articol=>$valoare_articol)
{
echo "\n $articol=>$valoare_articol";
}
}
}
}
?>

Obiectul returnat de funcţia de biblioteca IMAP imap_headerinfo() include următoarele


informaţii:

- data expedierii mesajului


- subiectul mesajului
- Identificatorul mesajului la care s-a răspuns prin acest mesaj, dacă există
- indicatoare de mesaj, cum sunt cele returnate de funcţia imap_fetch_overview()
- numele şi adresa de e-mail ale:
= expeditorului
= persoanei care primeşte răspunsul, dacă este specificată
= destinatarilor
= destinatarilor eventualelor copii (cc:)
= destinatarilor eventualelor copii la indigo necunoscute (bcc:), dacă informaţiile respective
sunt disponibile
Numeroase elemente ale tabloului asociativ au valori de tip tablou. Pentru parcurgerea
iterativă şi afişarea valorii acestor elemente se foloseşte o buclă îmbricată.
Pentru aplicaţi mai puţin pretenţioase se poate utiliza exemplul următor:

Cod:

<?php
$antete = imap_headerinfo($identificator, $numar);
print_r($antete);
?>

Folosind funcţia print_r() se generează date de ieşire mai puţin inteligibile.

Pentru a şterge un mesaj IMAP, mai întâi îl marcaţi în vederea ştergerii şi apoi îl eliminaţi.
Mesajele marcate pentru ştergere, dar care nu au fost încă eliminate, sunt numai semnalate
ca şterse şi sunt în continuare accesibile. Iată un exemplu care vă permite să ştergeţi un
mesaj prin specificarea numărului sau a identificatorului mesajului:

Cod:

<?php
$stergere = imap_delete($identificator, $id, FT_UID);
if ($stergere == false)
{
echo "Nu se poate sterge mesajul";
}
?>
Pentru a elimina mesajele şterse, testaţi următorul script:

Cod:

<?php
$eliminare = imap_expunge($identificator);
if ($eliminare == false)
{
echo "Nu s-a reusit eliminarea mesajelor";
}
?>

În cazul în care doriţi să vedeţi exact ce eroare a returnat una din funcţiile bibliotecii IMAP,
puteţi folosi funcţia imap_errors() astfel:

Cod:

<?php
$erori = imap_errors();
if ($erori)
{
foreach ($erori as $cheie=>$valoare)
{
echo "\n $cheie: valoare";
}
}
?>

Pentru copierea unui mesaj din directorul curent într-un alt director se poate folosi funcţia
imap_mail_copy() astfel:

Cod:

<?php
$numar = 0;
$director = $prefix."INBOX.".$director;
echo "Se copiaza mesajul $numar in directorul $director";
$nr_mesaje = "".$numar;
$copiere = <;/span>imap_mail_copy($identificator, $nr_mesaje, $director
);
if ($copiere === false)
{
echo "A aparut o eroare la copierea mesajului specificat";
}
?>

Deoarece serverele IMAP nu coopereaza la copierea unui mesaj de la un server la altul, nu


este necesar - sau posibil - să se specifice numele gazdei serverului la copierea mesajelor
IMAP.
Când aţi terminat de utilizat un server IMAP, trebuie să îl închideţi, aşa cum închideţi un fişier
atunci când aţi terminat cu el. Iată cum se poate închide o conexiune IMAP:
Cod:

<?php
$inchidere = imap_close($identificator);
if ($inchidere === false)
{
echo "Nu se poate inchide cutia postala";
}
?>

Biblioteca IMAP furnizează multe alte funcţii în afara celor descrise în acest articol. De
exemplu, funcţiile imap_search() şi imap_scanmailbox() vă permit să căutaţi mesaje care
satisfac criteriile specificate. De exemplu, puteţi căuta mesaje al căror corp conţine anumite
texte.
În cazul în care furnizorul de servicii internet dispune de un server POP, nu de un server IMAP,
puteţi avea acces la cutia poştală POP cu ajutorul sistemului PHP, folosind biblioteca IMAP. Pur
şi simplu deschideţi o conexiune cu serverul POP specificând o cutie poştala POP astfel:

$mbox = imap_open("{localhost/pop3:110}INBOX", $identificator_utilizator, $parola);

Numele gazdei, protocolul şi numărul portului sunt asemănătoare cu valorile similare folosite
pentru conectarea la un server IMAP. De asemenea, puteţi folosi biblioteca IMAP pentru a vă
conecta la un server de informaţii folosind NNTP (Network News Transfer Protocol). Pentru
aceasta, deschideţi o conexiune astfel:

$nntp = imap_open("{localhost/nntp:119}comp.test", "", "");

Pentru mai multe informaţii puteţi consulta manualul php de la adresa www.php.net.

Stocarea unor date ierarhice într-o bază de date

Fie că vreţi să vă construiţi propriul forum, să vă publicaţi mesajele dintr-un ‘mailing list' pe
propriul site de pe internet sau să vă scrieţi propriile CMS, va veni un moment când veţi dori
să stocaţi datele ierarhice într-o bază de date. Şi, dacă nu folosiţi o bază de date cu suport
XML, tabelele nu sunt ierarhice; ele nu sunt decât un fişier plat. Va trebui să gasiţi un mod de
a traduce ierarhia într-un fişier plat.

Stocarea arborilor este o problemă obişnuită, cu multiple soluţii. Există 2 abordări importante:
modelul listei adiacente şi algoritmul parcurgerii arborelui cu preordine modificată.

În acest articol vom explora aceste 2 metode de salvare a datelor ierarhice. Ca exemplu voi
folosi arborele dintr-un magazin alimentar fictiv de pe internet. Acest magazin îşi sortează
alimentele după categorie, culoare şi tip. Arborele arată astfel:
Acest articol conţine un număr de exemple de coduri care arată cum se salvează şi se
restabilesc datele. Deoarece folosesc eu însumi acest limbaj şi mulţi alţi oameni îl folosesc sau
îl cunosc, am ales să scriu exemplele în PHP. Probabil că-l puteţi traduce uşor în limbajul pe
care vi-l doriţi.

Metoda recursivă

Prima şi cea mai elegantă abordare pe care o vom încerca se numeşte metoda recursivităţii .
Este o abordare elegantă pentru că veţi avea nevoie de o simplă funcţie care să se repete în
arborele dvs. În magazinul nostru de alimente tabelul arată astfel:

După cum vedeţi salvaţi "părintele" fiecărui nod. Putem vedea că "Pear" este un copil al
lui "Green" care este un copil al "Fruit" s.a.m.d. Nodul rădăcină, "Food", nu are o valoare
parentală. Pentru simplificare, am folosit valoarea "title" pentru a identifica fiecare nod.
Bineânţeles, într-o bază de date reală, ar trebui să folosiţi id-ul numeric al fiecărui nod.

Daţi-mi arborele

Acum că am introdus arborele nostru în baza de date, e timpul să scriem o funcţie de afişare.
Această funcţie va trebui să înceapă la nodul rădăcină - nodul fără nici un părinte – şi ar trebui
după aceea să arate toţi copiii acelui nod. Pentru fiecare dintre aceşti copii, funcţia ar trebui să
restabilească şi să arate toate nodurile copii ale acelui copil. Pentru aceşti copii, funcţia ar
trebui să arate din nou toţi copiii s.a.m.d.

Aşa după cum probabil că aţi observat, există un tipar regulat în descrierea acestei funcţii.
Putem pur şi simplu să scriem o funcţie care restabileşte copiii unui anumit nod părinte. Acea
funcţie ar trebui atunci să pornească o altă instanţă a ei însăşi pentru fiecare dintre aceşti
copii, pentru a-i arăta pe toţi copiii acestora. Acesta este mecanismul recursiv care-i dă
metodei numele de " metoda recursivităţii".

Cod:

<?php
// $parent este parintele copiilor pe care vrem sa-i vedem
// $level creste cand inaintam in arbore,
// folosit pentru a arata un arbore frumos indentat
function display_children($parent, $level)
{
// restabileste toti copiii $parent
$result = mysql_query('SELECT title FROM tree '.'WHERE parent="'.
$parent.'";');
// arata fiecare copil
while ($row = mysql_fetch_array($result))
{
// indenteaza si arata titlul acestui copil
echo str_repeat(' ',$level).$row['title']."\n";
// foloseste din nou aceasta functie pt a arata
// copiii acestui copil
display_children($row['title'], $level+1);
}
}
?>

Pentru a arăta întregul nostru arbore, vom pune în aplicare funcţia cu un "string" gol cum ar
fi $parent şi

$row =0; display_children(' ',0);

Pentru arborele magazinului nostru de alimente funcţia returnează:

Citat:

Food
Fruit
Red
Cherry
Yellow
Banana
Meat
Beef
Pork

Observaţi că, dacă vreţi să vedeţi un sub-arbore, puteţi indica funcţiei să pornească cu un alt
nod. De exemplu, pentru a arăta sub-arborele "Fruit", ar trebui să puneţi în aplicare
display_children('Fruit',0);

Calea către un nod

Cu aproximativ aceeaşi funcţie, puteţi căuta calea spre un nod, dacă ştiţi numele sau id-ul
acelui nod. De exemplu, calea spre "Cherry" este "Food" > "Fruit" > "Red". Pentru a găsi
această cale, funcţia noastră va trebui să pornească la cel mai profund nivel : "Cherry". După
aceea, ea caută părintele acestui nod şi-l adaugă la cale. În exemplul nostru, acesta ar fi
"Cherry". Dacă stim că "Red" este părinte pentru "Cherry", putem calcula calea spre "Cherry",
folosind calea spre "Red". Si acest lucru ne este dat de funcţia pe care tocmai am folosit-o:
căutând în mod recursiv părinţii, vom găsi calea către orice nod din arbore.

Cod:

<?php
// $node este numele nodului a carui cale o dorim
function get_path($node)
{
// cauta parintele acestui nod
$result = mysql_query('SELECT parent FROM tree '.'WHERE title="'.
$node.'";');
$row = mysql_fetch_array($result);
// salveaza calea in aceasta ordine
$path = array();
// continua numai daca acest Snod nu este nodul radacina
// (acesta este nodul fara nici un parinte)
if ($row['parent']!='')
{
// ultima parte a caii spre $nod, este numele
// parintelui lui $node
$path[] = $row['parent'];
// ar trebui sa adaugam calea spre parintele acestui nod
// la cale
$path = array_merge(get_path($row['parent']), $path);
}
// returneaza calea
return $path;
}
?>

Această funcţie restabileşte acum calea către un nod dat. Ea restabileşte calea ca o dispunere,
ca un array, aşa că pentru a arăta calea putem folosi

print_r(get_path('Cherry'));

Dacă faceţi acest lucru pentru "Cherry", veţi vedea că:

Citat:

ARRAY
(
[0] => Food
[1] => Fruit
[2] => Red
)

Dezavantaje

Aşa cum tocmai am văzut, aceasta este o metodă excelentă. E uşor de înţeles şi codul de care
avem nevoie este de asemenea simplu. Atunci care sunt dezavantajele modelului acestei
structuri de date? În majoritatea limbajelor de programare, este lentă şi ineficientă. Acest
lucru se datorează în special recursivităţii. Avem nevoie de o interogare în baza de date pentru
fiecare nod din arbore.

Cum fiecare interogare durează destul de mult, aceasta face ca funcţia să fie foarte lentă când
se aplică pe arbori mari.

Al doilea motiv pentru care această metodă nu este atât de rapidă, este limbajul de
programare pe care probabil îl veţi folosi. Spre deosebire de limbaje cum ar fi Lisp, cele mai
multe limbaje nu sunt concepute pentru funcţii recursive. Pentru fiecare nod, funcţia porneşte
o altă instanţă a ei însăşi. Aşa că, pentru un arbore cu patru nivele, veţi pune în aplicare patru
instanţe ale funcţiei în acelaşi timp. Şi cum fiecare funcţie ocupă o felie de memorie şi are
nevoie de ceva timp pentru a porni, recursivitatea este foarte lentă atunci când este aplicată
pe arbori mari.

Parcurgerea în preordine modificată a arborelui

Acum, să aruncăm o privire asupra unei alte metode de stocare a arborilor. Recursivitatea
poate fi lentă, aşa că n-ar trebui să folosim o funcţie recursivă. Am dori de asemenea să
micşorăm numărul interogărilor în baza de date. Am prefera să avem o singură
interogare pentru fiecare activitate.

Vom începe prin a aşeza arborele nostru în poziţie orizontală. Pornim de la nodul rădăcină
("Food") şi scriem 1 în stânga lui. Urmăm arborele spre "Fruit" şi scriem 2 lângă el. În acest
fel, mergem de-a lungul marginilor arborelui în timp ce scriem câte un număr în stânga şi în
dreapta fiecărui nod. Ultimul număr este scris în dreapta nodului "Food". În această imagine,
puteţi vedea întregul arbore numerotat şi câteva săgeţi care arată ordinea numerotării.

Vom numi aceste numere stângul şi dreptul (de exemplu valoarea stângă pentru "Food" este
1, valoarea dreaptă este 18). După cum vedeţi, aceste numere indică relaţia care se stabileşte
între fiecare dintre aceste noduri. Deoarece "Red" are numerele 3 şi 6, el este un descendent
al nodului 1-18 "Food". În acelaşi fel, putem spune că toate nodurile cu valorile din stanga mai
mari decât 2 şi valorile din dreapta mai mici decât 11 sunt descendenţi ai nodului 2-11 "Fruit".
Structura arborelui este acum stocată în valorile din stânga şi din dreapta. Această metodă de
a merge de jur împrejurul arborelui şi de a număra nodurile se numeşte algoritmul
"Parcurgerea în preordine modificată a arborelui"
Înainte de a continua, să vedem cum arată aceste valori în tabelul nostru:

După cum observaţi, cuvintele "left" şi "right" au un înţeles special în SQL. De aceea, va trebui
să folosim "lft" şi "rgt" pentru a identifica coloanele. Observaţi de asemenea că nu prea mai
avem nevoie de coloana părinte . Avem acum valorile "lft" şi "rgt" pentru a stoca structura
arborelui.

Extragerea datelor din Arbore

Dacă vreţi să arătaţi arborele folosind un tabel cu valorile din stânga şi din dreapta, va trebui
mai întâi să identificaţi nodurile pe care vreţi să le restabiliţi. De exemplu, dacă vreţi sub-
arborele "Fruit", va trebui să selectaţi numai nodurile cu o valoare-stânga cuprinsă între 2 şi
11. În SQL, aceasta ar însemna:

SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;

Această interogare returnează:

Ei bine, iată un arbore întreg într-o singură interogare. Pentru a arăta acest arbore aşa cum
am procedat cu funcţia noastră recursivă, va trebui să adăugăm o clauză ORDONEAZA DUPA la
această interogare. Dacă adăugaţi şi ştergeţi rânduri din tabelul dvs, probabil că el nu va fi în
ordinea corectă. De aceea, ar trebui să ordonăm rândurile după valoarea lor din stânga.

SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;

Ultima problemă care ne-a mai rămas este indentarea.

Pentru a arăta structura arborelui, copiii ar trebui indentaţi ceva mai mult decât părintele lor.
Putem face aceasta, păstrând o stivă a valorilor din dreapta. De fiecare dată când începeţi cu
copiii unui nod, adăugaţi valoarea din dreapta a acelui nod la stivă. Ştiţi că toţi copiii acelui
nod au o valoare-dreapta mai mică decât valoarea din dreapta a părintelui, aşa că, dacă o să
comparaţi valoarea din dreapta a nodului curent cu ultimul nod din dreapta aflat în stivă, o să
puteţi vedea dacă încă mai arătaţi copiii acelui părinte. Când aţi terminat de arătat un nod,
îndepărtaţi valoarea sa din partea dreaptă din stivă. Dacă veţi număra elementele din stivă,
veţi obţine nivelul nodului curent.

Cod:

<?php
function display_tree($root)
{
// acum, restabileste toti descendentii nodului $root
$result = mysql_query('SELECT lft, rgt FROM tree '.'WHERE title="'.
$root.'";');
$row = mysql_fetch_array($result);
// incepe cu o stiva $right goala
$right = array();
// acum, restabileste toti descendentii nodului $root
$result = mysql_query('SELECT title, lft, rgt FROM tree '.
'WHERE lft BETWEEN '.$row['lft'].' AND '.
$row['rgt'].' ORDER BY lft ASC;');
// arata fiecare rand
while ($row = mysql_fetch_array($result))
{
// verifica stiva numai daca exista una
if (count($right)>0)
{
// verifica daca ar trebui sa indepartam un nod din stiva
while ($right[count($right)-1]<$row['rgt'])
{
array_pop($right);
}
}
// arata titlul nodului indentat
echo str_repeat(' ',count($right)).$row['title']."\n";
// adauga acest nod la stiva
$right[] = $row['rgt'];
}
}
?>

Dacă veţi folosi acest cod, veţi obţine exact acelaşi arbore pe care l-aţi obţinut cu funcţia
recursivă discutată mai sus. Noua noastră funcţie va fi probabil mai rapidă, nu este recursivă
şi foloseşte doar două interogări

Calea către un nod

Cu acest nou algoritm, va trebui de asemenea să găsim un nou mod de a obţine calea către un
anumit nod. Pentru a obţine această cale, vom avea nevoie de o listă a tuturor strămoşilor
acelui nod.

Cu structura noului nostru tabel, nu este foarte greu. Când vă uitaţi, de exemplu, la nodul 4-
5 "Cherry", o să vedeţi că valorile din stânga ale tuturor strămoşilor sunt mai mici decât 4, în
timp ce toate valorile din dreapta sunt mai mari decât 5. Pentru a obţine toţi strămoşii, putem
folosi această interogare:

SELECT title FROM tree WHERE lft < 4 AND rgt > 5 ORDER BY lft ASC;
Observaţi că, întocmai ca în investigaţia noastră precedentă, trebuie să folosim clauza
ORDONEAZA DUPA pentru a sorta nodurile. Această interogare va returna:

Citat:

+-------+
| title |
+-------+
| Food |
| Fruit |
| Red |
+-------

Acum nu ne rămâne decât să intrăm pe fiecare rând pentru a găsi calea spre "Cherry".

Câţi descendenţi

Dacă îmi daţi valorile din stânga şi din dreapta ale unui nod, vă pot spune căţi descendenţi
are, folosind puţină matematică.
Deoarece fiecare descendent incrementează valoarea din dreapta a nodului cu 2, numărul
descendenţilor poate fi calculat cu:

$descendants = (right - left - 1) / 2

Cu această formulă simplă, vă pot spune că nodul 2-11 "Fruit" are 4 noduri descendenţi şi că
nodul 8-9 "Banana" este doar un copil, nu un părinte.

Automatizarea parcurgerii arborelui

Acum că aţi văzut câteva dintre lucrurile uşoare pe care le puteţi face cu acest tabel, e timpul
să învăţăm cum putem automatiza crearea acestui tabel. Cu toate că este un exerciţiu plăcut
atunci când e făcut prima dată şi cu un arbore mic, avem cu adevărat nevoie de un scenariu
care să facă toată această numărătoare şi înconjur al arborelui pentru noi.

Să scriem un scenariu care transformă o listă adiacentă într-un tabel traversal al arborelui cu
preordine modificată.

Cod:

<?php
function rebuild_tree($parent, $left)
{
// valoarea din dreapta a acestui nod este valoarea din stanga + 1
$right = $left+1;
// obtine toti copiii acestui nod
$result = mysql_query('SELECT title FROM tree '.'WHERE parent="'.
$parent.'";');
while ($row = mysql_fetch_array($result))
{
// executarea recursiva a acestei functii pt fiecare
// copil al acestui nod
// $right este valoarea dreapta curenta, care este
// incrementata de functia rebuild_tree()
$right = rebuild_tree($row['title'], $right);
}
// am obtinut valoarea din stanga, si acum ca am procesat
// copiii acestui nod stim si valoarea din dreapta
mysql_query('UPDATE tree SET lft='.$left.', rgt='.$right.' WHERE ti
tle="'.$parent.'";');
// returneaza valoarea din dreapta a acestui nod + 1
return $right+1;
}
?>

Aceasta este o funcţie recursivă. Ar trebui s-o porniţi cu

rebuild_tree('FOOD',1);

atunci funcţia restabileşte toţi copiii nodului "Food".


Dacă nu există copii, ea stabileşte valorile din stânga şi din dreapta ale acestui nod. Valoarea
din stânga este dată, 1, iar valoarea din dreapta este valoarea din stânga plus 1. Dacă există
copii, această funcţie se repetă şi ultima valoare din dreapta este restabilită. Această valoare
este folosită atunci ca valoare din dreapta a nodului "Food".

Recursivitatea face ca această funcţie să fie, prin complexitatea ei, destul de greu de înţeles.
Totuşi, ea ajunge la acelaşi rezultat la care am ajuns noi manual la începutul acestui capitol.
Ea merge în jurul arborelui, adăugând câte un nod pentru fiecare nod pe care îl vede. După ce
aţi pus în aplicare această funcţie, veţi vedea că valorile din stânga şi din dreapta rămân
aceleaşi (o verificare rapidă, valoarea din dreapta a nodului rădăcină ar trebui să fie egală
cu de două ori numărul nodurilor).

Adăugarea unui nod

Cum adăugăm un nod la arbore? Există două abordări: puteţi păstra coloana părinte în tabelul
dvs şi doar să porniţi din nou funcţia rebuild_tree() – o funcţie simplă dar nu aşa de elegantă;
sau puteţi reactualiza valorile din stânga şi din dreapta ale tuturor nodurilor în partea dreaptă
a fiecărui nod nou.

Prima opţiune este simplă. Folosiţi metoda listei adiacente pentru reactualizare şi algoritmul
parcurgerii arborelui cu preordine modificată pentru restabilire. Dacă vreţi să adăugaţi un nou
nod, adăugaţi-l la tabel şi setaţi coloana părinte. Apoi, nu vă rămâne decât să reporniţi funcţia
rebuild_tree(). Această opţiune este uşoară, dar nu foarte eficientă cu arbori mari.

Cea de-a doua modalitate de a adăuga şi şterge noduri constă în reactualizarea valorilor din
stânga şi din dreapta ale tuturor nodurilor în partea dreaptă a noului nod. Să ne uităm la un
exemplu. Vrem să adăugăm un nou tip de fruct, o "Strawberry", ca ultim nod şi copil al "Red".
Mai întâi, va trebui să facem puţin loc. Valoarea - dreapta de la "Red" ar trebui schimbată din
6 în 8, iar nodul 7-10 "Yellow" ar trebui schimbat în 9-12 etc. Reactualizarea nodului "Red"
înseamnă că va trebui să adăugăm 2 la toate valorile din stanga şi din dreapta mai mari decât
5.
Vom folosi interogarea:

UPDATE tree SET rgt=rgt+2 WHERE rgt>5;


UPDATE tree SET lft=lft+2 WHERE lft>5;

Acum putem adăuga un nou nod "Strawberry" pentru a umple noul spaţiu. Acest nod are
valoarea - stânga 6 şi valoarea - dreapta 7.
INSERT INTO tree SET lft=6, rgt=7, title='Strawberry';

Dacă pornim funcţia noastră display_tree();, vom vedea că noul nostru nod "Strawberry" a
fost introdus cu succes în arbore:

Citat:

Food
Fruit
Red
Cherry
Strawberry
Yellow
Banana
Meat
Beef
Pork

Dezavantaje

În primul rând, algoritmul parcurgerii arborelui cu preordine modificată pare greu de înţeles.
Este cu siguranţă mai greu decât metoda listei adiacente. Totuşi, odată ce v-aţi obişnuit cu
proprietăţile valorilor din stânga şi din dreapta, este evident că puteţi face cu această tehnică
aproape tot ce făceaţi cu metoda listei adiacente şi că algoritmul traversal al arborelui cu
preordine modificată este mult mai rapid. Reactualizarea arborelui impune mai multe
investigaţii, ceea ce durează mai mult, dar restabilirea nodurilor se realizează cu o singură
interogare.

Concluzie

Acum v-aţi familiarizat cu ambele metode de stocare a arborilor într-o bază de date. Deşi
prefer oarecum parcurgerea arborelui cu preordine modificată, în cazul dvs. metoda listei
adiacente ar putea fi mai bună. Vă las să judecaţi singuri.

Lecturi suplimentare

Mai multe despre Arbori în SQL de specialistul în baze de date Joe Celko:
http://searchdatabase.techtarget.com/tip/1,289483,sid13_gci537290,00.html

Alte două metode pentru a opera cu datele ierarhice:


http://www.evolt.org/article/Four_ways_to_work_with_hierarchical_data/17/4047/index.html

Xindice, baza de date XLM nativă:


http://xml.apache.org/xindice/

O explicaţie a recursivităţii:
http://www.strath.ac.uk/IT/Docs/Ccourse/subsection3_9_5.html

Autor articol: De Gijs Van Tulder - 30 aprilie 2003


(Traducere efectuată de Dragos după articolul original)
PHP 5, Factory

O să încerc pe parcursul acestui tutorial să explic diferite tehnici introduse în PHP 5 pe care îmi
place să le folosesc (sau mi-ar plăcea).
Motivul?
Data viitoare când am nevoie de ceva asemănător să pot găsi repede şi cât de cât documentat
informaţiile necesare, ţinând cont că la un moment dat voi pierde aceste lucruri printr-un colţ
al hdd-ului.

I. Noţiuni

Încerc să respect cât mai exact regulile publicate sub numele de Coding Standards pe pagina
de web PEAR.
Documentaţia "inline" a claselor, metodelor şi atributelor este foarte folositoare când citesc
codul sursă al unui fişier scris în urmă cu 6 luni.
De obicei folosesc phpDocumentor pentru a genera din codul php documenţii în mod
profesional. Am găsit şi un tutorial aici.

II. Intro

Primul exemplu prezentat în această serie se referă la implementarea conceptului de factory în


php. Acest exemplu nu este complet şi nu poate fi considerat un exemplu standard al ideii de
factory.
Pentru a-mi răspunde la întrebarile "Ce este un Factory?", "La ce mă ajută?", "Este folositor?",
"Se merită?" am citit articolul "The Factory Method" de Harry Fuecks.
Am parcurs cu atenţie codul postat acolo, şi am mai citit şi paginile astea ce fac parte din
prezentarea "2002 International PHP Conference: Applied OO PHP: APIs, Design Patterns and
Useful Objects - Chuck Hagenbuch".
Google mi-a mai adus câteva articole interesante.
Într-un final, m-am hotărât să implementez un exemplu scris în java.

Pentru teste, o să folosesc php CLI şi un director numit trace_factory.

III. Interfaţa.

Din documentaţia prezentată în manual, printr-o interafţă putem creea un obiect care specifică
metodele pe care o clasă trebuie să le implementeze, fără a defini însă comportamentul
acestor metode.

Traducerea interfeţei din java în PHP 5 arată cam aşa:

Cod:

<?php
/**
* Is the Trace Interface
* It contains common methods for every implementation
* @package test.factory.trace
* @access public
*/

interface Trace
{
/**
* Turn on and off debugging
* @param bool debug
*/
public function setDebug($debug);
/**
* Write out a debug message
* @param string message to debug
*/
public function debug($message);
/**
* write out an error message
* @param string message to debug
*/
public function error($message);
}
?>

fişier pe care l-am salvat cu numele de ITrace.php.

Continuând exemplu, vom scrie două implementări, prima, va afişa mesajele în consolă (sau
pagina web dacă se renunţă la CLI) iar cea dea doua, va scrie mesajele într-un fişier text.

IV. StdoutTrace.php

Cod:

<?php
include_once('ITrace.php');
/**
* It display the trace to stdout
*
* @package test.factory.trace
* @access public
*/

class StdoutTrace implements Trace


{
/**
* debug
* @var bool
* @access private
*/
private $debug;
/**
* Sets the debug
* @param bool debug
* @return void
* @access public
*/
public function setDebug($debug)
{
$this->debug = $debug;
}
/**
* It writes a debug message
* only if debug is setted to true
* @param string message
* @return void
* @access public
*/
public function debug($message)
{
if($this->debug)
{
// only print if debug is true
echo date("d-m-Y H:i:s")." DEBUG >>>>".$message."\n";
}
}
/**
* It writes an error message
*
* @param string message
* @return void
* @access public
*/
public function error($message)
{
// always print out errors
echo date("d-m-Y H:i:s")." ERROR >>>>".$message."\n";
}
}
?>

Fişierul l-am salvat cu numele de StdoutTrace.php în acelaşi director.

V. FileTrace.php

Cod:

<?php
include_once('ITrace.php');
/**
* It logs the trace to a file
*
* @todo: implement a custom Exception class
* @package test.factory.trace
* @access public
*/

class FileTrace implements Trace


{
/**
* It`s the file handler
* @var handler
* @access private
*/
private $handler;
/**
* Is the file name
* @var string
* @access private
*/
private $file;
/**
* debug
* @var bool
* @access private
*/
private $debug;
/**
* The construnctor
* it opens the file handler
*
* @param string the file name
* @return void
* @access public
*/
public function __construct($file)
{
// a real FileTrace would need to obtain the filename somewhere
if((!is_file($file)) or (!is_writable($file)))
{
throw new Exception("The file ".$file." is not writable,\n
Or it dosent exist in ".__METHOD__." at ".__LINE__."!\n"
);
}
$this->handler = fopen($file, "a+");
}
/**
* Sets the debug
* @param bool debug
* @return void
* @access public
*/
public function setDebug($debug)
{
$this->debug = $debug;
}
/**
* It writes a debug message
* only if debug is setted to true
* @param string message
* @return void
* @throw Exception
* @access public
*/
public function debug($message)
{
if($this->debug)
{
// only print if debug is true
fwrite($this->handler<;/span>, date("d-m-Y H:i:s")." DEBUG
>>>> ".$message."\n");
}
}
/**
* It writes an error message
*
* @param string message
* @return void
* @throw Exception
* @access public
*/
public function error($message)
{
// always print out errors
fwrite($this->handler, date("d-m-Y H:i:s")." ERROR >>>> ".
$message."\n");
}
/**
* Is the Destructor
* just close the handle
* @access public
* return void
*/
public function __destruct()
{
if($this->handler===true)
{
fclose($this->handler);
}
}
}
?>

Fişierul l-am salvat cu numele de FileTrace.php în acelaşi director.

VI. Factory

Cod:

<?php
include_once('FileTrace.php');
include_once('StdoutTrace.php');

/**
* Is the factory
*
* @access public
* @package test.factory.trace
*/

class TraceFactory
{
/**
* It trys to get a trace
*
* @access public
* @return mixed Trace Interface implementation
*/
public static function &getTrace($file='')
{
try
{
return new FileTrace($file);
}
catch (Exception $ex)
{
$t = new StdoutTrace();
$t->error("Could not instantiate FileTrace: " + $ex-
>getMessage());
return $t;
}
}
}
?>

Salvat cu numele de TraceFactory.php.

VII. Ceva explicaţii

Înainte de a merge mai departe, cred că e timpul să explic ce am făcut până acum. Am
încercat să implementez în PHP 5 un model de factory preluat dintr-un exemplu dat în java.
În partea I, am scris o interfaţă ce conţine trei metode:

setDebug($debug), care îmi va permite să schimb nivelul afişat de trace (debug sau error),
debug($message), o să pot afişa un mesaj de debug (bineânţeles dacă am făcut
setDebug(true) în prealabil).
error($message), va afişa un mesaj de eroare tot timpul (indiferent de valoarea setată
pentru $debug).

În cea de-a doua parte, la fel ca în exemplul pe care l-am urmat, am implementat interfaţa
ITrace în două cazuri, FileTrace ce îmi va permite să log-ez mesajele de eroare/debug într-un
fişier text şi StdoutTrace, ce îmi va permite să afişez aceste mesaje în consolă (pagina web).
Obligatoriu, cele două noi obiecte vor trebui să implementeze metodele prezentate în interfaţa
ITrace.
FileTrace, în exemplul urmat de către mine, trebuia să arunce o excepţie în constructor. Am
decis că în cazul în care fişierul în care vrem să log-ăm mesajele nu există sau nu se poate
scrie în el, să arunc excepţia, însă dacă totul este în regulă, să creez handlerul ( :) ):

$this->handler = fopen($file, "a+").

Am decis să deschid fişierul în mod a+ (read/write; place the file pointer at the end of the
file), cu toate că probabil a era destul (nu intenţionez să şi citesc fişierul). Detalii despre
fopen, aici.
În plus faţă de exemplul urmat, am scris şi un destructor, dar acesta nu era necesar (PHP va
închide automat după terminare executarea codului handlerul?), iar condiţia:

if($this->handler===true)
nu cred că îşi are rostul (poate se întâmplă altceva în $this->handler = fopen($file, "a+") ?).
Am decis, ca în PHP să înlocuiesc atributul:

private java.io.PrintWriter pw

cu $handler, şi am constatat că în PHP pentru a scrie ceva într-un fişier este mai intuitiv şi mai
uşor de reţinut.
Comparaţie:

pw = new java.io.PrintWriter( new java.io.FileWriter( "c:\trace.log" ) ); (nu o să reţint foarte


uşor linia asta)

cu

$this->handler = fopen($file, "a+");

din constructori, sau cu modalitatea de scriere (de exemplu):

pw.println( "DEBUG: " + message );


pw.flush(); (??)

cu

fwrite($this->handler, date("d-m-Y H:i:s") . " DEBUG >>>> " . $message . "\n");

Dar, asta este deja o altă discuţie.


Pentru o mai mare flexibilitate, am decis ca numele fişierului în care să log-ăm mesajele să fie
pasat în constructor (parcă aş vrea să meargă şi pe linux şi pe windows în aceiaşi manieră, nu
folosind un nume de fişier predefinit: c:\trace.log).
Acest lucru, aduce şi modificări directe în factory.
În schimb, în StdoutTrace lucrurile sunt destul de clare, exact ca în exemplu, cu menţiunea că
numele obiectului prezentat în exemplu (SystemTrace), l-am înlocuit cu StdoutTrace.

Voi continua cu explicaţii pentru TraceFactory.


Exact ca în exemplul urmat, am declarat metoda ca fiind statică, adăugând în plus parametrul
$file, reprezentând numele fişierului în care voi loga mesajele.
Folosesc un bloc try/catch pentru a intercepta exceptia aruncată de constructorul din
FileTrace.
Poate că sensul exemplului s-a schimbat în momentul în care am decis să pasez numele
fişierului în care se face logarea.
Ca o mică traducere, încerc (try) să returnez o nouă instanţă a obiectului FileTrace, dacă nu
reuseşc acest lucru (catch), initializez StdoutTrace care va merge sigur având astfel
posibilitatea de a afişa mesajele de eroare/debug.

În partea următoare, o să încerc şi o implementare a acestui exemplu, cu toate că acum este


destul de intuitivă.

VIII. O implementare

Am scris fişierul runTrace.php:

Cod:

<?php
include_once('TraceFactory.php');
$filename = 'logger.log';

touch($filename);

$t = &TraceFactory::getTrace($filename);
$t->error("O eroare de test!");
$t->setDebug(true);
$t->debug("Debug is true");

for($i=1;$i<10;$i++)
{
$t->debug("Tha lup :: ".$i);
}

unset($t);

$t = &TraceFactory::getTrace();
$t->error("Ceva de test!");
$t->setDebug(true);
$t->debug("True Debug");

for($i=1;$i<10;$i++)
{
$t->debug("Za I :: " . $i);
}

$t->error("FOO IS BAR MUST DIE !!!");


?>

După execuţie, în consolă rezultatul a fost:

Citat:

$ php runTrace.php

15-01-2005 14:42:24 ERROR >>>>0


15-01-2005 14:42:24 ERROR >>>>Ceva de test!
15-01-2005 14:42:24 DEBUG >>>>True Debug
15-01-2005 14:42:24 DEBUG >>>>Za I :: 1
15-01-2005 14:42:24 DEBUG >>>>Za I :: 2
15-01-2005 14:42:24 DEBUG >>>>Za I :: 3
15-01-2005 14:42:24 DEBUG >>>>Za I :: 4
15-01-2005 14:42:24 DEBUG >>>>Za I :: 5
15-01-2005 14:42:24 DEBUG >>>>Za I :: 6
15-01-2005 14:42:24 DEBUG >>>>Za I :: 7
15-01-2005 14:42:24 DEBUG >>>>Za I :: 8
15-01-2005 14:42:24 DEBUG >>>>Za I :: 9
15-01-2005 14:42:24 ERROR >>>>FOO IS BAR MUST DIE !!!

iar în fişierul logger.log am:

Citat:

15-01-2005 14:42:24 ERROR >>>> O eroare de test!


15-01-2005 14:42:24 DEBUG >>>> Debug is true
15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 1
15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 2
15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 3
15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 4
15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 5
15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 6

15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 7


15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 8
15-01-2005 14:42:24 DEBUG >>>> Tha lup :: 9

dacă, comentez linia:

touch($filename);

şi şterg fişierul logger.log, rezultatul va fi (normal, doar în consolă, căci constructorul din
FileTrace va arunca excepţia întrucât fişierul nu va exista):

$ php runTrace.php

Citat:

15-01-2005 14:48:59 ERROR >>>>0


15-01-2005 14:48:59 ERROR >>>>O eroare de test!
15-01-2005 14:48:59 DEBUG >>>>Debug is true
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 1
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 2
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 3
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 4
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 5
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 6
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 7
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 8
15-01-2005 14:48:59 DEBUG >>>>Tha lup :: 9
15-01-2005 14:48:59 ERROR >>>>0
15-01-2005 14:48:59 ERROR >>>>Ceva de test!
15-01-2005 14:48:59 DEBUG >>>>True Debug
15-01-2005 14:48:59 DEBUG >>>>Za I :: 1
15-01-2005 14:48:59 DEBUG >>>>Za I :: 2
15-01-2005 14:48:59 DEBUG >>>>Za I :: 3
15-01-2005 14:48:59 DEBUG >>>>Za I :: 4
15-01-2005 14:48:59 DEBUG >>>>Za I :: 5
15-01-2005 14:48:59 DEBUG >>>>Za I :: 6
15-01-2005 14:48:59 DEBUG >>>>Za I :: 7
15-01-2005 14:48:59 DEBUG >>>>Za I :: 8
15-01-2005 14:48:59 DEBUG >>>>Za I :: 9
15-01-2005 14:48:59 ERROR >>>>FOO IS BAR MUST DIE !!!

Totuşi, nu sunt mulţumit de codul scris, şi mai mult, pasând $file ca parametru în factory, şi
implicit şi constructorului din FileTrace m-am îndepărtat prea mult de exemplul de la care am
pornit.
O să încerc să rescriu FileTraceşi TraceFactory pentru a ajunge la utilitatea şi concluziile
prezentate în exemplul urmat:

Citat:

Further, factory methods prove useful when you're not sure what concrete implementation of a class to
instantiate. Instead, you can leave those details to the factory method.
In the above examples your program didn't know whether to create FileTrace or SystemTrace instances.
Instead, you can program your objects to simply use Trace and leave the instantiation of the concrete
implementation to a factory method.

IX. Ceva corecturi

Aşa cum ziceam în finalul ultimului capitol, m-am decis să rescriu FileTrace şi TraceFactory,
pentru a fi cât mai aproape de modelul urmat.

FileTrace.php

Cod:

<?php
include_once('ITrace.php');
/**
* It logs the trace to a file
*
* @todo: implement a custom Exception class
* @package test.factory.trace
* @version 0.2
* @access public
*/
class FileTrace implements Trace
{
/**
* It`s the file handler
* @var handler
* @access private
*/
private $handler;

/**
* debug
* @var bool
* @access private
*/
private $debug;

/**
* The construnctor
* it opens the file handler
*
* @param string the file name
* @return void
* @access public
*/
public function __construct()
{
$file = 'logger.log';
if((!is_file($file)) or (!is_writable($file)))
{
throw new Exception("The file ".$file." is not writable,\nOr
it dosent exist in: ".
__METHOD__." at line: ".__LINE__."!");
}
$this->handler = fopen($file, "a");
}

/**
* Sets the debug
* @param bool debug
* @return void
* @access public
*/
public function setDebug($debug)
{
$this->debug = $debug;
}

/**
* It writes a debug message
* only if debug is setted to true
* @param string message
* @return void
* @access public
*/
public function debug($message)
{
if($this->debug)
{
// only print if debug is true
fwrite($this->handler, date("d-m-Y H:i:s")." DEBUG >>>> ".
$message."\n");
}
}

/**
* It writes an error message
*
* @param string message
* @return void
* @access public
*/
public function error($message)
{
// always print out errors
fwrite($this->handler, date("d-m-Y H:i:s")." ERROR >>>> ".
$message."\n");
}

/**
* Is the Destructor
* just close the handle
* @access public
* return void
*/
public function __destruct()
{
fclose($this->handler);
}
}
?>

TraceFactory.php

Cod:

<?php
/**
* Is the factory
*
* @version 0.2
* @access public
* @package test.factory.trace
*/

class TraceFactory
{
/**
* It trys to get a trace
*
* @access public
* @return mixed Trace Interface implementation
*/
public static function &getTrace()
{
try
{
include_once('FileTrace.php');
return new FileTrace();
}
catch (Exception $ex)
{
include_once('StdoutTrace.php');
$t = new StdoutTrace();
$t->error("Could not instantiate FileTrace:\n".$ex-
>getMessage());
return $t;
}
}
}
?>

X. Alte explicaţii

Am încercat să mă apropii cât mai mult de exemplul pe care l-am urmat.


Mai bine, constructorul din FileTrace, ar putea fi rescris aşa:

Cod:

<?php
function __construct()
{
$file = 'logger.log';
$this->handler = @fopen($file, "a");
if($this->handler===false)
{
throw new Exception("Cannot create the file hanled!");
}
}
?>

însă, pe windows ar fi mai greu de testat, nu ar trebui să existe îngrijorări legate de faptul că
nu aş putea crea fişierul logger.log. Pe linux, ţinând cont de permisiunile care trebuiesc setate
pentru directorul în care lucrez ar fi totuşi posibil.

XI. O altă implementare

Am rescris şi mini testul runTrace.php astfel:

Cod:

<?php
include_once('TraceFactory.php');
$t = &TraceFactory::getTrace();
$t->error("O eroare de test!");
$t->setDebug(true);
$t->debug("Debug is true");
for($i<;/span>=1;$i<10;$i++)
{
$t->debug("Tha lup :: ".$i);
}
unset($t);
$t = &TraceFactory::getTrace();
$t->error("Ceva de test!");
$t->setDebug(true);
$t->debug("True Debug");

for($i=1;$i<10;$i++)
{
$t->debug("Za I :: ".$i);
}
$t->error("FOO IS BAR MUST DIE !!!");
?>

Teste? Rezultatele au fost previzibile. FileTrace nu a aruncat nici o excepţie cu constructorul


din capitolul X deci totul a fost logat în fişierul logger.log.
Pot fi liniştit acum, îmi pot scrie scripturile mai departe, folosind şi o metodă de logare a
evenimentelor produse pe parcursul lor, fără să ma intereseze dacă se produce într-un fişier
sau pe consolă, este treaba factory-ului să decidă lucrul ăsta.

PHP 5, SQLite în Factory?


În articolul anterior am prezentat notiunea de factory în PHP 5. În continuare o să aprofundez
aceste tehnici raportate la o bază de date.

XII. SQLite?

După un timp, am zis să încerc să mai creez încă un produs pentru factory-ul descris în
tutorialul precedent.
Mi-ar fi plăcut să am posibilitatea să log-ez erorile şi mesajele de debug într-un tabel al unei
baze de date.
Şi cum încă nu am avut posibilitatea să lucrez cu SQLite, am decis ca acesta să fie tipul de
bază de date pe care o să îl folosesc.
Prima concluzie?
Dacă vreau să folosesc clientul SQLite din lina de comandă şi apoi să accesez baza de date
creată cu acest client din PHP 5.0 trebuie să folosesc SQLite 2.8.15, nu SQLite 3.0.8. Bazele
de date create cu SQLite 3.0.8 vor putea fi accesate din viitorul PHP 5.1, deci mai am de
asteptat până în a doua jumătate a acestui an.
Ce este SQLite?

Deci, folosind clientul SQLite, versiune 2.8.15 m-am pus pe treabă, şi am creat o bază de date
nouă:

$ sqlite logger.db

Am aflat că îmi pot scrie sql-ul liniştit şi apoi îl pot importa într-o bază de date SQLite.

dump.sql:

Cod:

BEGIN TRANSACTION;
CREATE TABLE logger (id INTEGER PRIMARY KEY,message TEXT,timeEnter DATE
);
CREATE TRIGGER insert_logger_timeEnter AFTER INSERT ON logger
BEGIN
UPDATE logger SET timeEnter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
COMMIT;

Lucruri obişnuite aici:


un tabel cu numele logger, ce conţine un câmp id de tip INTEGER cheie primară, un câmp
message, unde evident voi ţine mesajele şi timeEnter în care voi păstra data introducerii unui
mesaj nou.
În plus, am creat un TRIGGER, astfel la fiecare insert pe care îl voi face, câmpul timeEnter se
va actualiza singur (nu o să fie nevoie să îi mai zic
insert into logger (timeEnter) values DATETIME('NOW'),
insert into logger (message) values ($message)
va fi destul pentru a actualiza cele 3 campuri).
Am descoperit astfel şi triggeri în SQLite, după ce am citit şi tutorialul asta.

Am importat fişierul dump.sql cu comanda:

$ sqlite logger.db < dump.sql

Binarul (fişierul .exe pe Windows) ar trebui să fie în PATH pentru a avea comanda sqlite la
prompt.

XIII. Un nou produs, SQLite

Tinând cont că va trebui să implementez metodele interfeţei Trace şi, urmând exemplul din
FileTrace am scris destul de repede şi uşor SQLiteTrace.php:

Cod:

<?php
// merge cu sqlite 2.8.15 pe php 5.0!
/*
----------> SQL DUMP
BEGIN TRANSACTION;
CREATE TABLE logger (id INTEGER PRIMARY KEY,message TEXT,timeEnter DATE
);
CREATE TRIGGER insert_logger_timeEnter AFTER INSERT ON logger
BEGIN
UPDATE logger SET timeEnter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
COMMIT;
<---------- SQL DUMP
*/

include_once('ITrace.php');
/**
* It logs the trace to a sqlite db
*
* @todo: implement a custom Exception class
* @package test.factory.trace
* @access public
*/
class SQLiteTrace implements Trace
{
/**
* It`s the db handler
* @var handler
* @access private
*/
private $handler;
/**
* debug
* @var bool
* @access private
*/
private $debug;
/**
* The construnctor
* it opens the db handler
*
* @return void
* @access public
*/
public function __construct()
{
$dbname = 'logger.db';
$this->handler = @sqlite_open($dbname, 0666, $sqliteerror);
if($this->handler===false)
{
throw new Exception($sqliteerror);
}
}

/**
* Sets the debug
* @param bool debug
* @return void
* @access public
*/
public function setDebug($debug)
{
$this->debug = $debug;
}

/**
* It writes a debug message
* only if debug is true
* @param string message
* @return void
* @access public
*/
public function debug($message)
{
if($this->debug)
{
// only insert if debug is true
sqlite_query($this->handler, "INSERT INTO logger (message)
VALUES
(' DEBUG >>>> ".$message."')");
}
}

/**
* It writes an error message
*
* @param string message
* @return void
* @access public
*/
public function error($message)
{
// always log errors
sqlite_query($this->handler, "INSERT INTO logger (message) VALU
ES
(' ERROR >>>> ".$message."')");
}

/**
* Is the Destructor
* just close the handler
* @access public
* return void
*/
public function __destruct()
{
@sqlite_close($this->handler);
}
}
?>

XIV. Un nou Creator

Am reuşit să rescriu şi TraceFactory.php astfel:

Cod:

<?php
/**
* Is the factory
*
* @version 0.3
* @access public
* @package test.factory.trace
*/

class TraceFactory
{
/**
* It trys to get a trace
*
* @access public
* @return object Trace, a trace instance
*/
public static function &getTrace()
{
try
{
include_once('FileTrace.php');
return new FileTrace();
}
catch (Exception $ex)
{
try
{
include_once('SQLiteTrace.php');
$t_sqlite = new SQLiteTrace();
$t_sqlite->error("Could not instantiate FileTrace:\n".
$ex->getMessage());
return $t_sqlite;
}
catch(Exception $sqlite_ex)
{
include_once('StdoutTrace.php');
$t = new StdoutTrace();
$t->error("Could not instantiate SQLiteTrace:\n".
$sqlite_ex->getMessage());
return $t;
}
}
}
}
?>

Chiar dacă nu îmi place prea mult blocul:

Cod:

<?php
try
{

}
catch (Exception $ex)
{
try
{

}
catch(Exception $sqlite_ex)
{

}
?>

Tracerul meu este funcţional având 3 metode distincte de a loga mesajele:


într-un fişier,
într-o bază de date sau
direct pe consolă (nu prea o să văd lucrul ăsta prea curând totuşi).

XV. Neajunsuri

În momentul de faţă, sincer să fiu, nu îmi dau seama unde aş putea implementa acest
exemplu.
Aş vrea să îl continui, aducâd în discuţie un alt procedeu: observer, mai mult, mi-ar plăcea să
am mai multe nivele de logare (debug/info/error/alert/emergency).
Metoda getTrace nu mi se pare prea flexibilă, cum ar fi dacă aş vrea să mai adaug încă un
produs acolo?
Probabil ar trebui să o rescriu astfel:

Cod:

<?php
/**
* Is the factory
*
* @version 0.4
* @access public
* @package test.factory.trace
*/
class TraceFactory
{
/**
* It trys to get a trace
*
* @param string driver, it can be File or SQLite
* @access public
* @return object Trace, a trace instance
*/
public static function &getTrace($driver='')
{
$drivers = array('File','SQLite');
if(!in_array($driver, $drivers))
{
include_once('StdoutTrace.php');
return new StdoutTrace();
}
try
{
$rs = $driver.'Trace';
include_once($rs.'.php');
return new $rs();
}
catch (Exception $ex)
{
include_once('StdoutTrace.php');
$t = new StdoutTrace();
$t->error("Could not instantiate ".$driver.":\n".$ex-
>getMessage());
return $t;
}
}
}
?>

iar testul următor, runTrace.php mi-ar loga mesaje în fişierul text în prima parte, în baza de
date SQLite în partea de mijloc şi în final aş afişa şi ceva în consolă:

Cod:

<?php
include_once('TraceFactory.php');
$t = &TraceFactory::getTrace('File');
$t->error("O eroare de test!");
$t->setDebug(true);
$t->debug("Debug is true");
for($i=1;$i<10;$i++)
{
$t->debug("Tha lup :: ".$i);
}
unset($t);
$t = &TraceFactory::getTrace('SQLite');
$t->error("Ceva de test!");
$t->setDebug(true);
$t->debug("True Debug");

for($i=1;$i<10;$i++)
{
$t->debug("Za I :: ".$i);
}
$t->error("FOO IS BAR MUST DIE !!!");

unset($t);
$t = &TraceFactory::getTrace('Unknow_driver');
$t->error("Ajunge in consola!");
$t->setDebug(true);
$t->debug("True Debug a fos setat");

for($i=1;$i<10;$i++)
{
$t->debug("I-ul :: ".$i);
}
$t->error("Fatal!!!");
?>

Rămâne însă de discutat despre diferite niveluri de log şi de introducerea unui observer care
să mă anunţe în cazul în care se produce o eroare în sistem.
Până una-alta, rămân cu PEAR::Log, dar o să continui totuşi acest articol prin introducerea
componentelor de mai sus, cea ce înseamnă un sitem de logare a mesajelor cât de cât
complet şi utilizabil în producţie (chiar dacă constat că SQLite nu este chiar atât de rapid :) ).