Sunteți pe pagina 1din 107

Aplicații în arhitectură client-server

Curs 1

Generalități
Generalități XAMPP Crearea unei aplicații web
De ce client-server?
Deși arhitectura denumită client-server este o soluție de dezvoltare a aplicațiilor relativ
recentă, se poate observa că aplicațiile actuale sunt în marea lor majoritate bazate pe această
arhitectură. Suplețea oferită de posibilitatea separării aplicației în două părți distincte, partea
de reprezentare a informațiilor și partea de producere și prelucrare a acestora, face ca și unele
aplicații de tip desktop să fie realizate în această arhitectură (editorul Atom, Visual Studio
Code și altele).
Dar această arhitectură s-a impus datorită creșterii spectaculoase a numărului de aplicații web
create în ultimii ani. Acestea profită cel mai mult de avantajele oferite de această arhitectură
software.
Cursul va fi axat de alfel doar pe studiul aplicațiilor web, cele de tip desktop fiind
nesemnificative din perspectiva numărului și importanței lor practice.
O aplicaţie web este definită ca fiind alcătuită din două părți principale: o parte care se
execută într-o aplicație de navigare în Internet (componenta client) și o parte care se execută
pe un calculator având rolul de server (componenta server). Pentru fiecare dintre cele două
părți există limbaje și tehnologii dedicate. Asfel, pentru partea executată în aplicația de
navigare, aplicația va consta dintr-un ansamblu de fișiere conținând cod HTML, CSS și
JavaScript. Pentru cealaltă parte, executată pe server, aplicația constă dintr-un ansamblu de
fișiere executabile. Acestea sunt lansate în execuție de o aplicație de tip server de web (de
exemplu Apache sau NGINX), conectată la Internet, care primește comenzi de la componenta
client. Pentru scrierea codurilor componentelor părții de server pot fi utilizate toate limbajele
de programare de uz general (C, C++, Java, Python, C#, etc.) dar și limbaje dedicate (PHP,
PERL).
Spre deosebire de aplicaţiile obişnuite, care pot fi executate numai după obţinerea unui kit de
instalare şi instalarea pe calculator, aplicaţiile web pot fi executate imediat ce interfaţa expusă
de acestea s-a încărcat în fereastra browser-ului. Aceste aplicații sunt deci permanent la
îndemână, nu utilizează spaţiul de stocare al calculatorului pe care rulează și, depinzând doar
de disponibilitatea unui browser, se pot rula utilizând orice terminal pe care este instalată o
astfel de aplicație (deci și pe terminale mobile: telefoane sau tablete).
Tipice pentru această familie de aplicații sunt magazinele virtuale, aplicațiile destinate
schimbării de mesaje (Facebook, Twitter, Instagram), cele destinate poștei electronice, etc..
Observații:
1. Partea de server a unei aplicații web utilizează, pe lângă serverul de web menționat și
aplicații de tip server de baze de date. Un server de baze de date deservește simultan
mai multe aplicații web.
2. Atenţie la termenul server! Când se referă la un calculator, acesta are nişte
caracteristici aparte, respectiv este conectat întro reţea şi pe el rulează continuu un
ansamblu de aplicaţii accesibile prin reţea. De cele mai multe ori serverele nu aparţin
unui utilizator anume ci unei firmei care oferă servicii de găzduire de site-uri și
aplicații pentru web. Dar dacă termenul se referă la un program, este vorba despre o
aplicaţie care furnizează resurse (informații) unei rețele de aplicații client. Aplicațiile
client trimit aplicației server cereri iar aplicația server răspunde cererilor primite.
Exemplu de arhitectură hardware necesară exploatării unei aplicații web:

Tipuri de arhitecturi client-server


Arhitectura cu două niveluri (eng. 2-Tier Architecture):
Este adoptată în cazul aplicațiilor care folosesc pentru păstrarea datelor un serviciu web.
Nivelul 1 rulează în browser-ul terminalului client (PC, telefon inteligent sau tabletă) și
integrează atât partea de prezentare cât și cea de prelucrare a datelor (eng. bussiness logic).
Nivelul 2 îl reprezintă un serviciu web specializat în stocarea datelor (eng. Database-as-a-
Service, prescurtat DBaaS).
Calculatoarele client și serverul sunt conectate direct, comunicarea fiind realizată fără
utilizarea unui nivel intermediar (de exemplu un server de web). Clientul declanșează o
acțiune și primește instantaneu răspuns. Rezultatul cel mai rapid este primit exploatând actst
tip de sistem.
Această arhitectură se folosește pentru aplicații relativ simple: trimitere de mesaje (eng. chat),
aplicații de cumpărare a biletelor online ș.a..
Avantajele acestei arhitecturi țin de ușurința proiectării aplicației client, de rapiditatea
răspunsului, de modul de implementare.
Dezavantajele sunt legate de mai slaba performanță în cazul unui număr foarte mare de
utilizatori care trimit cereri simultan și, uneori, un grad mai scăzut de securizare.

Arhitectură cu trei niveluri (eng. 3-Tier Architecture):


Acest tip de arhitectură, pe lângă client și server, are nevoie de un nivel intermediar, (eng.
middleware). Cererea trimisă de componenta client (nivelul 1) spre server este adresată
nivelului intermediar (nivelul 2). În acesta au loc prelucrările cerute și eventuale accesări ale
nivelului 3, acesta fiind de regulă un server de baze de date (Oracle, MySQL, PostgreSQL,
Mssql etc.). Prelucrările efectuate în nivelul intermediar au ca și rezultat crearea unei noi
prezentări grafice (practic o pagină web generată dinamic) și trimiterea acesteia spre client.
Frecvent această arhitectură este referită folosind denumirea MVC (prescurtare pentru Model -
View - Controller).
Cele trei niveluri sunt:
 nivelul de prezentare sau interfața cu utilizatorul (eng. view);
 nivelul aplicației, în care datele sunt prelucrate (eng. controller);
 nivelul de date, care gestionează datele aplicației (eng. model).
Avantajele acestui tip de arhitectură sunt legate de rapiditatea dezvoltării, scalabilitate,
fiabilitate și securitate.

Arhitectură multinivel (eng. n-Tier Architecture sau Multitier architecture):


Acest tip de arhitectură oferă un model prin care dezvoltatorii pot crea aplicații flexibile și
reutilizabile. Având această separare a componentelor aplicației, dezvoltatorii pot modifica
sau adăuga "din mers" anumite module, fără ca aceasta să necesite refacerea întregii aplicații.
Exemplu de arhitectură pe mai multe niveluri (https://ro.qaz.wiki/wiki/Multitier_architecture):

Avantajele acestui tip de arhitectură sunt aceleași pe are le oferă arhitectura cu trei niveluri,
fiind practic doar o extindere a acesteia.
Dezavantajele sunt legate de complexitatea crescută a aplicațiilor, care afectează durata de
implementare și nivelul de calificare a dezvoltatorilor.

Aplicații client-server
Modelul client-server se referă la structurarea aplicațiilor software în componente client și
componente server. Componentele client adresează componentelor server comenzi prin care
solicită informații. Dacă rulează pe calculatoare diferite, clienții și serverele comunică prin
rețea. Pe un server pot rula aplicații accesate de mai mulți clienți. Un client nu partajează cu
nimeni altcineva resursele sale. Funcția lui este aceea de a solicita informații unei aplicații de
tip server. Exemple de aplicații informatice care utilizează modelul client-server sunt
magazinele virtuale, aplicațiile de poștă electronică, aplicațiile web, etc..

TOP
XAMPP
În cele expuse s-au menționat denumiri ale unor aplicații care intervin în funcționarea
aplicațiilor web: browser-e, aplicații de tip server web (Apache, Nginx) și aplicații de tip
server de baze de date (Oracle, MySQL, PostgreSQL, Mssql etc.). Standardizarea comunicării
cu astfel de aplicații a făcut însă posibilă punerea la dispoziția dezvoltatorilor a unor seturi
restrânse de aplicații, conținând, printre altele, un server de web și un server de baze de date.
Observație: Toate sistemele de operare integrează aplicații de navigare, deci pachetele de
aplicații menționate conțin doar setul de aplicații necesare dezvoltării părții de server ale unei
aplicații web.
Un astfel de pachet de aplicații este XAMPP, disponibil pentru toate sistemele de operare
majore: Windows, Linux și macOS (Apple).
Pachetul conține mai multe aplicații, importante fiind serverul de web Apache, serverul de
baze de date MariaDB (echivalentul gratuit al serverului MySQL) și interpretorul de cod
PHP.
Odată instalat, XAMPP poate pune la dispoziţia dezvoltatorilor o infrastructură care poate fi
imediat utilizată pentru crearea aplicațiilor web. Evident, odată finalizată, aplicația va fi
copiată pe serverul firmei care o va găzdui. Mutarea unei aplicații pe un server necesită însă și
operarea unor mici adaptări.
XAMPP se poate descărca de la adresa https://www.apachefriends.org/ro/download.html.
Se poate limita spațiul necesar instalării selectând la începutul procesului de instalare doar
aplicațiile care vor fi necesare, ca în imagine:
Instalarea se va realiza în rădăcina discului C: (sau D: sau E:, etc), prezenţa pe calculator a
pachetului de aplicaţii manfestându-se doar prin apariția directorului /xampp în rădăcina
partiției utilizate pentru instalare.
Pentru a testa site-uri și aplicații pentru web, vor trebui lansate în execuție două componente:
serverul de web Apache și serverul de baze de date MySQL. Aceasta se realizează lansând în
execuție panoul de control XAMPP xampp-control.exe (dublu clic în fereastra aplicației File
Explorer):
Verificarea funcţionării aplicaţiilor necesare pentru crearea aplicațiilor web se poate realiza
tastând în browser adresa unei aplicaţii web integrată în XAMPP, PHPMyAdmin:
http://localhost/phpmyadmin/
Aplicația lansată, PHPMyAdmin, este programată în limbajul PHP și permite gestionarea
serverului de baze de date MySQL.
Observație: Încărcarea în fereastra browser-ului a unei aplicații web sau a unui site web va
produce o serie de comenzi adresate serverului de web de pe calculatorul pe care este găzduită
aplicația. Aceste comenzi sunt compuse dintr-un verb (GET), un nume de fișier și, eventual,
unul sau mai multe argumente suplimentare. Fișierul referit în comandă poate fi de diferite
tipuri (HTML, CSS, JavaScript, PHP etc.). Cele care au un conținut static (texte, imagini,
fișiere de stiluri) vor fi "servite" de server imediat (adică transferate aplicației client) în timp
ce fișierele care conțin cod PHP vor fi executate pe server (într-un interpretor specializat).

XAMPP
XAMPP este un pachet de aplicații software gratuit, "open source" și multiplatformă care
odată instalat pe calculatorul personal, îl transformă pe acresta într-un server complex cu două
componente: o aplicație de tip server de web, Apache și un server de baze de date, MySQL.
Pachetul conține și un interpretor de cod PHP, deci acest limbaj va putea fi utilizat la
programarea componentelor părții de server a aplicației web în curs de dezvoltare.

TOP
Utilizarea serverului Apache pentru realizarea unei aplicații web
Un server de web este un program reactiv. El rulează în continuu pe calculatorul destinat
gestionării unuia sau mai multor site-uri și aplicații web şi aşteaptă cereri din partea unei
aplicaţii client (Microsoft Edge, Google Chrome, Mozilla Firefox, Opera etc.).
Ca aplicaţie, serverul pentru web accesează un ansamblu de fişiere și directoare dispuse într-
un anumit director de pe discul calculatorului pe care acesta este instalat. Dacă o aplicaţie
client trimite o comandă prin care solicită un fişier existent, serverul Apache îl va furniza
(dacă nu este un fișier conținând un program PHP) respectând regulile unui protocol precizat
în cererea clientului (http, https, ftp). Dacă serverul primește o comandă care conține
denumirea unui fișier PHP, serverul de web va lansa în execuție interpretorul de cod PHP și îi
va trimite acestuia fișierul referit în comandă.
Pentru a exemplifica utilizarea pachetului aplicații XAMPP pentru realizarea și testarea unei
aplicații (sau site) web, vor fi parcurși pașii următori:
1. Se lansează în execuție serverul Apache;
2. Se crează un subdirector derivat din .../xampp/htdocs/. Acesta va conține toate
fișierele site-ului. De exemplu: E:/xampp/htdocs/FamiliaMea/

3. Se crează apoi fișierele care compun site-ul sau se descarcă și se adaptează un model
de site (un template, de exemplu un template care folosește componente prestilizate,
bazat pe Bootstrap).
Notă: Scopul cursului nefiind crearea unei aplicații web "de la zero", vom adopta a
doua variantă, deci vom descărca un template gratuit. Pentru a limita activitatea de
stilizare, template-ul va fi bazat pe Bootstrap și va fi descărcat de la adresa:

https://bootstrapmade.com/family-multipurpose-html-bootstrap-template-free/.

4. Se afișează pagina principală a aplicației web (index.html) tastând în caseta de


adrese a browserului adresa http://localhost/FamiliaMea/
La o primă analiză a template-ului, se poate vedea că meniul derulant din bara de navigare
(Drop Down) nu conține legături spre pagini existente ci doar un model de scriere a unui
astfel de meniu. Posibil ca în versiunea cumpărată a template-ului să existe și alte modele de
pagini, ceea ce ar ușura crearea unor pagini suplimentare și legarea lor în site folosind opțiuni
din meniul derulant.
După traducerea textelor, un rezultat posibil ar putea fi:

Observație: Dacă testarea în XAMPP a unui site (sau a unei aplicații web) se realizează cu
succes, va urma copierea sa pe serverul unei firme de găzduire și realizarea adaptărilor care se
impun.

TOP

Aplicații în arhitectură client-server


Curs 2

phpMyAdmin MySQL Crearea bazei de date a unei aplicații Baza de date a aplicației Familia
mea Limbajul de programare PHP Elementele de bază
phpMyAdmin
Conform site-ului ofocial https://www.phpmyadmin.net/, PHPMyAdmin este un instrument
software gratuit scris în limbajul PHP, destinat gestionării serverului de baze de date MySQL.
Având în vedere funcțiile pe care le îndeplinește și complexitatea demonstrată, PHPMyAdmin
este un bun exemplu de utilizare a limbajului PHP.
Interfața grafică expusă de PHPMyAdmin permite realizarea următoarelor acțiuni:
 crearea și suprimarea bazelor de date;
 gestionarea utilizatorilor bazelor de date și impunerea drepturilor lor de acces;
 crearea, modificarea și suprimarea tabelelor bazelor de date;
 inserarea, editarea și ștergerea înregistrărilor din tabelele bazelor de date;
 exportarea datelor din bazele de date folosind diferite formate. De regulă conținuturile
se exportă sub forma fișierelor în format CSV (Comma Separated Values),
exploatabile în continuare în Excel și în format SQL;
 tastarea și executarea comenzilor SQL necesare creării tabelelor și manipulării datelor,
 importarea datelor din fișiere CSV sau SQL.
Pentru a putea utiliza PHPMyAdmin, trebuie lansate în execuție serverele Apache și MySQL:
Accesul la aplicație se realizează tastând în browser adresa http://localhost/phpmyadmin/

MySQL
MySQL este un sistem de gestiune a bazelor de date relaţionale produs de compania suedeză
MySQL AB (preluată în 2008 de Sun Microsystems, cumpărată la rândul ei în 2009 de Oracle
Co.). Inițial a fost distribuit gratuit (sub Licenţa Publică Generală, GNU) dar din 2010
utilizarea comercială a aplicației necesită cumpărarea unei licențe (aprox. 900$/server).
MySQL este cel mai popular SGBD open-source şi o componentă principală a pachetului de
aplicaţii XAMPP.
Deşi este folosit foarte des împreună cu limbajul PHP, serverul de baze de date MySQL poate
fi accesat din orice limbaj major: C, C++, C#, Java, Perl, sau Python.
Administrarea serverului MySQL se poate face din PHPMyadmin, dar și în modul linie de
comandă.
MySQL poate fi rulat pe toate platformele software majore (Windows, Linux, Mac OS, etc.).
În cele ce urmează MySQL va fi componenta aplicaţiilor web destinată păstrării datelor
aplicaţiei. Deşi limbajul PHP are funcţii destinate scrierii de fişiere pe discul serverului care
găzduiește componentele de tip server ale aplicațiilor care vor fi realizate, de regulă se
apelează la varianta mult mai sigură a folosirii serverului de baze de date MySQL.
Observație: Oracle Co. oferă dezvoltatorilor și varianta alternativă, MariaDB. Practic este
același server de baze de date, sub o altă denumire.
Accesarea SGBD MySQL (MariaDB) după instalarea pachetului de aplicații XAMPP se
realizează folosind ca nume root (administratorul serverului), fără parolă (paola va fi un șir de
caractere vid "").
Desigur, pot fi creați utilizatori suplimentari. Acestora vor trebui să li se definească parole de
acces și drepturile pe care le vor avea asupra bazelor de date de pe server.
Observație: Un server de baze de date poate găzdui mai multe baze de date. Fiecare bază de
date va putea fi exploatată de unul sau mai mulți utilizatori. Fiecărui utilizator i se va deschide
un cont separat. Odată cu deschiderea unui cont se poate opta și pentru crearea unei baze de
date pe care noul utilizator o va putea exploata, deci crearea utilizatorului va precede crearea
noii baze de date.
Pentru a crea un nou utilizator al serverului MySQL se va selecta tabul Utilizatori (eng. User
accounts):
Înainte de a se crea efectiv utilizatorul, în aceeași fereastră se impun drepturile acestuia. De
regulă se acceptă toate drepturile din primele două categorii, Date și Structură (eng. Data și
Structure).

MySQL
MySQL este un sistem de gestiune a bazelor de date relaționale. Este cel mai popular SGBD
open-source la ora actuală. Este folosit foarte des împreună cu limbajul de programare PHP.
Cu MySQL se pot construi aplicații în orice limbaj major (de ex. C, C++, C#, Java, Perl, PHP,
Python, etc.).

TOP
Crearea bazei de date a unei aplicații
Aplicațiile software sunt create pentru a culege, prelucra și păstra informații. Aceasta implică
faptul că natura informațiilor care vor fi prelucrate este cunoscută de la început. În primele
stadii de dezvoltare a aplicației pot fi deci definite principalele entități (sau obiecte, în sens
informatic) putându-se trasa și o diagramă care indică relațiile dintre acestea (o diagramă ER,
prescurtare de la Entity - Relationship).
Diagrama afișată definește denumirile și structura principalelor clase (sau tabele, dacă ne
referim la modul de stocare a entităților în baza de date) și relațiile dintre ele. Relațiile sunt
cele cunoscute din teroria bazelor de date relaționale:

Diagrama conține și denumirile câmpurilor tabelelor bazei de date și denumirea cheii primare,
respectiv denumirea unui câmp care are valori distincte pentru toate articolele unui tabel.
Informațiile din această diagramă vor permite crearea bazei de date a aplicației. La crearea
tabelelor bazei de date vor mai trebui definite pentru fiecare câmp tipul de dată utilizat
(număr, șir de caractere, dată calendaristică etc.). De asemenea, structura inițială va fi
completată cu un set de tabele de legătură destinat normalizării bazei de date.
Baza de date a aplicației Familia mea
Deoarece template-ul selectat va servi la realizarea unei aplicații, în continuare se va crea baza
de date a acesteia.
Concret se va proceda astfel:
1. Se va lansa în execuție aplicația PHPMyAdmin;
2. Pentru crearea bazei de date necesare se va selecta în PHPMyAdmin primul tab,
Databases, se va introduce numele noii baze de date (familia) și setul de caractere care
va fi folosit în tabelele acesteia (utf8_general_ci):
1. Vor fi create apoi tabelele necesare. Pentru a le defini, vor fi analizate secțiunile din
paginile site-ului care vor avea un conținut dinamic, preluat din baza de date.

Pagina evenimente.html
Dacă se selectează opțiunea Evenimente de pe bara de navigare, în fereastra browser-ului va fi
afișat următorul conținut:

Fiecare articol din tabelul care va fi creat (evenimente) va trebui să permită crearea unui bloc
similar celui evidențiat în imagine. Un astfel de bloc se crează pornind de la următoarele
informații:
 o imagine (600x400px) - câmpul imagine;
 un titlu (Lara's 1th Birthday) - câmpul titlu;
 o dată calendaristică (Sunday, September 26th at 7:00 pm) - câmpul data;
 o prezentare (Lorem ipsum dolor sit amet, ...) - câmpul prezentare;
 un câmp suplimentar, id, care va avea valori întregi și va fi cheie primară în tabelul
EVENIMENTE.
Crearea tabelului evenimente presupune doi pași, declararea numelui tabelului și a numărului
de câmpuri respectiv definirea denumirilor și a caracteristicilor câmpurilor tabelului, ca în
imaginile următoare:
Pagina galerie.html
Dacă se selectează pe bara de navigare opțiunea Galerie, în fereastra browser-ului va fi afișată
o galerie de imagini.
Pentru a înțelege modul în care operează scripturile care permit filtrarea setului de imagini în
funcție de categorie, se va analiza codul paginii galerie.html. Mai precis informațiile asociate
intrărilor din lista de categorii și cele utilizate pentru a afișa o imagine oarecare. Informațiile
relevante rezultă din imaginea următoare:

Se observă că fiecare element din lista neordonată are un atribut denumit data-filter având ca
și valoare denumirea unei clase (.filter-home, .filter-beach sau .filter-vacation).
Aceste denumiri de clase se regăsesc în listele claselor folosite la stilizarea blocurilor care
conțin imagini.
Din perspectiva definirii bazei de date, se observă că pentru a gestiona categoriile (ALL,
HOME, BEACH, VACATION) va trebui creat un tabel, categorii, fiecare articol din acest tabel
avînd având trei câmpuri: id (întreg, autoincrement, cheie primară), categorie (VARCHAR,
max. 20 caractere), și clasa (VARCHAR, max. 20 caractere), ca în imagine:

În ceea ce privește imaginile, când cursorul mausului se suprapune peste o imagine, pe


imagine se afișează un titlu (Beach 1) și sub titlu, un șir de caractere (un comentariu:
BEACH):

Pentru memorarea imaginilor, se va crea un tabel denumit imagini având următoarele


câmpuri:
1. id - întreg, autoincrement, cheie primară;
2. clasa - VARCHAR, max. 20 caractere, pentru filtrare (valori din câmpul omolog din
categorii);
3. fotografie - VARCHAR, max. 12 caractere, pentru numele fișierului;
4. titlu - VARCHAR, max. 20 caractere;
5. comentariu - VARCHAR, max. 30 caractere;
Observație: În cursurile viitoare vor fi prezentate noțiuni de programare în limbajul PHP.
Folosind acest limbaj, secțiunile care primesc date din baza de date vor fi rescrise, dar pentru
a putea testa codul, în tabelele bazei de date trebuie să fie inserate datele necesare. Într-o
primă fază vor fi inserate chiar cele utilizate în template-ul ales. Apoi acestea vor fi șterse,
urmând să fie încărcate informații reale folosind o aplicație specializată, scrisă tot în PHP,
care va trebui să fie creată.

Pentru inserarea datelor necesare testării se va folosi tot PHPMyAdmin, respectiv va fi


selectat tabul Insert de pe bara de navigare a acesteia.
Cu excepția imaginilor, inserarea informațiilor nu pune probleme. În cazul imaginilor,
practica obișnuită presupune redenumirea acestora. Concret, imaginile necesare afișării
cardurilor din pagina evenimente.html vor fi memorate în directorul derivat imagini,
denumirile acestora fiind formate din caracterul 'e' urmat de valoarea cheii primare a
articolului în care imaginea este referită și de extensia specifică tipului de fișier. Exemplu:
e2.jpg. La fel, denumirile imaginilor afișate în galerie.html vor începe cu litera 'g' urmată de
valoarea cheii primare din articolul în care sunt referite și de extensie, după modelul: g7.jpg.

TOP
Limbajul de programare PHP
În cadrul ansamblului de "instrumente software" folosit pentru crearea unei aplicaţii Web,
PHP este limbajul de programare destinat scrierii componentelor care se rulează pe server.
Există desigur şi alte limbaje care pot fi folosite, dar PHP este în acest moment soluţia cea
mai răspândită pentru scrierea scripturilor care prelucrează datele din formulare, care
returnează date memorate în baze de date sau care generează pagini dinamice bazate pe date
păstrate în baze de date.
Limbajul PHP şi interpretorul de comenzi aferent sunt gratuite. Interpretorul de comenzi este
conţinut în pachetul de aplicaţii XAMPP şi este instalat automat împreună cu celelalte
componente ale pachetului.
PHP este un acronim pentru "PHP: Hypertext Preprocessor". Acest limbaj este destinat
scrierii componentei de back-end a unei aplicații web, deci codul scris va fi executat pe
serverul care găzduiește aplicația.
Un fişier PHP poate conţine numai cod PHP sau un mix constând din elemente HTML și
secvențe de cod PHP.
Lansarea în execuţie a interpretorului PHP se realizează de către serverul de Web (Apache,
IIS etc.) dacă fişierul cerut de browser are extensia .php.
http://localhost/FamiliaMea/galerie.php
Interpretorul de cod PHP va trimite browser-ului atât codul HTML existent în fişier cât şi
rezultatele executării secvenţelor programate în PHP.
Codul PHP este încadrat între marcajele "<?php" și "?>". Un fișier HTML obișnuit, chiar dacă
nu include secvențe de cod PHP, poate fi salvat cu extensia .php.
Exemplu de fișier PHP tipic:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<?php
$nume = "Ionescu Paul";
$an = 1998;
?>
<h2>Autorul lucrării:</h2>
<p>Numele: <?php echo $nume ?>, născut în <?php echo $an ?></p>
</body>
</html>
În PHP identificatorul unei variabile începe cu caracterul '$'.
În exemplul dat, pentru afișarea valorii variabilelor $nume și $an se folosește instrucțiunea
echo, astfel: <?php echo variabila ?>. În cele ce urmează va fi însă utilizată cu precădere
o scriere simplificată: <?= variabila ?>. Deci linia care afișează datele persoanei se poate
scrie astfel:
<p>Numele: <?= $nume ?>, născut în <?= $an ?></p>

În cazul care un fișier PHP conține numai cod PHP, marcajele specifice (<?php și ?>) trebuie
scrise. Exemplu:
<?php
$nume = "Ionescu Paul";
$an = 1998;
echo $nume . " din <br> " . $an; // În PHP . (punctul) este operatorul
de concatenare a sirurilor de caractere.
?>
Observație: Codul HTML poate conține cod PHP, dar ceea ce se returnează browser-ului,
rezultatul procesării fișierului PHP în cadrul interpretorului de cod, trebuie să fie un cod
HTML corect pe care browser-ul să-l poată utiliza.

Limbajul PHP
Limbajul PHP este limbajul de programare destinat scrierii componentelor care se rulează pe
server. Este potrivit pentru dezvoltarea aplicațiilor web și poate fi încorporat în HTML.

TOP
Elementele de bază

Elementele de bază ale limbajului


În PHP numele unei variabile începe cu caracterul "$". Variabilele nu trebuie declarate în
prealabil, alocarea memoriei necesare și stabilirea tipului de dată realizându-se dinamic, în
momentul atribuirii unei valori.
Unele variabile sunt create automat de interpretorul PHP. De exemplu variabilele $_POST sau
$_GET, care conțin setul de date transmis scriptului PHP referit în atributul action al unui
element HTML <form>.
În PHP, tipurile de date sunt:
 integer,
 double (nr. reale, dublă precizie),
 string,
 boolean (tipul logic, true sau false),
 array (şir de valori),
 object (obiect) sau
 NULL (sau null)
Exemple:
$a = "acesta este un sir de caractere"; // string
$b = 3; // $b este integer
$c = 4.12; // $c este double
$d = "2"; // $d este un şir de caractere
$e = $b + $d; // $e = 5, deci $d a fost tratat ca întreg!
$f = true; // $f este boolean.
$g = false;
$luni = array("ian", "feb", "mar", "apr"); // Un şir de valori

Şiruri de caractere
Şirurile de caractere sunt delimitate prin caractere " (ghilimele) sau ' (apostrof). Dacă în şir
există ghilimele, caractere $ sau caractere \ (backslash), pentru a fi interpretate ca atare
acestea vor fi precedate de \.
Exemplu:
$a = 15;
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie = $ctg";
Variabilele prezente în şiruri delimitate prin ghilimele vor fi înlocuite prin valoarea lor, deci,
dacă $ctg = 7, practic s-a scris:
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie = 7".
Dacă un şir este delimitat prin caractere ' (apostrof), variabilele incluse în şir nu vor mai fi
înlocuite prin valorile lor.
În PHP "." (punct) este operatorul de concatenare.
Exemplu:
<?php
$a=1;
$b=12;

$c = '<li><a href="caut.php?id_art = ' . $a . '&id_materie=' . $b;


$c .= '"></a></li>'; // .= este operator de atribuire combinată
. . .
?>

Tipul array
Un şir de valori (array) poate fi declarat folosind funcţia array():
$sirVid = array(); // Sau varianta echivalenta: $sirVid = [];
$luni = array("ianuarie", "februarie", "martie", "aprilie");
Se poate scrie însă și mai simplu:
$luni = ["ianuarie", "februarie", "martie", "aprilie"];
$luni[4] = "mai";
$luni[5] = "iunie";
$luni[] = "iulie"; // Adaugare la sfarsit
Atribuirea $luni[] = "iulie"; este corectă, elementul care va primi valoare fiind luni[6].

Şiruri asociative
Elementele unui șir asociativ sunt de forma cheie => valoare
Pentru cheie se poate folosi un număr întreg sau un șir de caractere.
Exemplu:
$persoana = array('varsta' => 23, 'profesia' => 'medic', 'gen' => 'm');
Șirul asociativ $persoana poate fi creat și altfel, scriind:
$persoana['varsta'] = 23;
$persoana['profesia'] = 'medic';
$persoana['gen'] = 'm';
Se poate scrie însă și mai simplu:
$persoana = [
'varsta' => 23,
'profesia' => 'medic',
'gen' => 'm'
];
Observație:
1. În PHP elementele șirurilor de valori sunt de fapt întotdeauna de forma (cheie => valoare).
De exemplu șirul [234, 12, -7] este de fapt șirul asociativ (0 => 234, 1 => 12, 2 => -7).
2. Exemple importante de șiruri asociative sunt $_GET și $_POST. Acestea primesc automat,
datorită unui mecanism integrat în PHP, valorile preluate din câmpurile elementelor HTML
de tip <form> și transmise scriptului PHP care le va prelucra. Așa cum se știe, transmiterea se
poate realiza folosind method="GET" sau method="POST", de unde și denumirile șirurilor
asociative menționate. Exemplu:
$eml = $_POST['e_mail'];
3. Elementele aparţinând şirurilor asociative nu sunt înlocuite corect de către interpretorul
PHP dacă apar într-un şir delimitat prin ghilimele. Exemplu:
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie =
$_POST['id_cat']"; // Incorect!
Soluţia corectă:
$idc = $_POST['id_cat'];
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie = $idc";

script PHP
Un script PHP se află și rulează pe server. Are extensia .php. În cazul în care se utilizează
calculatorul personal pe care se instalează pachetul XAMPP, scriptul va fi salvat în directorul
htdocs sau într-un director derivat din acesta. Execuția scriptului se realizează tastând în bara
de adrese a browser-ului adresa acestuia (de ex.: http://localhost/testePHP/numescript.php).

TOP

Aplicații în arhitectură client-server


Curs 2

phpMyAdmin MySQL Crearea bazei de date a unei aplicații Baza de date a aplicației Familia
mea Limbajul de programare PHP Elementele de bază
phpMyAdmin
Conform site-ului ofocial https://www.phpmyadmin.net/, PHPMyAdmin este un instrument
software gratuit scris în limbajul PHP, destinat gestionării serverului de baze de date MySQL.
Având în vedere funcțiile pe care le îndeplinește și complexitatea demonstrată, PHPMyAdmin
este un bun exemplu de utilizare a limbajului PHP.
Interfața grafică expusă de PHPMyAdmin permite realizarea următoarelor acțiuni:
 crearea și suprimarea bazelor de date;
 gestionarea utilizatorilor bazelor de date și impunerea drepturilor lor de acces;
 crearea, modificarea și suprimarea tabelelor bazelor de date;
 inserarea, editarea și ștergerea înregistrărilor din tabelele bazelor de date;
 exportarea datelor din bazele de date folosind diferite formate. De regulă conținuturile
se exportă sub forma fișierelor în format CSV (Comma Separated Values),
exploatabile în continuare în Excel și în format SQL;
 tastarea și executarea comenzilor SQL necesare creării tabelelor și manipulării datelor,
 importarea datelor din fișiere CSV sau SQL.
Pentru a putea utiliza PHPMyAdmin, trebuie lansate în execuție serverele Apache și MySQL:
Accesul la aplicație se realizează tastând în browser adresa http://localhost/phpmyadmin/

MySQL
MySQL este un sistem de gestiune a bazelor de date relaţionale produs de compania suedeză
MySQL AB (preluată în 2008 de Sun Microsystems, cumpărată la rândul ei în 2009 de Oracle
Co.). Inițial a fost distribuit gratuit (sub Licenţa Publică Generală, GNU) dar din 2010
utilizarea comercială a aplicației necesită cumpărarea unei licențe (aprox. 900$/server).
MySQL este cel mai popular SGBD open-source şi o componentă principală a pachetului de
aplicaţii XAMPP.
Deşi este folosit foarte des împreună cu limbajul PHP, serverul de baze de date MySQL poate
fi accesat din orice limbaj major: C, C++, C#, Java, Perl, sau Python.
Administrarea serverului MySQL se poate face din PHPMyadmin, dar și în modul linie de
comandă.
MySQL poate fi rulat pe toate platformele software majore (Windows, Linux, Mac OS, etc.).
În cele ce urmează MySQL va fi componenta aplicaţiilor web destinată păstrării datelor
aplicaţiei. Deşi limbajul PHP are funcţii destinate scrierii de fişiere pe discul serverului care
găzduiește componentele de tip server ale aplicațiilor care vor fi realizate, de regulă se
apelează la varianta mult mai sigură a folosirii serverului de baze de date MySQL.
Observație: Oracle Co. oferă dezvoltatorilor și varianta alternativă, MariaDB. Practic este
același server de baze de date, sub o altă denumire.
Accesarea SGBD MySQL (MariaDB) după instalarea pachetului de aplicații XAMPP se
realizează folosind ca nume root (administratorul serverului), fără parolă (paola va fi un șir de
caractere vid "").
Desigur, pot fi creați utilizatori suplimentari. Acestora vor trebui să li se definească parole de
acces și drepturile pe care le vor avea asupra bazelor de date de pe server.
Observație: Un server de baze de date poate găzdui mai multe baze de date. Fiecare bază de
date va putea fi exploatată de unul sau mai mulți utilizatori. Fiecărui utilizator i se va deschide
un cont separat. Odată cu deschiderea unui cont se poate opta și pentru crearea unei baze de
date pe care noul utilizator o va putea exploata, deci crearea utilizatorului va precede crearea
noii baze de date.
Pentru a crea un nou utilizator al serverului MySQL se va selecta tabul Utilizatori (eng. User
accounts):
Înainte de a se crea efectiv utilizatorul, în aceeași fereastră se impun drepturile acestuia. De
regulă se acceptă toate drepturile din primele două categorii, Date și Structură (eng. Data și
Structure).

MySQL
MySQL este un sistem de gestiune a bazelor de date relaționale. Este cel mai popular SGBD
open-source la ora actuală. Este folosit foarte des împreună cu limbajul de programare PHP.
Cu MySQL se pot construi aplicații în orice limbaj major (de ex. C, C++, C#, Java, Perl, PHP,
Python, etc.).

TOP
Crearea bazei de date a unei aplicații
Aplicațiile software sunt create pentru a culege, prelucra și păstra informații. Aceasta implică
faptul că natura informațiilor care vor fi prelucrate este cunoscută de la început. În primele
stadii de dezvoltare a aplicației pot fi deci definite principalele entități (sau obiecte, în sens
informatic) putându-se trasa și o diagramă care indică relațiile dintre acestea (o diagramă ER,
prescurtare de la Entity - Relationship).
Diagrama afișată definește denumirile și structura principalelor clase (sau tabele, dacă ne
referim la modul de stocare a entităților în baza de date) și relațiile dintre ele. Relațiile sunt
cele cunoscute din teroria bazelor de date relaționale:

Diagrama conține și denumirile câmpurilor tabelelor bazei de date și denumirea cheii primare,
respectiv denumirea unui câmp care are valori distincte pentru toate articolele unui tabel.
Informațiile din această diagramă vor permite crearea bazei de date a aplicației. La crearea
tabelelor bazei de date vor mai trebui definite pentru fiecare câmp tipul de dată utilizat
(număr, șir de caractere, dată calendaristică etc.). De asemenea, structura inițială va fi
completată cu un set de tabele de legătură destinat normalizării bazei de date.
Baza de date a aplicației Familia mea
Deoarece template-ul selectat va servi la realizarea unei aplicații, în continuare se va crea baza
de date a acesteia.
Concret se va proceda astfel:
1. Se va lansa în execuție aplicația PHPMyAdmin;
2. Pentru crearea bazei de date necesare se va selecta în PHPMyAdmin primul tab,
Databases, se va introduce numele noii baze de date (familia) și setul de caractere care
va fi folosit în tabelele acesteia (utf8_general_ci):
1. Vor fi create apoi tabelele necesare. Pentru a le defini, vor fi analizate secțiunile din
paginile site-ului care vor avea un conținut dinamic, preluat din baza de date.

Pagina evenimente.html
Dacă se selectează opțiunea Evenimente de pe bara de navigare, în fereastra browser-ului va fi
afișat următorul conținut:

Fiecare articol din tabelul care va fi creat (evenimente) va trebui să permită crearea unui bloc
similar celui evidențiat în imagine. Un astfel de bloc se crează pornind de la următoarele
informații:
 o imagine (600x400px) - câmpul imagine;
 un titlu (Lara's 1th Birthday) - câmpul titlu;
 o dată calendaristică (Sunday, September 26th at 7:00 pm) - câmpul data;
 o prezentare (Lorem ipsum dolor sit amet, ...) - câmpul prezentare;
 un câmp suplimentar, id, care va avea valori întregi și va fi cheie primară în tabelul
EVENIMENTE.
Crearea tabelului evenimente presupune doi pași, declararea numelui tabelului și a numărului
de câmpuri respectiv definirea denumirilor și a caracteristicilor câmpurilor tabelului, ca în
imaginile următoare:
Pagina galerie.html
Dacă se selectează pe bara de navigare opțiunea Galerie, în fereastra browser-ului va fi afișată
o galerie de imagini.
Pentru a înțelege modul în care operează scripturile care permit filtrarea setului de imagini în
funcție de categorie, se va analiza codul paginii galerie.html. Mai precis informațiile asociate
intrărilor din lista de categorii și cele utilizate pentru a afișa o imagine oarecare. Informațiile
relevante rezultă din imaginea următoare:

Se observă că fiecare element din lista neordonată are un atribut denumit data-filter având ca
și valoare denumirea unei clase (.filter-home, .filter-beach sau .filter-vacation).
Aceste denumiri de clase se regăsesc în listele claselor folosite la stilizarea blocurilor care
conțin imagini.
Din perspectiva definirii bazei de date, se observă că pentru a gestiona categoriile (ALL,
HOME, BEACH, VACATION) va trebui creat un tabel, categorii, fiecare articol din acest tabel
avînd având trei câmpuri: id (întreg, autoincrement, cheie primară), categorie (VARCHAR,
max. 20 caractere), și clasa (VARCHAR, max. 20 caractere), ca în imagine:

În ceea ce privește imaginile, când cursorul mausului se suprapune peste o imagine, pe


imagine se afișează un titlu (Beach 1) și sub titlu, un șir de caractere (un comentariu:
BEACH):

Pentru memorarea imaginilor, se va crea un tabel denumit imagini având următoarele


câmpuri:
1. id - întreg, autoincrement, cheie primară;
2. clasa - VARCHAR, max. 20 caractere, pentru filtrare (valori din câmpul omolog din
categorii);
3. fotografie - VARCHAR, max. 12 caractere, pentru numele fișierului;
4. titlu - VARCHAR, max. 20 caractere;
5. comentariu - VARCHAR, max. 30 caractere;
Observație: În cursurile viitoare vor fi prezentate noțiuni de programare în limbajul PHP.
Folosind acest limbaj, secțiunile care primesc date din baza de date vor fi rescrise, dar pentru
a putea testa codul, în tabelele bazei de date trebuie să fie inserate datele necesare. Într-o
primă fază vor fi inserate chiar cele utilizate în template-ul ales. Apoi acestea vor fi șterse,
urmând să fie încărcate informații reale folosind o aplicație specializată, scrisă tot în PHP,
care va trebui să fie creată.

Pentru inserarea datelor necesare testării se va folosi tot PHPMyAdmin, respectiv va fi


selectat tabul Insert de pe bara de navigare a acesteia.
Cu excepția imaginilor, inserarea informațiilor nu pune probleme. În cazul imaginilor,
practica obișnuită presupune redenumirea acestora. Concret, imaginile necesare afișării
cardurilor din pagina evenimente.html vor fi memorate în directorul derivat imagini,
denumirile acestora fiind formate din caracterul 'e' urmat de valoarea cheii primare a
articolului în care imaginea este referită și de extensia specifică tipului de fișier. Exemplu:
e2.jpg. La fel, denumirile imaginilor afișate în galerie.html vor începe cu litera 'g' urmată de
valoarea cheii primare din articolul în care sunt referite și de extensie, după modelul: g7.jpg.

TOP
Limbajul de programare PHP
În cadrul ansamblului de "instrumente software" folosit pentru crearea unei aplicaţii Web,
PHP este limbajul de programare destinat scrierii componentelor care se rulează pe server.
Există desigur şi alte limbaje care pot fi folosite, dar PHP este în acest moment soluţia cea
mai răspândită pentru scrierea scripturilor care prelucrează datele din formulare, care
returnează date memorate în baze de date sau care generează pagini dinamice bazate pe date
păstrate în baze de date.
Limbajul PHP şi interpretorul de comenzi aferent sunt gratuite. Interpretorul de comenzi este
conţinut în pachetul de aplicaţii XAMPP şi este instalat automat împreună cu celelalte
componente ale pachetului.
PHP este un acronim pentru "PHP: Hypertext Preprocessor". Acest limbaj este destinat
scrierii componentei de back-end a unei aplicații web, deci codul scris va fi executat pe
serverul care găzduiește aplicația.
Un fişier PHP poate conţine numai cod PHP sau un mix constând din elemente HTML și
secvențe de cod PHP.
Lansarea în execuţie a interpretorului PHP se realizează de către serverul de Web (Apache,
IIS etc.) dacă fişierul cerut de browser are extensia .php.
http://localhost/FamiliaMea/galerie.php
Interpretorul de cod PHP va trimite browser-ului atât codul HTML existent în fişier cât şi
rezultatele executării secvenţelor programate în PHP.
Codul PHP este încadrat între marcajele "<?php" și "?>". Un fișier HTML obișnuit, chiar dacă
nu include secvențe de cod PHP, poate fi salvat cu extensia .php.
Exemplu de fișier PHP tipic:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<?php
$nume = "Ionescu Paul";
$an = 1998;
?>
<h2>Autorul lucrării:</h2>
<p>Numele: <?php echo $nume ?>, născut în <?php echo $an ?></p>
</body>
</html>
În PHP identificatorul unei variabile începe cu caracterul '$'.
În exemplul dat, pentru afișarea valorii variabilelor $nume și $an se folosește instrucțiunea
echo, astfel: <?php echo variabila ?>. În cele ce urmează va fi însă utilizată cu precădere
o scriere simplificată: <?= variabila ?>. Deci linia care afișează datele persoanei se poate
scrie astfel:
<p>Numele: <?= $nume ?>, născut în <?= $an ?></p>

În cazul care un fișier PHP conține numai cod PHP, marcajele specifice (<?php și ?>) trebuie
scrise. Exemplu:
<?php
$nume = "Ionescu Paul";
$an = 1998;
echo $nume . " din <br> " . $an; // În PHP . (punctul) este operatorul
de concatenare a sirurilor de caractere.
?>
Observație: Codul HTML poate conține cod PHP, dar ceea ce se returnează browser-ului,
rezultatul procesării fișierului PHP în cadrul interpretorului de cod, trebuie să fie un cod
HTML corect pe care browser-ul să-l poată utiliza.

Limbajul PHP
Limbajul PHP este limbajul de programare destinat scrierii componentelor care se rulează pe
server. Este potrivit pentru dezvoltarea aplicațiilor web și poate fi încorporat în HTML.

TOP
Elementele de bază

Elementele de bază ale limbajului


În PHP numele unei variabile începe cu caracterul "$". Variabilele nu trebuie declarate în
prealabil, alocarea memoriei necesare și stabilirea tipului de dată realizându-se dinamic, în
momentul atribuirii unei valori.
Unele variabile sunt create automat de interpretorul PHP. De exemplu variabilele $_POST sau
$_GET, care conțin setul de date transmis scriptului PHP referit în atributul action al unui
element HTML <form>.
În PHP, tipurile de date sunt:
 integer,
 double (nr. reale, dublă precizie),
 string,
 boolean (tipul logic, true sau false),
 array (şir de valori),
 object (obiect) sau
 NULL (sau null)
Exemple:
$a = "acesta este un sir de caractere"; // string
$b = 3; // $b este integer
$c = 4.12; // $c este double
$d = "2"; // $d este un şir de caractere
$e = $b + $d; // $e = 5, deci $d a fost tratat ca întreg!
$f = true; // $f este boolean.
$g = false;
$luni = array("ian", "feb", "mar", "apr"); // Un şir de valori

Şiruri de caractere
Şirurile de caractere sunt delimitate prin caractere " (ghilimele) sau ' (apostrof). Dacă în şir
există ghilimele, caractere $ sau caractere \ (backslash), pentru a fi interpretate ca atare
acestea vor fi precedate de \.
Exemplu:
$a = 15;
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie = $ctg";
Variabilele prezente în şiruri delimitate prin ghilimele vor fi înlocuite prin valoarea lor, deci,
dacă $ctg = 7, practic s-a scris:
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie = 7".
Dacă un şir este delimitat prin caractere ' (apostrof), variabilele incluse în şir nu vor mai fi
înlocuite prin valorile lor.
În PHP "." (punct) este operatorul de concatenare.
Exemplu:
<?php
$a=1;
$b=12;

$c = '<li><a href="caut.php?id_art = ' . $a . '&id_materie=' . $b;


$c .= '"></a></li>'; // .= este operator de atribuire combinată
. . .
?>

Tipul array
Un şir de valori (array) poate fi declarat folosind funcţia array():
$sirVid = array(); // Sau varianta echivalenta: $sirVid = [];
$luni = array("ianuarie", "februarie", "martie", "aprilie");
Se poate scrie însă și mai simplu:
$luni = ["ianuarie", "februarie", "martie", "aprilie"];
$luni[4] = "mai";
$luni[5] = "iunie";
$luni[] = "iulie"; // Adaugare la sfarsit
Atribuirea $luni[] = "iulie"; este corectă, elementul care va primi valoare fiind luni[6].

Şiruri asociative
Elementele unui șir asociativ sunt de forma cheie => valoare
Pentru cheie se poate folosi un număr întreg sau un șir de caractere.
Exemplu:
$persoana = array('varsta' => 23, 'profesia' => 'medic', 'gen' => 'm');
Șirul asociativ $persoana poate fi creat și altfel, scriind:
$persoana['varsta'] = 23;
$persoana['profesia'] = 'medic';
$persoana['gen'] = 'm';
Se poate scrie însă și mai simplu:
$persoana = [
'varsta' => 23,
'profesia' => 'medic',
'gen' => 'm'
];
Observație:
1. În PHP elementele șirurilor de valori sunt de fapt întotdeauna de forma (cheie => valoare).
De exemplu șirul [234, 12, -7] este de fapt șirul asociativ (0 => 234, 1 => 12, 2 => -7).
2. Exemple importante de șiruri asociative sunt $_GET și $_POST. Acestea primesc automat,
datorită unui mecanism integrat în PHP, valorile preluate din câmpurile elementelor HTML
de tip <form> și transmise scriptului PHP care le va prelucra. Așa cum se știe, transmiterea se
poate realiza folosind method="GET" sau method="POST", de unde și denumirile șirurilor
asociative menționate. Exemplu:
$eml = $_POST['e_mail'];
3. Elementele aparţinând şirurilor asociative nu sunt înlocuite corect de către interpretorul
PHP dacă apar într-un şir delimitat prin ghilimele. Exemplu:
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie =
$_POST['id_cat']"; // Incorect!
Soluţia corectă:
$idc = $_POST['id_cat'];
$comandaSQL = "SELECT * FROM categorii WHERE id_categorie = $idc";

script PHP
Un script PHP se află și rulează pe server. Are extensia .php. În cazul în care se utilizează
calculatorul personal pe care se instalează pachetul XAMPP, scriptul va fi salvat în directorul
htdocs sau într-un director derivat din acesta. Execuția scriptului se realizează tastând în bara
de adrese a browser-ului adresa acestuia (de ex.: http://localhost/testePHP/numescript.php).

TOP

Aplicații în arhitectură client-server


Curs 3

Rularea aplicațiilor web Instrucţiunile limbajului PHP Functii PHP

Rularea aplicațiilor web


Odată baza de date a aplicației web creată, modificarea template-ului ales va continua cu
schimbarea extensiilor fișierelor în format HTML. Modificarea va consta în înlocuirea
extensiei .html cu extensia .php.
Observație: Paginile web ale unui template sunt inițial compuse din secțiuni având texte
aleatoare (de cele mai multe ori Lorem ipsum). În procesul de adaptare, conținutul aleator este
înlocuit cu secvențe de text și imagini reale, aparținând noului site sau noii aplicații web.
Având în vedere conținutul lor, despre astfel de secțiuni (și pagini) spunem că au conținut
static sau, mai scurt, că sunt statice. După verificarea corectitudinii afișării și operarea în
fișierul de stiluri (CSS) a eventualelor adaptări, se poate trece la modificarea secțiunilor
destinate afișării de informații provenind din baza de date. Pentru aceasta se vor utiliza
secvențe de cod PHP care pot extrage datele din bază și pot crea dinamic noi elemente HTML
care vor îngloba datele extrase. Varianta astfel obținută (pentru o secțiune, respectiv pentru
pagina care o conține) este denumită variantă dinamică.
Observație: Modificările extensiilor fișierelor vor determina și modificări ale adreselor din
elementele <a> folosite la navigarea în interiorul aplicației. Exemplu:
<nav class="nav-menu d-none d-lg-block">
<ul>
<li><a href="index.php">Acasă</a></li>
<li><a href="povestea-noastra.php">Povestea noastră</a></li>
<li class="active"><a href="evenimente.php">Evenimente</a></li>
<li><a href="galerie.php">Galerie de imagini</a></li>
<li><a href="contact.php">Contact</a></li>
</ul>
</nav>
În cazul aplicației începute, Familia Mea, conținutul directorului care va găzdui aplicația va fi
cel din imagine:

Dacă se tastează în caseta de adrese a browser-ului adresa:


http://localhost/FamiliaMea/index.php
se obține:

Evident, fiind vorba despre fișiere .php, se va porni în prealabil serverul de web Apache:
Pe lîngă directorul /xampp/localhost/FamiliaMea/ va fi creat și un director destinat testării
altor scripturi PHP scrise pe parcursul cursului. Denumirea acestuia va fi
/xampp/localhost/testePHP/. Dacă test1.php este denumirea unui fișier din acest director,
salvarea acestuia se va face în directorul .../xampp/htdocs/testePHP:
iar adresa care trebuie tastată în caseta de adrese a browser-ului va fi:
http://localhost/testePHP/test1.php

Exemplu fundamental
Se consideră fișierul următor, care conține o secvenţă scrisă în PHP. Instrucţiunea echo
realizează inserarea în conținutul trimis spre browser a unui şir de caractere. Şirul de caractere
este încadrat între ghilimele.
Fișierul va fi salvat în subdirectorul http://localhost/testePHP/ și va fi denumit test1.php.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Testare PHP </title>
<link href="css/stil.css" rel="stylesheet">
</head>
<body>
<h2>Fișier conținând cod PHP</h2>
<?php
echo "<p>Acest mesaj este afișat de <em>echo</em></p>";
?>
<p>Secvența programată s-a terminat. Acest cod este simplu HTML.</p>
</body>
</html>
Rezultat:

TOP
Instrucţiunile limbajului PHP

Instrucţiunea echo
Instrucțiunea echo este folosită pentru a trimite spre browser un șir de caractere. Șirul de
caractere poate fi oricât de lung și de complex. De multe ori șirul trimis conține codul HTML
necesar creării în fereastra browser-ului a unor noi elemente. Exemple:
<?php
// Scriptul testecho.php
$nume = "<h2>Ionescu Carmen</h2>";
$adr = "<em>Str. Plopilor Nr. 14, Cluj-Napoca</em>";
echo $nume;
echo $adr;
?>

Instrucţiunea if
Ca şi în alte limbaje, instrucţiunea if are două forme:
if (condiţie) {
acţiuni pentru condiţie = adevărat (TRUE)
}
respectiv
if (condiţie) {
acţiuni pentru condiţie = adevărat (TRUE)
} else {
acţiuni pentru condiţie = fals (FALSE)
}
Condiţia poate fi o expresie logică, scrisă folosind operatorii relaţionali uzuali: < <= > >=
== != (sau <>, diferit), respectiv && (dar şi and, operatorul şi), || (dar şi or, operatorul sau), !
(negaţie). Cele două variante de operatori logici "şi" respectiv "sau" diferă prin ordinea de
evaluare a operanzilor.
Ca şi în alte limbaje, condiţie poate fi o expresie aritmetică, o valoare 0 a acesteia fiind
interpretată ca fals (FALSE) iar o valoare diferită de 0 ca adevărat (TRUE).

Instrucţiunea if ... elseif


Ca şi în C++, şi în PHP pot fi scrise construcţii de forma:
if (conditie_1) {
Acţiuni pentru condiţie_1 = adevărat
} elseif (conditie_2) {
Acţiuni pentru condiţie_2 = adevărat
} elseif (conditie_3) {
Acţiuni pentru condiţie_3 = adevărat
} else {
Acţiuni pentru restul situaţiilor
}

Ultimul else poate lipsi.

Instrucţiunea switch ... case


Pentru cazul în care într-un program ramificarea depinde de valoarea unei variabile, structura
switch ... case este mai potrivită. Ea are sintaxa:
switch ($var)
{
case v1:
acţiuni;
break;

case v2:
acţiuni;
break;

case v3:
acţiuni;
break;

default:
acţiuni default;
}
Exemplu:
switch ($submit)
{
case "insert":
// instructiuni pt. inserare in baza de date
break;
case "update":
// instructiuni pt. actualizarea bazei de date
case "display":
// instructiuni pt. imprimare
break;
}
Porţiunea din scriptul anterior realizează o acţiune comandată prin apăsarea unui buton de tip
submit dintr-un formular. În funcţie de butonul apăsat, valoarea transmisă scriptului diferă. În
cazul "update" instrucţiunea "break" lipseşte, deci după actualizare se va executa și codul
specific imprimării ($submit = "display").

Instrucţiunea while
Instrucţiunea while provoacă repetarea unei acţiuni atâta vreme cât o condiţie este adevărată.
Sintaxa instrucţiunii este:
while (condiţie) {
acţiune
}
Exemplu:
$articole = [];
$cda = "SELECT nume, prenume, gen FROM util ORDER by nume";
if ($rez=mysqli_query($cnx,$cda)) {
// Se preiau liniile pe rand
while ($linie = mysqli_fetch_assoc($rez)) {
$articole[] = $linie;
}
}
Așa cum se va vedea în cele ce urmează, această structură de cod va fi folosită pentru
recuperarea de informaţii dintr-o bază de date.
Instrucţiunea do ... while determină repetarea unei acţiuni atâta vreme cât o condiţie este
adevărată. Spre deosebire de while, condiţia de continuare a ciclului este testată după
executarea cel puţin o dată a acţiunii. Sintaxa instrucţiunii este:
do {
acţiune
}
while (condiţie);

Instrucţiunea for
Instrucţiunea for are sintaxa următoare:
for(exp1; exp2; exp3) {
acţiune
}
Exemplu:
<html>
<head>
<title>Calcule matematice in PHP</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.
css"

integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf2
3Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h2>Calcul factorial</h2>
<?php
$factorial = 1;
for ($i=1; $i<7; $i++) {
$factorial *= $i; // atribuire combinata, ca în C.
echo "<p>" . $i . " factorial = " . $factorial . "</p>";
}
?>
</div>
</body>
</html>
Rezultat:

Instrucţiunea foreach
Instrucţiunea foreach se foloseşte exclusiv pentru prelucrarea elementelor şirurilor de valori.
Sintaxa instrucţiunii este:
foreach ($nume_sir as $variabila)
{
acţiune pentru $variabila
}
Exemplu:
$nume = array("Ion", "Maria", "George"); // Sir de valori de tip
"string" (sir de caractere).
foreach ($nume as $coleg) {
echo "$coleg este invitat la cina.<br>\n";
}

Instrucţiunile break și continue


Ca şi în C++, break întrerupe un ciclu sau un switch. Înstrucţiunea care urmează după break
este cea care urmează după instrucţiunea switch sau după ciclul care conţine break.
Instrucţiunea continue este folosită tot în interiorul ciclurilor şi comandă reluarea imediată a
ciclului întrerupând secvenţa de cod cuprinsă între locul în care continue este inserat şi
sfârşitul ciclului.
Exemplu:
<html>
<head>
<title>Accesare continut director</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.
css"

integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf2
3Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div class="container">
<?php
$nume = 'C:/xampp/htdocs/FamiliaMea/';
?>
<h2>Fisierele din directorul <em><?= $nume ?></em></h2>
<?php
$director = opendir ($nume);
while ($fisier = readdir($director))
{
if (is_dir ($nume . $fisier)) { // Am construit calea absoluta
continue;
}
echo "$fisier <br> \n";
}
closedir ($director);
?>
</div>
</body>
</html>
Funcţiile opendir() respectiv closedir() deschid respectiv închid un director iar funcţia
readdir() citeşte o intrare din acest director. Tipul intrării (fişier sau director) este testat prin
apelul funcţiei is_dir() şi în caz pozitiv, intrarea este ignorată (se execută instrucţiunea
continue).

Observație: Expresia <?= $nume ?> realizează afișarea în ecranul browser-ului a valorii
variabilei $nume. Este practic o formă prescurtată a variantei prezentate deja, <?php echo
$nume; ?>.
Instrucţiunea exit
Instrucţiunea exit opreşte imediat scriptul PHP. Acelaşi efect îl are funcţia die().
Exemplu:
die("Ati completat gresit formularul!");
Mesajul din argumentul funcției die va fi transmis spre browser și afișat în fereastra acestuia
înainte ca sriptul să fie oprit (ca efect al executării funcției die).

Instructiuni

Limbajul PHP este un limbaj de programare imperativ. Setul de instrucțiuni de control este cel
cunoscut de la alte limbaje din aceeași categorie:if, while, do, for, break și continue. Pentru
parcurgerea șirurilor de valori, în PHP se folosește instrucțiunea foreach. Pentru scrierea unui
șir de caractere în textul trimis browser-ului, se folosește echo.

TOP

Funcții PHP
Într-o aplicaţie scrisă în PHP pot fi întâlnite două tipuri de funcţii: funcţii definite de
programator pentru a evita scrierea repetată a unor secvenţe de cod sau pentru a uşura
înţelegerea codului și funcţii predefinite, aparţinând limbajului.

Definirea unei funcţii de către programator


Sintaxa unei funcţii scrise în PHP este următoarea:
function nume([listă_parametri]) {
corpul_funcţiei
[return expresie;]
}
Lista parametrilor transmişi unei funcţii poate lipsi. Dacă funcţia nu returnează nimic (lipseşte
instrucţiunea return) funcţia nu poate figura într-o expresie.
Exemple:
function calcul ($a, $b) {
$c = $a + $b;
return $c;
}
Apelul funcţiei se poate face astfel:
$rez = calcul(12, 223);
Valoarea returnată de o funcţie poate aparţine oricărui tip: string, array, integer, double etc.
function corectez($sir) {
if (isset($sir)) {
$sir = strip_tags(trim($sir));
$sir = mysql_real_escape_string($sir); // Pt. a preveni atacurile de
tip "SQL injection"
}
return $sir;
}
// Apelul functiei:
$nume = corectez($_POST["nume"]);

Vizibilitatea variabilelor
Utilizarea funcţiilor pune şi în PHP probleme de vizibilitate a variabilelor. În PHP o variabilă
declarată în afara oricărei funcţii este o variabilă globală iar o variabilă declarată într-o
funcţie este o variabilă locală. Spre deosebire de alte limbaje, pentru a fi vizibile într-o
funcţie, variabilele globale trebuie declarate folosind declaraţia global.
Exemplu:
function suma ($b) {
global $a;
$c = $a + $b;
return $c;
}

$a = 100;
echo suma(12);

Funcţii predefinite
PHP este deosebit de bogat în funcţii. O listă completă poate fi găsită la adresa
http://www.php.net/manual.
În contextul cursului de față, importante sunt funcţiile pentru prelucrarea şirurilor de
caractere.
În domeniul prelucrării şirurilor de caractere, PHP oferă o mare varietate de funcţii
predefinite, peste 70 la număr, ceea ce face posibilă realizarea în acest limbaj a celor mai
multe dintre prelucrările posibile în alte limbaje. Fiind orientat pe tratarea informaţiilor
conţinute în pagini web, PHP pune la dispoziţie şi o serie de funcţii specifice, deosebit de utile
în practică.

• trim() – este o funcţie care înlătură toate spaţiile de la începutul şi sfârşitul şirului dat ca
argument, inclusiv caracterele return, LF (line feed) sau tab. Prototipul funcţiei este:
string trim (string sir_dat)

• htmlspecialchars() - este o funcție care înlocuiește în șirul dat ca argument caracterele


destinate scrierii marcajelor HTML (<, >, etc.), astfel:
Caracter HTML Șir de substituție

& (ampersand) &amp;

" (ghilimele) &quot;

< (mai mic) &lt;

> (mai mare) &gt;

• explode() – realizează fragmentarea unui şir de caractere folosind separatorii conţinuţi într-
un alt şir. Rezultatul va fi un şir de elemente. Prototipul funcţiei este:
string[] explode(string separatori, string sir_de_prelucrat[, limita])
Exemplu de utilizare:
$cumparaturi = "1,67,32,16";
$elemente = explode(',', $cumparaturi); // separatorul este virgula si
// $elemente va fi un sir de valori numerice
foreach ($elemente as $articol) {
. . . // prelucrez elementul curent, $articol
}

• strip_tags() – realizează înlăturarea dintr-un şir de caractere a tuturor marcajelor HTML sau
PHP, cu excepţia unora specificate în mod explicit. Prototipul funcţiei este:
string strip_tags (string sir [, string marcaje_permise])
Funcţia este importantă deoarece permite înlăturarea pericolului includerii de către un
utilizator într-o casetă de text sau o zonă de text, a unor marcaje HTML sau scripturi PHP
nedorite.
Exemplu de utilizare:
$sir_bun = strip_tags($sir, "<em><strong>");

• str_replace() – realizează căutarea într-un şir de caractere a unui subşir şi înlocuirea sa cu un


alt şir. Prototipul funcţiei este:
string str_replace (string sir_cautat, string sir_substitutie, string
sir_de_prelucrat)
Exemplu:
$sir = "Cei patru evanghelisti erau trei";
$sir1 = str_replace("trei", "doi", $sir);

• strcmp() – este funcţia de comparare a două şiruri. Prototipul funcţiei este:


int strcmp (string sir1, string sir2)
Funcţia returnează o valoare pozitivă dacă primul şir este mai mare, 0 dacă şirurile sunt
identice şi o valoare negativă dacă primul şir este mai mic.

• strlen() – returnează lungimea şirului dat ca argument. Prototipul funcţiei este:


int strlen (string sir)

• strpos() – furnizează poziţia şirului dat ca al doilea argument în şirul dat ca prim argument.
Prototipul funcţiei este:
int strpos (string sir_dat, string sir_cautat [, int offset])
Funcţia returnează o valoare pozitivă dacă şirul este găsit şi FALSE dacă şirul căutat nu există.
Dacă parametrul offset este definit, acesta reprezintă poziţia în şirul dat de unde începe
căutarea.

Funcții

Fiind conceput pentru partea de logică a aplicațiilor web, limbajul PHP oferă un set extins de
funcții. În contextul prelucrării datelor trimise de formulare și cel al generării conținutului
paginilor dinamice, importante sunt funcțiile strlen(), trim(), htmlspecialchars(), strip_tags(),
strpos(), str_replace().

TOP

Aplicații în arhitectură client-server


Curs 4

Limbajul PHP (continuare)


Accesarea unei baze de date Afișarea datelor din baza
de date Exemple
Accesarea unei baze de date
PHP dispune de funcţii care pot asigura exploatarea unui mare număr de servere de baze de
date. În timp s-au definit de asemenea mai multe moduri de accesare a acestora. În cele ce
urmează se va prezenta modul de utilizare a serverului de baze de date MySQL, pentru
accesare fiind utilizate funcții incluse într-o extensie a limbajului PHP, MySQLi.
Observație: Pentru a utiliza MySQLi nu trebuie realizate instalări sau configurări deoarece
funcțiile specifice acestei extensii sunt integrate în PHP.

Conectarea la serverul de baze de date


Pentru conectarea la serverul de baze de date MySQL se utilizează funcția mysqli_connect()
având următorul prototip:
mysqli_connect(host,username,password,dbname);
Ea returnează o valoare (un obiect) care va fi folosită în continuare pentru a accesa baza de
date.
Pentru a realiza o conexiune la baza de date familia, utilizată în exemplele care vor urma,
pentru conectare se va apela scriptul următor:
<?php
$cnx = mysqli_connect("localhost","root","","familia"); // user: root,
fara parola!
// Conectare reusita?
if (mysqli_connect_errno()) {
die("Conectare la MySQL nereusita: " . mysqli_connect_error());
};
// Impun setul de caractere utf8
mysqli_set_charset($cnx,"utf8");
?>
Observaţii:
a. La crearea variabilei $cnx funcția mysqli_connect() a fost apelată cu patru parametri: adresa
serverului (de cele mai multe ori localhost deoarece scriptul PHP și serverul MySQL rulează
pe același calculator), un nume de utilizator și parola asociată (poate rămâne "root", fără
parolă, dacă se folosește pachetul de aplicații XAMPP și după instalare nu s-a realizat nicio
configurare) și numele bazei de date care va fi exploatată.
b. Funcția mysqli_connect_errno() returnează "true" dacă s-a produs o eroare în procesul de
conectare. Dacă da, se apelează funcția die() care permite trimiterea spre aplicația client a
unui mesaj și apoi se abandonează executarea scriptului. De regulă mesajul conține apelul
funcției mysqli_connect_error() care afișează cauza eșuării încercării de conectare.
c. Scriptul anterior poate fi salvat într-un fișier denumit de exemplu conect.php, care va fi
inclus în toate scripturile care accesează baza de date. Includerea scriptului conect.php într-un
alt script PHP, care accesează baza de date a aplicației, se va realiza prin inserarea liniei:
<?php
include 'conect.php';
. . .
d. Dacă serverul de baze de date MySQL accesat ar rula rulat pe un alt calculator şi nu pe cel
care găzduieşte site-ul, în locul denumirii localhost s-ar fi folosit adresa IP a calculatorului pe
care rulează MySQL sau numele de domeniu al acestuia. Exemplu:
$cnx = mysqli_connect("193.226.7.133","util7","parolaUtil7","familia");

Conectarea la o bază de date


Limbajul PHP oferă un set complet de funcții pentru exploatarea unei baze de date MySQL.
Aceste funcții aparțin unei extensii a limbajului, MySQLi. Înainte de a trimite comenzi
serverului de baze de date MySQL este necesară apelarea funcției mysqli_connect(). Această
funcție returnează o valoare care va fi utilizată în apelarea funcțiilor viitoare.

TOP
Afișarea datelor din baza de date
Aplicațiile web au rolul de a colecta și de a afișa date. În cazul aplicațiilor web care utilizează
serverul de baze de date MySQL, crearea bazei de date, a tabelelor acesteia și inserarea unui
set inițial de date necesar testării aplicației se realizează folosind PHPMyAdmin.
Componenta de server a unei aplicații web realizează generarea paginilor dinamice (cu
conținut dinamic). O astfel de pagină conține informații provenind din baza de date a
aplicației. Informațiile afișate într-o pagină dinamică depind deci de starea aplicației (de
conținutul bazei de date și de valorile unor parametri transmiși componentei care crează
pagina).
Generarea unei pagini dinamice care afișează date provenind din baza de date presupune
parcurgerea următorilor pași:
1. se creează o conexiune la baza de date,
2. se interoghează baza de date (prin una sau mai multe comenzi SQL SELECT),
3. se parcurge mulțimea de selecție creată și se inserează în elementele HTML din pagină
datele din mulțimea de selecție.
Observație: Pentru ca o aplicație web să afișeze informații corecte și de actualitate, trebuie
creat un sistem de întreținere a bazei de date. De regulă se creează o aplicație suplimentare, de
asistență. Este tot o aplicație web dar, de regulă, pentru a o putea folosi, un operator trebuie să
parcurgă un proces de logare. Paginile pe care le va putea accesa apoi acesta îi vor permite să
modifice informații din tabelele bazei de date. Pentru proprietarul aplicației web (sau persoana
însărcinată cu întreținerea bazei de date) această aplicație de asistență ține loc de
PHPMyAdmin. Din perspectiva asigurării securității bazei de date, persoanele care nu au
pregătire de specialitate trebuie să opereze în bază doar prin intermediul unor astfel de
aplicații.
Utilizarea limbajului PHP pentru interogarea bazei de date
Pentru a trimite serverului MySQL o comandă SQL SELECT, se apelează funcția PHP
mysqli_query():
$evnm = mysqli_query($cnx, "SELECT * FROM evenimente") or die("Eroare: "
. mysqli_error($cnx));
Primul parametru al funcției este variabila $cnx. Această variabilă a fost creată în scriptul
conect.php, care trebuie rulat înainte de a da comenzi serverului MySQL.
Al doilea parametru este un șir de caractere conținând comanda SQL SELECT care trebuie
executată. Deoarece comanda SELECT poate fi de multe ori complicată, în practică șirul de
caractere care conține comanda este scris separat și atribuit unei variabile, astfel:
$interogare = "SELECT * from evenimente";
$evnm = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
Observație: În cazul unor incidente legate de crearea unei mulțimi de selecție, comanda
SELECT, care de cele mai multe ori este la originea erorii, poate fi afișată în fereastra
browswer-ului, apoi copiată și executată direct în PHPMyAdmin (selectând tabul SQL din
bara de navigare a aplicației). Deci înainte de a apela mysqli_query() se va insera o
instrucțiune echo:
$interogare = "SELECT * from evenimente";
echo $interogare;
$evnm = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));

Parcurgerea mulțimii de selecție rezultată în urma unei interogări


În urma unei interogări rezultă o mulțime de selecție care va fi parcursă într-un ciclu while.
La fiecare repetare a ciclului se va prelua într-un șir asociativ un articol din mulțimea de
selecție, apelând funcția mysqli_fetch_assoc(). Această funcție are un singur argument,
variabila care conține mulțimea de selecție și care a fost inițializată prin apelul funcției
mysqli_query().
Pe lângă returnarea unui articol din mulțimea de selecție, mysqli_fetch_assoc() realizează
și trecerea la înregistrarea următoare. Dacă mulțimea de selecție este epuizată,
mysqli_fetch_assoc() returnează null, ceea ce va determina întreruperea ciclului while.
Exemplu:
while($articol = mysqli_fetch_assoc($evnm)) {
echo '<p>Eveniment: ' . $articol['titlu'] . '</p>';
}
Observații:
1. În cazul în care mulțimea de selecție poate conține un singur articol, while este înlocuit cu
if, ca în exemplul următor:
$interogare = "SELECT nume from clienti where id=$cod_util";
$util = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
if($articol = mysqli_fetch_assoc($util)) {
echo '<p>Sunteți conectat ca ' . $articol['nume'] . ' ' .
$articol['prenume'] . '.</p>';
}
2. Pentru scrierea mai simplă a unor astfel de structuri de cod, se poate folosi o sintaxă diferită
a instrucțiunii while:
<?php while(conditie): ?>
. . . // cod HTML și PHP
<?php endwhile; ?>
Împreună cu notația cunoscută deja, <?= $variabila ?> utilizabilă în cazul afișării valorii
unei variabile (sau a unei expresii) PHP, exploatarea unei mulțimi de selecție se poate scrie
astfel:
<?php while($articol = mysqli_fetch_assoc($evnm)): ?>
<p>Eveniment: <?= $articol['titlu'] ?> </p>
<?php endwhile; ?>

Exemple:

Scriptul evenimente.php
Selectarea opțiunii Evenimente din meniul aplicației Familia Mea afișează un ansamblu de
carduri Bootstrap (mai exact elemente <div class="card">), ca în imagine:
Informațiile necesare afișării unui card conținând informații despre un eveniment provin dintr-
un articol al tabelului evenimente. Acest tabel a fost creat în cursul 2. În el au fost de
asemenea inserate informațiile necesare testării. Acestea provin din template.
De exemplu, pentru afișarea blocului care descrie primul eveniment, codul din template este
următorul:
<div class="col-md-6 d-flex align-items-stretch">
<div class="card">
<div class="card-img">
<img src="assets/img/events-1.jpg" alt="...">
</div>
<div class="card-body">
<h5 class="card-title">Lara's 1th Birthday</h5>
<p class="font-italic text-center">Sunday, September 26th at
7:00 pm</p>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur
elit, sed do eiusmod tempor ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat</p>
</div>
</div>
</div>
În codul afișat au fost evidențiate informațiile care vor fi preluate din liniile tabelului
evenimente. Imaginea referită va fi însă preluată din directorul imagini.
În imaginile următoare se vede cum s-au introdus în tabelul evenimente datele necesare
testării codului care va fi scris în continuare.
După inserarea secvențelor de cod PHP necesare, codul secțiunii din pagină care generează
setul de carduri este următorul:
<!-- ======= Event List Section ======= -->
<section id="event-list" class="event-list">
<div class="container">
<div class="row">
<?php include 'conect.php';
// Creez multimea de selectie
$interogare = "SELECT * from evenimente";
$evnm = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
?>
<?php while($articol = mysqli_fetch_assoc($evnm)): ?>
<div class="col-md-6 d-flex align-items-stretch">
<div class="card">
<div class="card-img">
<img src="imagini/<?= $articol['imagine'] ?>" alt="...">
</div>
<div class="card-body">
<h5 class="card-title"><?= $articol['titlu'] ?></h5>
<p class="font-italic text-center"><?= $articol['data'] ?
></p>
<p class="card-text"><?= $articol['prezentare'] ?></p>
</div>
</div>
</div>
<?php endwhile; ?>
</div>

</div>
</section><!-- End Event List Section -->
În codul afișat au fost evidențiate secvențele scrise în limbajul PHP. După conectare și crearea
mulțimii de selecție necesară (variabila $evnm), s-a inserat un ciclu while. În corpul ciclului
se generează un card, informațiile afișate provenind în acest caz din câmpurile liniei curente a
mulțimii de selecție: $articol['imagine'], $articol['titlu'], $articol['data'] și
$articol['prezentare'].

Scriptul galerie.php
Selectarea opțiunii Galerie de imagini din meniul aplicației Familia Mea afișează o listă de
categorii (ALL, HOME, BEACH și VACATION) și un ansamblu de imagini:
Structurarea bazei de date, așa cum s-a realizat ea în cursul 2, permite crearea listei de
categorii folosind date dintr-un tabel (tabelul categorii). Denumirile fișierelor care conțin
imaginile și informațiile despre fiecare imagine sunt păstrate de asemenea într-un tabel
denumit fotografii, deci și acestea vor proveni din baza de date.
Pentru a putea testa funcționarea scriptului galerie.php, într-o primă etapă în cele două tabele
vor fi inserate înregistrări care vor permite afișarea datelor exact așa cum sunt afișate în
template.
Înregistrările adăugate în tabelul categorii:
Înregistrările adăugate în tabelul fotografii:
După încheierea testării înregistrările din cele două tabele vor fi șterse și se va putea trece la
inserarea datelor reale, folosind aplicația de gestionare a bazei de date menționată la începutul
cursului.
Pentru a putea insera secvențele de cod necesare trecerii de la varianta statică a secțiunii care
afișează galeria la cea dinamică, se va afișa mai întâi varianta din template:
<!-- ======= Gallery Section ======= -->
<section id="gallery" class="gallery">
<div class="container">

<div class="row">
<div class="col-lg-12 d-flex justify-content-center">
<ul id="gallery-flters">
<li data-filter="*" class="filter-active">All</li>
<li data-filter=".filter-home">Home</li>
<li data-filter=".filter-beach">Beach</li>
<li data-filter=".filter-vacation">Vacation</li>
</ul>
</div>
</div>

<div class="row gallery-container">

<div class="col-lg-4 col-md-6 gallery-item filter-home">


<div class="gallery-wrap">
<img src="assets/img/gallery/home-1.jpg" class="img-fluid"
alt="">
<div class="gallery-info">
<h4>Home 1</h4>
<p>Home</p>
<div class="gallery-links">
<a href="assets/img/gallery/home-1.jpg" data-
gall="galleryGallery" class="venobox" title="Home 1"><i class="bx bx-
plus"></i></a>
</div>
</div>
</div>
</div>

<div class="col-lg-4 col-md-6 gallery-item filter-vacation">


<div class="gallery-wrap">
<img src="assets/img/gallery/vacation-2.jpg" class="img-
fluid" alt="">
<div class="gallery-info">
<h4>Vacation 2</h4>
. . .
</div>
</section><!-- End Gallery Section -->
Pe codul inserat au fost evidențiate toate datele care provin din tabelele bazei de date.
Pentru scrierea codului PHP necesar, trebuie observat că vor fi necesare două interogări: una
pentru generarea listei de categorii și una pentru generarea zonei în care sunt descrise
imaginile.
Rezolvare:
<!-- ======= Gallery Section ======= -->
<?php include 'conect.php';
// Creez cele doua multimi de selectie
$interogare = "SELECT * from categorii";
$categ = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
$interogare = "SELECT * from fotografii";
$fotografii = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
?>
<section id="gallery" class="gallery">
<div class="container">

<div class="row">
<div class="col-lg-12 d-flex justify-content-center">
<ul id="gallery-flters">
<li data-filter="*" class="filter-active">All</li>
<?php while($cat = mysqli_fetch_assoc($categ)): ?>
<li data-filter="<?= $cat['clasa'] ?>"><?=
$cat['categorie'] ?></li>
<?php endwhile; ?>
</ul>
</div>
</div>

<div class="row gallery-container">

<?php while($foto = mysqli_fetch_assoc($fotografii)): ?>


<div class="col-lg-4 col-md-6 gallery-item <?= $foto['clasa'] ?
>">
<div class="gallery-wrap">
<img src="imagini/<?= $foto['fotografie'] ?>" class="img-
fluid" alt="">
<div class="gallery-info">
<h4><?= $foto['titlu'] ?></h4>
<p><?= $foto['comentariu'] ?></p>
<div class="gallery-links">
<a href="imagini/<?= $foto['fotografie'] ?>" data-
gall="galleryGallery" class="venobox" title="<?= $foto['titlu'] ?>"><i
class="bx bx-plus"></i></a>
</div>
</div>
</div>
</div>
<?php endwhile; ?>
</div>

</div>
</section><!-- End Gallery Section -->
În codul prezentat au fost evidențiate toate secvențele de cod PHP.

Afișarea datelor din baza de date


Pentru citirea datelor din baza de date se creează mai întâi mulțimea de selecție necesară.
Apoi, pentru afișare, într-un ciclu while se parcurg înregistrările acesteia. Fiecare executare a
ciclului while va începe cu preluarea într-un șir asociativ a liniei curente din mulțimea de
selecție. Apoi, în corpul ciclului, informațiile care ar trebui preluate din baza de date vor fi
înlocuite cu valorile corespunzătoare din șirul asociativ.

TOP

Aplicații în arhitectură client-server


Curs 5

Inserarea într-o bază de date


Comenzi adresate serverului
web Inserarea datelor într-o
bază de date Aplicația apliFamilia
Comenzi adresate serverului de web
Standardul HTTP (HyperTex Transfer Protocol) pe care se bazează comunicarea în în cadrul
WWW (World Wide Web) definește un ansamblu de nume de funcții (sau metode) pe care o
aplicație client (un browser de exemplu) le poate trimite serverului de web. Aceste denumiri
sunt denumite și verbe (sau comenzi) HTTP și sunt implementate de toate serverele de web.
Principalele comenzi care vor fi utilizate în cele ce urmează sunt GET și POST. Celelalte
comenzi (HEAD, PUT, DELETE, CONNECT, OPTIONS, TRACE și PATCH) sunt destinate
creării unor servicii web mai complexe, care depășesc aria de cunoștințe și de competențe
specifice acestui curs.
Comanda GET, utilizată deja, este trimisă de browser unui server de web pentru a primi
conținutul unei resurse. Conținutul primit trebuie să fie codificat folosind un standard de
reprezentare cunoscut de browser. De exemplu ar putea fi vorba despre un fișier în format
.html (static), un fișier conținând o imagine (.png, .gif, .jpg)sau un conținut generat de o
aplicație (script PHP, ASP, Java, Python, etc.). În acest ultim caz, rezultatul executării
comenzii și returnat browser-ului este de regulă tot cod HTML, dar acest conținut este
dinamic, deci depinde de starea aplicației lansate în execuție.

Utilizarea comenzii POST


Comanda POST se folosește pentru a transmite unei aplicații (un script PHP în cazul nostru)
un set de date. De cele mai multe ori setul de date trimis va fi stocat întro bază de date.
Aplicația referită în comandă va citi setul de date transmis de browser din fișierul standard de
intrare (stdin din limbajul C++). Trimiterea spre aplicația referită a datelor se realizează
folosind un șir de caractere având formatul:
param_1=val_1&param_2=val_2& ... &param_n=val_n
Acest format este similar celui folosit în cazul comenzii GET pentru transmiterea valorilor
unor parametri.
Pregătirea datelor în forma cerută și transmiterea este realizată automat de către browser iar
interpretorul PHP va adăuga (tot automat!) aplicației PHP apelate un șir asociativ denumit
$_POST în care va memora valorile parametrilor primiți.
Acest mecanism este specific preluării datelor din formulare.
Inserarea datelor într-o bază de date

Crearea unui formular


În aplicațiile web, pentru introducerea datelor trebuie create formulare. Acestea utilizează
elemente HTML cunoscute: <input>, <textarea>, <button>, etc..
Revenind la site-ul (aplicația web) FamiliaMea, selectarea ultimei opțiuni de pe bara de
navigare, Contact, provoacă afișarea unei pagini care conține un astfel de formular.

Observație: Pagina afișată conține și o hartă, dar aceasta nu apare în captură deoarece nu are
legătură cu subiectul abordat.
Codul HTML care descrie formularul din imagine este următorul:
<form action="forms/contact.php" method="post" >
<div class="form-row">
<div class="col-md-6 form-group">
<input type="text" name="name" class="form-control" id="name"
placeholder="Your Name" data-rule="minlen:4" data-msg="Please enter at
least 4 chars" />
<div class="validate"></div>
</div>
<div class="col-md-6 form-group">
<input type="email" class="form-control" name="email" id="email"
placeholder="Your Email" data-rule="email" data-msg="Please enter a valid
email" />
<div class="validate"></div>
</div>
</div>
<div class="form-group">
<input type="text" class="form-control" name="subject" id="subject"
placeholder="Subject" data-rule="minlen:4" data-msg="Please enter at least
8 chars of subject" />
<div class="validate"></div>
</div>
<div class="form-group">
<textarea class="form-control" name="message" rows="5" data-
rule="required" data-msg="Please write something for us"
placeholder="Message"></textarea>
<div class="validate"></div>
</div>

<div class="text-center"><button type="submit">Send


Message</button></div>
</form>
Observație: Față de varianta din template, în codul formularului au trebuit suprimate unele
elemente. În varianta inițială, elementele suprimate erau utilizate de către un script JavaScript
care modifica funcționarea normală a formularului.
Pe codul formularului sunt, de asemenea, evidențiate niște atribute ale unora dintre elemente.
Acestea sunt importante din perspectiva prelucrării datelor din formular. Astfel din prima linie
se poate ști că scriptul care prelucrează datele trebuie pus în subdirectorul forms și se numește
contact.php. De asemenea, serverului web Apache i se va trimite o comandă POST, deci în
scriptul PHP apelat, formulare/contact.php, datele transmise (împreună cu comanda) vor fi
disponibile în șirul asociativ $_POST.
Se știe deja că, în PHP, un șir asociativ conține perechi de forma cheie => valoare. Pentru
fiecare element din formular destinat preluării unei informații (<input>, <textarea>, etc.),
perechea cheie=>valoare din $_POST se formează după regula: cheie este valoarea
atributului name al unui element din formular iar valoare este conținutul (sau valoarea)
acestuia.
În codul afișat au fost evidențiate toți parametri care vor fi trimiși: name, email, subject și
message.

Crearea tabelului impresii


Pentru păstrarea mesajelor trimise cu ajutorul formularului prezentat, va trebui adăugat în
baza de date familia un tabel suplimentar, impresii.
Deoarece formularul permite introducerea a 4 valori (4 șiruri de caractere), noul tabel va avea
5 câmpuri, câmpul suplimentar fiind necesar pentru a defini cheia primară.
Observație: În tabele destinate păstrării impresiilor vizitatorilor se adaugă frecvent o coloană
suplimentară,destinată păstrării datei calendaristice.
Prelucrarea și memorarea informațiilor
Orice formular expus accesării prin Internet poate fi subiectul unor tentative de atac
informatic. Din acest motiv prelucrarea datelor transmise spre server în momentul apăsării
butonului de tip <submit> al formularului trebuie să se realizeze astfel încât atacurile să nu
producă efecte.
Scriptul forms/contact.php va începe deci cu preluarea datelor transmise prin intermediul
șirului asociativ $_POST și apelarea unor funcții PHP destinate eliminării marcajelor utilizate
într-un eventual atac.
<?php

function corectez($sir) {
$sir = trim($sir);
$sir = stripslashes($sir);
$sir = htmlspecialchars($sir);
return $sir;
}

// preiau valorile din campurile formularului (nume, email, subiect si


mesaj)
// și verific daca acele campuri au fost completate
$eroare = '';

if(empty($_POST['name'])) {
$eroare .= '<p>Nu ați introdus numele!</p>';
} else {
$nume = corectez($_POST['name']);
}

if(empty($_POST['email'])) {
$eroare .= '<p>Nu ați introdus adresa Dv. de e-mail!</p>';
} else {
$email = corectez($_POST['email']);
}
if(empty($_POST['subject'])) {
$eroare .= '<p>Nu ați introdus subiectul!</p>';
} else {
$subiect = corectez($_POST['subject']);
}

if(empty($_POST['message'])) {
$eroare .= '<p>Nu ați introdus mesajul!</p>';
} else {
$mesaj = corectez($_POST['message']);
}

// Verific daca preluarea datelor s-a derulat corect


if($eroare == '') {
// Nu sunt mesaje de eroare
include '../conect.php';
// formulez comanda INSERT
$comanda = "INSERT INTO impresii (nume, email, subiect, mesaj) VALUES (?,
?, ?, ?)";
if($stm = mysqli_prepare($cnx, $comanda)) {
mysqli_stmt_bind_param($stm, 'ssss',$nume, $email, $subiect, $mesaj);
mysqli_stmt_execute($stm);
} else {
echo "Eroare la crearea variabilei de tip statement.";
}
mysqli_close($cnx);
// Reincarc "index.php"
header('Location: ../index.php');
} else {
echo "Eroare: " . $eroare;
}
?>
Observații:
1. Funcția corectez() are rolul de a împiedica inserarea de cod html în controalele
formularului. Anumite tipuri de atacuri se bazează pe lipsa acestor prelucrări aplicate șirurilor
de caractere introduse în câmpurile formularelor, grav fiind atacul de tip XSS (vezi Cross Site
Scripting). Acest tip de atac permite furtul de identitate a unui operator care introduce date în
fomular, dar și alte acțiuni, la fel de grave.
2. La începutul scriptului s-a declarat variabila $eroare și s-a inițializat cu "" (un șir de
caractere vid). În cazul în care unul dintre câmpurile formularului nu este completat, în
această variabilă se adaugă un mesaj explicativ.
3. Pentru a verifica dacă s-a introdus o valoare într-un câmp al formularului, se apelează
funcția PHP empty(). De exemplu, pentru a verifica dacă s-a introdus o adresă de e-mail în
câmpul email (valoarea fiind automat preluată în $_POST['email']) se va scrie:
if(empty($_POST['email'])) { ... }
Desigur, această verificare este insuficientă pentru a verifica dacă șirul de caractere introdus
respectă sintaxa specifică unei adrese de e-mail. Pentru o verificare mai consistentă accesați
https://www.w3schools.com/php/php_form_url_email.asp.
4. Pentru a accesa din /FamiliaMea/forms/contact.php fișierul /FamiliaMea/conect.php
necesar creării conexiunii cu baza de date, calea spre fișierul conect.php trebuie scrisă astfel:
../conect.php. Așa cum se știe, ".." indică directorul părinte al directorului curent.
5. Un alt tip de atac informatic cu care ne putem confrunta este cel denumit SQL Injection
(explicații aici). Pentru prevenirea lui, soluția consacrată este utilizarea obiectelor de tip
prepared statements. Exemplu concret:
$comanda = "INSERT INTO impresii (nume, email, subiect, mesaj) VALUES (?,
?, ?, ?)";
if($stm = mysqli_prepare($cnx, $comanda)) {
mysqli_stmt_bind_param($stm, 'ssss',$nume, $email, $subiect, $mesaj);
mysqli_stmt_execute($stm);
} else {
echo "Eroare la crearea variabilei de tip statement.";
}
În exemplul dat, $stm este o variabilă de tip prepared statement. Ea se creează pornind de la o
comandă SQL incompletă, în care, în locul unor valori preluate din formular se scriu caractere
'?' (semne de întrebare). Apoi se realizează asocierea valorilor preluate formular scriind:
mysqli_stmt_bind_param($stm, 'ssss',$nume, $email, $subiect, $mesaj);
Fiecare dintre literele din șirul 'ssss' indică natura unei informații care va fi inserată.
Caracterul 's' se folosește pentru un șir de caractere iar 'i' și 'd' se folosesc pentru numere
întregi, respectiv reale, în dublă precizie. Sunt 4 caractere 's' deoarece în locul caracterelor '?'
trebuie inserate 4 șiruri de caractere. Ordinea scrierii variabilelor este cea din comanda
INSERT.
6. Din lista de câmpuri din comanda SQL INSERT lipsește câmpul id. Acesta are valori
întregi, a fost declarat ca fiind de tip autoincrement și este cheia primară a tabelului impresii.
Valorile acestui câmp sunt generate automat de către serverul MySQL. Există însă
posibilitatea ca, după o comandă INSERT, să se apeleze o funcție PHP
(mysqli_insert_id()) care returnează valoarea cheii primare a ultimului articol inserat în
baza de date.
Exemplu:
...
mysqli_stmt_execute($stm);
//recuperez valoarea cheii primare
$cheiep = mysqli_insert_id($cnx);
... // Cod care foloseste variabila $cheiep
Variabila $cheiep preia valoarea unei chei primare, deci o valoare unică în tabelul impresii.
Ea poate fi utilizată ulterior în alte prelucrări, așa cum se va vedea în exemplele viitoare.
7. Dacă sunt erori în date, scriptul forms/contact.php nu trimite nicio informație (niciun
caracter!) spre browser. Pentru a nu se afișa o pagină albă, după apăsarea butonului de tip
submit al formularului, s-a inclus un apel al funcției PHP header(). Astfel scrisă, aceasta
impune browser-ului să încarce fișierul index.php.
header('Location: ../index.php');
Funcția header() se folosește și în alte situații în care trebuie trimise anumite informații spre
browser (este documentată pe larg aici). Indiferent pentru ce este utilizată, ea nu va produce
niciun efect decât dacă înaintea apelului ei nu a fost trimis spre browser nimic, niciun
caracter.

Testarea soluției
Pentru a verifica dacă inserarea a funcționat, se poate folosi PHPMyAdmin.
Exemplu de formular completat:
Articolul inserat în tabelul impresii:

Aplicația apliFamilia
Până în acest moment, gestionarea datelor din baza de date a aplicației FamiliaMea s-a
realizat folosind aplicația PhpMyAdmin. S-a menționat însă că această soluție este permisă
doar dezvoltatorului aplicației, deoarece accesarea bazei de date în modul permis de
PhpMyAdmin este de regulă rezervată doar persoanelor calificate în domeniul creării și
exploatării bazelor de date relaționale.
Realizarea acestei aplicații va începe cu crearea directorului apliFamilia în care vor fi
memorate fișierele acesteia. Este bine ca acest director să fie conținut în directorul principal,
FamiliaMea.

Inserarea în baza de date a unei imagini


Transferul spre serverul care găzduiește o aplicație web a unor fișiere conținând imagini
intervine foarte frecvent. Problema apare practic în orice secțiune a unei pagini care conține
imagini și care este generată dinamic.
Pentru a face posibil transferul fișierelor care conțin imagini, formularul cu ajutorul căruia se
va realiza încărcarea pe server va trebui aibă definit și atributul enctype, scris astfel:
<form action="formulare/adaugeveniment.php" method="POST"
enctype="multipart/form-data">
Pentru exemplificare va fi creat un script care permite adăugarea unei noi înregistrări în
tabelul evenimente al bazei de date familia. Scriptul PHP care va fi scris,
adaugeveniment.php, va aparține aplicației apliFamilia.
Pentru a minimiza eforturile de stilizare, scriptul adaugeveniment.php va utiliza elemente
prestilizate preluate din Bootstrap.
Scriptul adaugeveniment.php va conține un formular. Conținutul acestuia va corespunde
structurii tabelului evenimente.

Pentru început, conținutul fișierului adaugeveniment.php va fișierul recomandat ca starter


template în site-ul Bootstrap (https://getbootstrap.com/docs/4.0/getting-started/introduction/):
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

<!-- Bootstrap CSS -->


<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css
" integrity="sha384-
Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">

<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>

<!-- Optional JavaScript -->


<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/
GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min
.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXus
vfa0b4Q" crossorigin="anonymous"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+7
6PVCmYl" crossorigin="anonymous"></script>
</body>
</html>
Primele modificări vor viza definirea unui titlul (<title>) și adăugarea conținutului care va fi
afișat. Acesta va consta dintr-un element <h2> și a unui <form>, ambele incluse într-un <div>
având class="container".
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

<!-- Bootstrap CSS -->


<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css
"
integrity="sha384-
Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">

<title>Adaug eveniment</title>
</head>
<body>
<div class="container mt-5" style="max-width:800px;">
<h2>Adăugare eveniment nou</h2>
<section id="formular">

</section>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/
GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min
.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXus
vfa0b4Q" crossorigin="anonymous"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+7
6PVCmYl" crossorigin="anonymous"></script>
</body>
</html>
Formularul conținut în secțiunea <section id="formular"> poate fi construit folosind
secvențe de cod HTML copiate din pagina
https://getbootstrap.com/docs/4.0/components/forms/. El trebuie să afișeze cotroalele necesare
introducerii valorilor pentru câmpurile unei înregistrări din tabelul EVENIMENTE: imagine,
titlu, data și prezentare.
Conținutul formularului este următorul:
<section id="formular" class="mt-3">
<form action="formulare/adaugeveniment.php" method="POST"
enctype="multipart/form-data">
<div class="form-group row">
<label for="imagine" class="col-sm-3 col-form-
label">Selectați imaginea (600x400 px):</label>
<div class="col-sm-4 input-group mb-2">
<input type="file" name="imagine" id="imagine">
</div>
</div>

<div class="form-group row">


<label for="titlu" class="col-sm-3
col-form-label">Titlu:</label>
<div class="col-sm-9 input-group mb-2">
<input type="text" class="form-control" name="titlu"
id="titlu">
</div>
</div>

<div class="form-group row">


<label for="data" class="col-sm-3
col-form-label">Data:</label>
<div class="col-sm-9 input-group mb-2">
<input type="text" class="form-control" name="data"
id="data">
</div>
</div>

<div class="form-group row">


<label for="prezentare" class="col-sm-3 col-form-
label">Prezentare:</label>
<div class="col-sm-9 input-group mb-2">
<textarea class="form-control" name="prezentare"
id="prezentare" rows="3"></textarea>
</div>
</div>
<button type="submit" class="btn btn-primary mx-auto d-
block">Înregistrează!</button>
</form>
</section>

Ca și în cazul formularului destinat introducerii de impresii, și în codul acestui formular au


fost evidențiați parametrii care vor fi trimiși scriptului referit în <form>,
formulare/adaugeveniment.php, respectiv:
 imagine,
 titlu,
 data și
 prezentare.

Scriptul /formulare/adaugeveniment.php
<?php
// Afisez ce am primit
// print_r($_POST);

function corectez($sir) {
$sir = trim($sir);
$sir = stripslashes($sir);
$sir = htmlspecialchars($sir);
return $sir;
}

// preiau imaginea aleasa


$poza = $_FILES["imagine"]["name"];
$nmtmp = $_FILES["imagine"]["tmp_name"];
$extensie = pathinfo($poza,PATHINFO_EXTENSION);

// numele initial pt toate pozele


$pinit = 'temp.png';

// preiau valorile din campurile formularului (titlu, data si prezentare)


și verific daca au fost completate
$eroare = '';

if(empty($_POST['titlu'])) {
$eroare .= '<p>Nu ați introdus titlul!</p>';
} else {
$titlu = corectez($_POST['titlu']);
}

if(empty($_POST['data'])) {
$eroare .= '<p>Nu ați introdus data evenimentului!</p>';
} else {
$data = corectez($_POST['data']);
}

if(empty($_POST['prezentare'])) {
$eroare .= '<p>Nu ați introdus o prezentare!</p>';
} else {
$prezentare = corectez($_POST['prezentare']);
}

// Verific daca preluarea datelor s-a derulat corect


if($eroare == '') {
// Nu sunt mesaje de eroare

// formulez comanda INSERT


include '../../conect.php';
$comanda = "INSERT INTO evenimente (imagine, titlu, data, prezentare)
VALUES (?, ?, ?, ?)";
$stm = mysqli_prepare($cnx, $comanda);
mysqli_stmt_bind_param($stm, 'ssss', $pinit, $titlu, $data,
$prezentare);
mysqli_stmt_execute($stm);
// Preiau valoarea cheii primare
$nr = mysqli_insert_id($cnx);
//redenumesc fisierul continand imaginea si il copiez in directorul
poze din site (/htdocs/FamiliaMea/poze)

$poza_r = (string)"e".$nr.".".strtolower($extensie); // Numele incepe


cu 'e', urmeaza valoarea cheii primare si apoi extensia. Exemplu: e3.png
$cale = "../../imagini/$poza_r"; // Fiind in
directorul /FamiliaMea/apliFamilia/formulare, calea e mai complicata!
$rezultat = move_uploaded_file($nmtmp, $cale);
// schimb denumirea fisierului in articolul scris
$cdamodif = "UPDATE evenimente set imagine='$poza_r' where id=$nr";
mysqli_query($cnx, $cdamodif) or die("Nu merge update in tabel");

//inchid conexiunea
mysqli_close($cnx); //sau $cnx = null;
header('Location: ../adaugeveniment.php');
} else {
echo $eroare;
}
?>
Observație: Transferul pe server al unui fișier se realizează inițial într-un director temporar.
Este o măsură de precauție. În scriptul PHP care va realiza în final transferul fișierului în
directorul destinat păstrării imaginilor se pot apela o serie de funcții prin care se stabilește ce
s-a primit (tipul și mărimea fișierului). Scriptul poate opera și transformări ale fișierului primit
(redimensionare de exemplu).
Scriptul PHP /apliFamilia/formulare/adaugeveniment.php începe cu preluarea datelor
transmise în momentul selectării cu mausul a butonului de tip submit al formularului.
Deoarece la declararea formularului atributul method a primit valoarea POST, datele
transmise vor fi preluate din șirul asociativ $_POST (în câmpurile $_POST['titlu'],
$_POST['data'] și $_POST['prezentare']), denumirea fișierului fiind însă într-un alt șir,
$_FILES.
Inserarea unei noi înregistrări în tabelul evenimente se va realiza astfel:
- Se va adăuga în tabel un articol nou care va conține valorile primite, cu excepția denumirii
fișierului. În locul denumirii reale se va introduce o denumire temporară (temp.png).
- După executarea comenzii INSERT se va prelua întro variabilă (variabila $nr) valoarea cheii
primare atribuită de MySQL în momentul executării comenzii.
- Folosind variabila $nr se va crea o denumire de fișier în care primul caracter este 'e', în
continuare copiindu-se valoarea variabilei $nr. Extensia care va fi dată fișierului astfel
denumit va fi, desigur, extensia fișierului transferat (variabila $extensia).
Observație: Acest sistem de construire a numelui fișierului de pe server face imposibilă
apariția coliziunilor de nume deoarece variabila $nr are valoarea cheii primare a articolului
creat în fișierul fotografii. Dacă nu se proceda astfel, dat fiind modul de stabilire a denumirii
pozelor specific aparatelor de fotografiat digitale, ar exista o posibilitate de repetare a
aceleiași denumiri.
- Se modifică denumirea imaginii în articolul înregistrat în tabelul evenimente. Pentru a-l
localiza se folosește cheia primară (memorată în $nr).
- Ultimul pas este transferarea fișierului încărcat, din directorul temporar în directorul în care
va fi păstrat.
Observație: Calea folosită pentru a salva fișierul din directorul temporar în directorul
/FamiliaMea/poze/, ținând cont de faptul că scriptul în curs de executare este în directorul
FamiliaMea/apliFamilia/formular/ trebuie scrisă astfel:
$cale = "../../imagini/$poza_r";
Pentru verificarea funcționării scriptului apliFamilia/formulare/adaugeveniment.php, se poate
utiliza tot PHPMyAdmin:

Se poate de asemenea deschide directorul de pe server destinat păstrării pozelor încărcate. În


acest director se poate observa că s-a adăugat un fișier nou, e3.png:

TOP

Aplicații în arhitectură client-server


Curs 6

Programare avansată în PHP


Sesiuni Corectarea datelor Publicarea site-ului
Sesiuni
O mare parte dintre aplicațiile web sunt programate în PHP. Din acest motiv, o parte dintre
funcțiile din bibliotecile acestuia sunt destinate rezolvării unor probleme mai complexe.
Una dintre acestea este realizarea de sesiuni de lucru cu aplicațiile web. Conversația
operatorului cu o astfel de aplicație se realizează prin intermediul serverelor web obișnuite
(Apache, Nginx sau IIS), ori acestea sunt aplicații fără stare (eng. stateless). O astfel de
aplicație primește o comandă, o execută imediat sau o transferă unei alte aplicații,
specializate, după care așteaptă o nouă comandă. Între operator (și browser-ul utilizat de
acesta) și modulele specializate, scrise în PHP, este deci interpusă o aplicație care "uită tot ce
a făcut".
O aplicație web scrisă în PHP poate crea însă pe server un spațiu de stocare asociat acesteia.
În acest spațiu se pot memora diverse informații, ele rămânând accesibile pe toată durata unei
sesiuni de lucru cu aplicația.
Observație: Deoarece aplicația poate fi accesată de mai mulți utilizatori simultan, vor fi
practic definite mai multe astfel de spații de stocare, câte unul pentru fiecare client.
Un exemplu evident al necesității unui astfel de spațiu de stocare este asigurarea derulării unui
ciclu de cumpărare de produse de la un magazin virtual. Coșul de cumpărături constituie o
informație creată și apoi modificată succesiv de un ansamblu de scripturi PHP.

Crearea sesiunii
Inițierea unei sesiuni de lucru cu o aplicație PHP presupune crearea unei variabile denumită
$_SESSION. Practic va fi vorba despre un șir asociativ, valorile din șir fiind înregistrate pe
server (într-un fișier temporar).
O aplicație web poate crea pe server o singură variabilă $_SESSION. Crearea acesteia se
realizează folosind funcția PHP session_start(). Această funcție este apelată la începutul
tuturor scripturilor aplicației care trebuie să acceseze datele memorate în $_SESSION.
Primul apel al funcției session_start() va avea ca efect crearea variabilei $_SESSION și a
unui cod unic. Codul unic va fi utilizat ca nume al fișierului temporar menționat (care
păstrează valorile din $_SESSION). Acest nume va fi însă trimis imediat și browser-ului care a
apelat scriptul PHP. Browser-ul va memora local acest cod (sub forma unui cookie) și, din
acel moment va transmite serverului acel cod ori de câte ori utilizatorul aplicației apelează un
script al acesteia. Procedându-se astfel, toate scripturile PHP ale aplicației web vor putea
accesa informațiile din $_SESSION.

Distrugerea sesiunii
Odată cu încetarea lucrului cu aplicația web în cadrul căreia s-a creat o sesiune, aceasta
trebuie distrusă. Această acțiune poate fi declanșată folosind următoarea secvență de cod:
<?php
// se distrug variabilele memorate în șirul $_SESSION
session_unset();

// se distruge sesiunea
session_destroy();
?>
O sesiune deschisă se va distruge și singură, dacă se închide fereastra browser-ului sau după
trecerea unui interval de timp în care n-a fost accesată. Valoarea implicită a duratei unei
sesiuni este de 1440s (24 de minute).

Exemplu de utilizare
Aplicația folosită pentru administrarea bazei de date familia trebuie să poată fi utilizată doar
de o persoană autorizată. Primul script al aplicației, index.php, va trebui să afișeze un
formular de logare care să permită introducerea unui nume de utilizator și a unei parole.
Scriptul asociat acestui formular va trebui să caute în baza de date informațiile transmise de
formularul de logare. Dacă există un utilizator cu numele și parola primite, în $_SESSION,
care, așa cum s-a spus deja, este un șir asociativ, va fi adăugat elementul
$_SESSION['logat'] = true. Evident, dacă nu există un utilizator logat, nu se va scrie
nimic în $_SESSION și formularul de logare va rămâne afișat pe ecran.

Rezolvare
La prima accesare a aplicației web, fișierul index.php trebuie să afișeze conținutul din
imagine:

Pentru aceasta, el va fi realizat astfel:


1. Se creează o primă versiune a fișierului index.php bazată pe acest model, utilizat
deja.
<!DOCTYPE html>
<html>
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,
shrink-to-fit=no">

<!-- Bootstrap CSS -->


<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css
"
integrity="sha384-
Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<!-- Font Awesome CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-
awesome/4.7.0/css/font-awesome.min.css">

<link rel="stylesheet" href="stil.css">


<title>bdFamilia</title>
</head>
<body>
<header class="container-fluid colorat">
</header>

<!-- Optional JavaScript -->


<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/
GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min
.js"

integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXus
vfa0b4Q"
crossorigin="anonymous"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"

integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+7
6PVCmYl"
crossorigin="anonymous"></script>
</body>
</html>

Fișierul stil.css referit în index.php, are următorul conținut:


.colorat {
background-color: #008891;
color: white;
}

header {
height: 110px;
position: fixed;
top: 0;
z-index: 1000;
}

nav {
margin-top: 50px;
}
.login {
width: 100%;
background-color: white;
color: #333;
border: 1px solid #008891;
border-radius: 3px;
}
Rezultat:

1. Se adaugă la începutul fișierului index.php codul necesar deschiderii unei sesiuni.


<?php
session_start();
if(isset($_SESSION['logat']) && $_SESSION['logat'] == true) {
$display = "none";
$nume = $_SESSION['nume'];
} else {
$display = "block";
$nume = "Nelogat";
}
?>
<!DOCTYPE html>
<html>
<head>
. . .
Dacă este prima accesare a scriptului, se va crea codul sesiunii, așa cum s-a afirmat. Dacă nu
este prima accesare, codul sesiunii va fi transmis automat de către browser. Apoi se verifică în
șirul asociativ $_SESSION dacă $_SESSION['logat'] == true, deci dacă utilizatorul care a
lansat în execuție index.php s-a logat în prealabil. Variabilele create, $display și $nume sunt
folosite astfel:
. . .
<header class="container-fluid colorat">
<div class="container">
<nav class="navbar navbar-expand-sm navbar-dark bg-transparent">
<!-- Navbar content -->
<a class="navbar-brand" href="#">FamiliaMea</a>

<button class="navbar-toggler" type="button" data-toggle="collapse"


data-target="#navbarSupportedContent" aria-
controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle
navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="index.php">Acasă<span class="sr-
only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="evenimente.php">Evenimente</a>
</li>
<li class="nav-item">
<a class="nav-link" href="imagini.php">Imagini</a>
</li>
</ul>
<span class="navbar-text"><i class="fa fa-user-o" aria-
hidden="true"></i>
<?= $nume ?> &nbsp; <a href="formulare/delogare.php" class="btn
btn-outline-warning btn-sm"
role="button">Delogare</a></span>
</div>
</nav>
</div>
</header>

<div class="container-fluid d-flex align-items-center" style="height:


100vh; background-color: #E7E7DE;">

<!-- Blocul care contine formularul -->


<div class="container" style="display: <?= $display ?>">
<div class="row justify-content-center">
<div class="col-sm-8 col-md-6 col-lg-4">
<div class="login p-3">
<form action="formulare/logare.php" method="post">
<div class="form-group">
<label for="nume">Numele:</label>
<input type="text" class="form-control" id="nume"
name="nume">
</div>
<div class="form-group">
<label for="parola">Parola:</label>
<input type="password" class="form-control" id="parola"
name="parola">
</div>
<div class="text-center">
<button type="submit" class="btn
btn-primary">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
. . .
Rezultat:

Observații:
 Numele persoanei logate este afișat pe bara de navigare, astfel:
<span class="navbar-text"><i class="fa fa-user-o" aria-hidden="true"></i>
<?= $nume ?> &nbsp; <a href="formulare/delogare.php" class="btn btn-
outline-warning btn-sm"
role="button">Delogare</a></span>
 După numele persoanei s-a afișat un buton care va realiza delogarea operatorului. Ar
trebui ca acest buton să nu fie vizibil decât în cazul în care există un operator logat.
Pentru a păstra însă codul cât mai simplu, acest acest comportament nu a fost
implementat.
 Se observă de asemenea că variabila $display poate influența afișarea sau ascunderea
formularului de logare, valoarea ei fiind folosită ca valoare a proprietății CSS display
a blocului care conține formularul. Deci dacă $display are valoarea none, blocul care
conține formularul nu va mai fi afișat.
 Toată prima parte a fișierului index.php poate fi memorată în două fișiere PHP și
inclusă apoi prin două comenzi include atât în index.php cât și în fișierele care vor fi
realizate în continuare. Aceste fișiere vor fi denumite sesiune.php respectiv
header.php.
Fișierul sesiune.php:
<?php
session_start();
if(isset($_SESSION['logat']) && $_SESSION['logat'] == true) {
$display = "none";
$nume = $_SESSION['nume'];
} else {
$display = "block";
$nume = "Nelogat";
}
?>

Fișierul header.php poate fi copiat de aici.


 În cadrul unui site (sau a unei aplicații web), elementul <footer> este identic în toate
paginile. Acest element, împreună cu toate liniile de cod HTML până la </html> vor
fi inserate într-un fișier denumit chiar footer.php și poate fi copiat de aici.
Aplicând aceste transformări, fișierul index.php poate fi scris mult mai simplu:
<?php
include 'sesiune.php';
include 'header.php';
?>
<div class="container-fluid d-flex align-items-center" style="height:
100vh; background-color: #E7E7DE; margin-top: 110px;">
<div class="container" style="display: <?= $display ?>">
<div class="row justify-content-center">
<div class="col-sm-8 col-md-6 col-lg-4">
<div class="login p-3">
<form action="formulare/logare.php" method="post">
<div class="form-group">
<label for="nume">Numele:</label>
<input type="text" class="form-control" id="nume"
name="nume">
</div>
<div class="form-group">
<label for="parola">Parola:</label>
<input type="password" class="form-control" id="parola"
name="parola">
</div>
<div class="text-center">
<button type="submit" class="btn
btn-primary">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<?php
include 'footer.php';
?>
În site-ul FamiliaMea nu s-au operat astfel de structurări ale codului, deși toate paginile sunt
conținute în fișiere PHP. Dacă se examinează fișierele scrise, se pot, desigur, crea două fișiere
PHP care vor permite generarea primei părți respectiv a părții de final a fiecărei pagini.
Procedând astfel, orice modificare operată în cele două fișierele suplimentare menționate se
va afișa pe toate paginile (evident!) iar paginile vor deveni mult mai simpu de întreținut
deoarece ele vor conține doar codul care poate eventual suferi modificări.

1. Se adaugă bazei de date familia tabelul admin

Tabelul admin are trei câmpuri, id, nume și parola. În tabelul creat se adaugă un articol
(nume: admin și parola: 1234).

1. Se crează scripturile referite în index.php

Fișierul formulare/logare.php
<?php
session_start();

function corectez($sir) {
$sir = trim($sir);
$sir = stripslashes($sir);
$sir = htmlspecialchars($sir);
return $sir;
}

// preiau valorile din campurile formularului (nume și parola)


$eroare = '';

if(empty($_POST['nume'])) {
$eroare .= '<p>Nu ați introdus numele!</p>';
} else {
$nume = corectez($_POST['nume']);
}

if(empty($_POST['parola'])) {
$eroare .= '<p>Nu ați introdus parola!</p>';
} else {
$parola = corectez($_POST['parola']);
}

// Verific daca preluarea datelor s-a derulat corect


if($eroare == '') {
// Nu sunt mesaje de eroare
include '../../conect.php';
// formulez comanda SELECT
$comanda = "SELECT * FROM admin where nume = '$nume' and parola =
'$parola'";
if ($rez = mysqli_query($cnx, $comanda)) {
if ($linie = mysqli_fetch_assoc($rez)) {
$_SESSION['logat'] = true;
$_SESSION['nume'] = $linie['nume'];
}
mysqli_free_result($rez);
}

mysqli_close($cnx);
// Reincarc "index.php"
header('Location: ../index.php');
} else {
echo "Eroare: " . $eroare;
}
?>
Observație: Codul scris urmărește mersul din cursul 4, singura diferență importantă este
apelul funcției mysqli_fetch_assoc(). Dacă în cazul cursului 4 mulțimea de selecție putea
conține mai multe înregistrări, în cazul acesta poate fi doar una sau niciuna. În astfel de cazuri
while se înlocuiește cu un if care este adevărat dacă mulțimea de selecție conține un articol
și fals în caz contrar.

Fișierul formulare/delogare.php
<?php
session_start();
session_unset();
session_destroy();
// Reincarc "index.php"
header('Location: ../index.php');
?>
Pentru lansarea lui în execuție, secvența de cod din header.php a fost scrisă astfel:
<a href="formulare/delogare.php" class="btn btn-outline-warning btn-
sm"
role="button">Delogare</a>
Bootstrap permite reprezentarea elementelor <a> ca butoane. De altfel selectarea unui element
<a> a cărui atribut href indică numele unui script PHP provoacă executarea acelui script. Un
element <a> poate declanșa deci o acțiune, exact ca și un element <button>.

Sesiuni
Funcția session-start() realizează crearea unei sesiuni. Din momentul creării acesteia, în
șirul asociativ $_SESSION pot fi inserate valorile unor parametri de stare ai aplicației. Aceste
valori vor putea fi astfel accesate în toate scripturile aplicației care încep cu apelul funcției
session_start().

TOP
Corectarea datelor
Corectarea datelor din baza de date presupune mai mulți pași:
1. selectarea înregistrării care va fi modificată,
2. încărcarea într-un formular a conținuturilor câmpurilor acesteia,
3. editarea în formularul expus a informațiilor greșite și
4. executarea unui script PHP în care, folosind o comandă SQL UPDATE, se modifică
articolul din baza de date.
Primul pas presupune afișarea conținutului tabelului în care trebuie operate modificări. De
obicei este creată o reprezentare tabelară a datelor. Tabelul afișat va conține însă o coloană
suplimentară în care se afișează un element selectabil cu mausul (un <button<> sau un
element <a>) care va declanșa afișarea formularului dedicat operării corecturilor.
Pentru a exemplifica un astfel de proces, se va scrie scriptul imagini.php. Acesta va fi lansat
în execuție prin selectarea opțiunii Imagini de pe bara de navigare a aplicației apliFamilia.
Executarea scriptului produce o reprezentare tabelară a informațiilor despre imaginile din
tabelul imagini din baza de date. Pentru a putea interveni asupra unei înregistrări (modificare,
ștergere), tabelul afișat va avea o coloană suplimentară, Operații.
<?php
include 'sesiune.php';
if($nume == "Nelogat") {
header('Location: ./index.php');
}
include 'header.php';
?>

<?php
include '../conect.php';
$interogare = "SELECT * FROM imagini ORDER BY clasa";
// Execut comanda SQL
$trimit = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
?>
<section id="tabel_poze">
<div class="container-fluid d-flex align-items-center">
<div class="container" style="margin-top:130px;">
<table class="table table-image">
<thead>
<tr>
<th scope="col">Nr.crt.</th>
<th scope="col">Imagine</th>
<th scope="col">Titlu</th>
<th scope="col">Comentariu</th>
<th scope="col">Operații</th>
</tr>
</thead>
<tbody>
<?php
$i = 1; // $i este un contor care va fi incrementat în ciclul
while
while($rez = mysqli_fetch_assoc($trimit)): ?>
<tr>
<th scope="row"><?= $i ?></th>
<td class="w-25">
<img src="../imagini/<?= $rez['fotografie'] ?>"
class="img-fluid" style="max-width: 120px; height: auto">
</td>
<td><?= $rez['titlu'] ?></td>
<td><?= $rez['comentariu'] ?></td>
<td>
<a href="editFoto.php?editez=<?= $rez['id'] ?>">
<i class="fa fa-pencil-square-o fa-lg" aria-
hidden="true"></i></a>
<a href="formulare/sterg.php?sterg=<?= $rez['id'] ?>">
<i class="fa fa-trash fa-lg"
aria-hidden="true"></i></a>
</td>
</tr>
<?php
$i++;
endwhile;
mysqli_close($cnx);
?>
</tbody>
</table>
</div>
</div>
</section>
<?php
include 'footer.php';
?>

Scriptul imagini.php începe prin inserarea fișierului sesiune.php care conține un apel al
funcției session_start() și verificarea logării. După ce se execută codul conținut în
sesiune.php, se verifică dacă utilizatorul este logat. Dacă nu este, se rulează scriptul
index.php, abandonându-se scriptul curent. În acest mod se împiedică accesarea paginii
curente de către un utilizator nelogat.
<?php
include 'sesiune.php';
if($nume == "Nelogat") {
header('Location: index.php');
}
include 'header.php';
?>
Secvența de cod evidențiată în scriptul imagini.php inserează în ultima coloană (Operații)
două link-uri care afișează pictograme consacrate pentru editarea respectiv ștergerea unei linii
dintr-un tabel.
Cele două link-uri produc lansarea în execuție a două scripturi PHP, editFoto.php și
formulare/sterg.php. Acestea realizează afișarea informațiilor conținute într-un articol al
tabelului imagini respectiv ștergerea acestuia. Adresa referită de atributul href este creată
dinamic și conține și parametrul editez, acesta având valoarea cheii primare corespunzătoare
din tabelul imagini. Mecanismul inserării acestei valori este cel cunoscut, respectiv se iterează
folosind un o instrucțiune while în mulțimea de selecție pregătită în prealabil. În interiorul
ciclului se adaugă părții statice a adresei ("editFoto.php?editez=") valoarea cheii primare,
utilizând sintaxa cunoscută (<?= $rez['id'] ?>).
De exemplu plasarea cursorului mausului deasupra pictogramei evidențiată în imaginea de
mai sus produce pentru atributul href valoarea
http://localhost/FamiliaMea/apliFamilia/editFoto.php?editez=6 deoarece pentru
acel articol id = 6.
Scriptul formulare/sterg.php
Acest script realizează ștergerea unui articol din baza de date, după care se reîncarcă scriptul
imagini.php. Datorită transmiterii parametrului necesar folosind adresa scriptului, valoarea
parametrului va fi disponibilă în șirul asociativ $_GET.
<?php
// preiau valoarea cheii primare (parametrul "sterg")
$cheie = $_GET['sterg'];
include '../../conect.php';
// formulez comanda DELETE
$comanda = "DELETE FROM imagini where id = $cheie";
mysqli_query($cnx, $comanda);
mysqli_close($cnx);
// Reincarc "imagini.php"
header('Location: ../imagini.php');
?>

Scriptul editFoto.php
Acest script este mai complex. El afișează o interfață asemănătoare celei necesare inserării
unui nou articol, dar, în acest caz, toate câmpurile formularului vor avea valori inițiale.
Acestea provin din câmpurile articolului care este ediat.
Selectarea butonului de tip submit al formularului conținut în script va lansa în execuție
scriptul formulare/editFoto.php, transmiterea valorilor realizându-se prin metoda
corespunzătoare comenzii POST.
Codul scriptului editFoto.php este următorul:
<?php
include 'sesiune.php';
if($nume == "Nelogat") {
header('Location: ./index.php');
}
include 'header.php';
?>

<?php
include '../conect.php';
// Preiau valoarea cheii primare (parametrul "editez")
$cod_foto=$_GET['editez'];
$interogare = "SELECT * FROM imagini where id = $cod_foto";
// Execut comanda SQL din $interogare
$trimit = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
// Preiau într-un șir asociativ câmpurile articolului care trebuie editat
$rez = mysqli_fetch_assoc($trimit);

// Generez lista categoriilor


$interogare = "SELECT * FROM categorii";
// Execut comanda SQL din $interogare
$selcateg = mysqli_query($cnx, $interogare) or die("Eroare: " .
mysqli_error($cnx));
?>
<section id="tabel_poze">
<div class="container" style="margin-top:110px; padding: 20px;">
<h1 class="mt-3">Editare fotografie</h1>
<br />
<form action="formulare/editFoto.php" method="POST">
<input type="hidden" name="edit" value="<?= $cod_foto ?>" />
<div class="form-group row">
<label for="clasa" class="col-sm-2
col-form-label">Categoria:</label>
<div class="col-sm-3 input-group mb-2">
<select class="form-control" id="clasa" name="clasa">
<option value="0">Selectați categoria:</option>
<?php while($categ = mysqli_fetch_assoc($selcateg)): ?>
<option value="<?= $categ['clasa'] ?>"
<?= $categ['clasa'] == ".".$rez['clasa'] ? "selected" :
"" ?>>
<?= $categ['categorie'] ?></option>
<?php endwhile; ?>
</select>
</div>
</div>

<div class="form-group row">


<label for="fisier" class="col-sm-2 col-form-
label">Fotografie:</label>
<div class="col-sm-3">
<img src="../imagini/<?= $rez['fotografie'] ?>" alt=""
style="max-width: 160px; height: auto" >
</div>
</div>

<div class="form-group row">


<label for="titlu" class="col-sm-2 col-form-label">Titlu:</label>
<div class="col-sm-10 input-group mb-2">
<input type="text" class="form-control" value="<?=
$rez['titlu'] ?>" id="titlu" name="titlu">

</div>
</div>

<div class="form-group row">


<label for="comentariu" class="col-sm-2 col-form-
label">Comentariu:</label>
<div class="col-sm-10 input-group mb-2">
<input type="text" class="form-control" value="<?=
$rez['comentariu'] ?>" id="comentariu" name="comentariu">

</div>
</div>

<button type="submit" class="btn btn-primary mx-auto d-


block">Înregistrează!</button>
</form>
</div>
</div>
</section>
<?php
include 'footer.php';
?>
Rezultat:

Scriptul scris conține câteva elemente de noutate, evidențiate în codul afișat. De exemplu,
pentru a transmite cheia primară a articolului supus editării se folosește un element input de
tip "hidden":
<input type="hidden" name="edit" value="<?= $cod_foto ?>" />
Apoi, pentru a scrie atributul selected în elementul <option> care corespunde categoriei
selectate, se folosește operatorul ternar cunoscut din limbajul C++ și existent în toate
limbajele derivate din acesta. Sintaxa acestuia este:
condiție ? valoare pentru "true" : valoare pentru false
Concret:
<?= $categ['clasa'] == ".".$rez['clasa'] ? "selected" : "" ?>
Observație: În alte situații, vor fi probabil necesare impuneri de valori și altor tipuri de
controale Windows (de exemplu checkbox sau radioButton). Soluțiile vor trebui căutate
accesând resurse din Internet.

Scriptul formulare/editFoto.php
Acest script realizează editarea unui articol din baza de date folosind datele transmise la
apăsarea butonului de tip submit din formularul afișat de scriptul editFoto.php.
După preluarea datelor, scriptul continuă cu generarea unei comenzi SQL UPDATE și
executarea acesteia.
Codul scriptului este următorul:
<?php

// preiau din $_POST valorile primite: clasa, titlu si comentariu


$clasa = $_POST['clasa'];
// Elimin caracterul "." de la inceput
$clasa = substr($clasa, 1);

$titlu = $_POST['titlu'];
$comentariu = $_POST['comentariu'];
$edit = $_POST['edit']; // ID-ul imaginii
// formulez comanda UPDATE
include '../../conect.php';
$comanda = "UPDATE imagini set clasa=?, titlu=?, comentariu=? where id
= ?";
$stm = mysqli_prepare($cnx, $comanda);
mysqli_stmt_bind_param($stm, 'sssi', $clasa, $titlu, $comentariu, $edit);
mysqli_stmt_execute($stm);
//inchid conexiunea
mysqli_close($cnx); //sau $cnx = null;
header('Location: ../imagini.php');
?>

Observații:
1. Acest script este asemănător unuia care inserează un nou articol în baza de date. Totuși
nu s-au făcut verificări ale datelor transmise scriptului deoarece accesul la script este
permis doar persoanelor care au parcurs procesul de logare.
2. Odată finalizat acest script, aplicația apliFamilia implementează toate cele patru
operații specifice exploatării unei baze de date: crearea, afișarea, ștergerea și editarea
articolelor conținute în tabelele acesteia.

TOP
Publicarea
Pentru publicarea site-ului puteți opta pentru oricare dintre variantele gratuite de găzduire
web.
Vă prezentăm soluția oferită de https://ro.000webhost.com
Având în vedere că am construit un site dinamic care afișează unele date dintr-o bază de date
MySQL, publicare lui înseamnă atât copierea fișierelor și directoarelor care intră în
componența site-ului cât și reconstituirea bazei de date.
1. Crearea unui cont pe serverul care va găzdui site-ul
Contul devine valabil după confirmarea cerută pe adresa de email furnizată
2. Copierea site-ului FamiliaMea din calculatorul personal în directorul serverului
observație: site-ul FamiliaMea exista deja, am denumit site-ul FamiliaMea21.
observație: adoptând această metodă, directoarele nu se copiază automat. Ele vor
trebui copiate rând pe rând, ceea ce este un proces destul de anevoios. Se poate alege
copierea atât a directoarelor cât și a fișierelor prin metoda drag-and-drop.

3. Crearea bazei de date familiape serverul MySQL


observație: ne reconectăm folosind datele de logare.
observație: exportăm baza de date locală, creând un fișier cu extensia sql pe care il
vom importa pe server.

4. Adaptarea fișierului de conectare cu noile date


5. Vizualizarea site-ului
TOP

S-ar putea să vă placă și