Sunteți pe pagina 1din 243

Programarea Core PHP

Instalarea şi pregătirea pentru lucru


În această lecţie, vom învăţa cum să setăm mediul de dezvoltare şi ce ne trebuie ca să lucrăm cu
PHP. PHP este un limbaj de programare de scripting cu scop general. Iniţial, a fost proiectat ca
limbaj pentru crearea paginilor web dinamice. Face posibilă procesarea şi încărcarea rapidă a
paginilor, este simplu de înţeles şi de utilizat şi se execută pe aproape toate sistemele de operare.
PHP este procesat de către serverul web şi generează codul HTML sau o altă ieşire pe care
clienţii (care sunt cel mai des browsere web) pot să o recunoască şi să o interpreteze.

Ca să puteţi să creaţi pagini web interactive şi să executaţi programele PHP, este necesar să aveţi
acces la un server care suportă PHP. Însă, este lipsit de pragmatism ca, atunci când creaţi un site
web interactiv cu ajutorul PHP-ului, să trimiteţi pagina PHP la un server de la distanţă de fiecare
dată când doriţi să o testaţi. De aceea, se recomandă instalarea PHP pe plan local,
pe propriul calculator.

Unele sisteme de operare, precum Linux şi multe versiuni Unix, sunt livrate acum cu PHP deja
instalat. La alte sisteme de operare, precum Windows sau Mac OSX, trebuie să instalaţi singuri.

Aşadar, PHP este un limbaj de scripting al cărui scop primar, dar nu şi singurul (fiind vorba de
un limbaj de scripting cu scop general), este procesarea datelor pe serverul web şi implementarea
lor în codul HTML. Este vorba de un derivat direct al limbajului C şi o mare parte a sintaxei
acestuia este identică cu acest limbaj de programare. Este gratuit şi aplicarea lui în HTML este
foarte simplă.

Pentru determinarea funcţionalităţii PHP, trebuie să fie indeplinite câteva condiţii:

 Instalarea lui PHP pe calculatorul pe care vrem să se efectueze


Scripturile PHP se interpretează, ceea ce înseamnă că nu sunt activate în mod direct, ci
printr-un program de interpretare. Dacă pachetul PHP este instalat pe calculator, această
componentă va fi disponibilă;
 Instalarea unui server web pe calculatorul pe care dorim ca acest limbaj să se
efectueze
De fapt, PHP nu necesită un server web pentru executarea sa, ci doar un interpreter. Dar,
fiindcă vom vorbi de PHP în contextul web, este necesar şi un server web;
 Instalarea bazei de date pe calculatorul pe care vrem să se efectueze acest limbaj
De asemenea, aceasta nu este o componentă necesară, dar, fiindcă PHP este o punte de
legătură dintre paginile web şi date, se recomandă instalarea unei baze de date;
 Alegerea instrumentelor de codare a lui PHP
Codul-sursă PHP se poate scrie în cele mai elementare instrumente de procesare a
textului (de ex. Notepad). Însă, se recomandă utilizarea unui instrument care recunoaşte
(şi marchează) comenzile PHP. Este posibil (şi de preferat) să utilizăm în acest scop unul
dintre programele de producere a paginilor HTML (Adobe Dreamweaver, NetBeans,
Eclipse, Notepad++, SublimeText), care conţine şi partea de design. În acest curs, vom
utiliza Notepad++.

Instalarea lui PHP

Există mai multe moduri de instalare a lui PHP pe sistemul de operare (SO). Dacă este vorba de
Linux, instalarea se face în timpul sau după instalarea sistemului de operare, prin asocierea
serviciilor potrivite din distribuţia SO.

Când este vorba de sistemele de operare Microsoft Windows, instalarea se poate face în două
moduri: manual, componentă cu componentă, sau prin instalarea unui pachet care conţine
întregul sistem. Aceste pachete sunt extraordinar de practice şi ne vom axa pe unul dintre acestea
- WampServer. Cu ajutorul său, vom acoperi toate cele trei condiţii menţionate mai sus (PHP,
serverul web şi baza de date).

Pentru cerinţele acestui curs, puteţi să descărcați şi să instalaţi WampServer de pe internet:


(http://www.wampserver.com/en/).

Instalarea instrumentelor de codare

Pentru nevoile cursului, puteţi să descărcaţi şi să instalaţi instrumentul Notepad++ de la


următorul link: (http://notepad-plus-plus.org/).

După setarea corectă a tuturor serviciilor şi după pregătirea instrumentelor, utilizarea sistemului
şi producţia aplicaţiilor PHP pot începe. Totuşi, pentru a ne uşura munca, trebuie să cunoaştem
principiile de bază a funcţionării unui astfel de sistem.

Mai întâi, trebuie menţionat că regulile de mai sus nu sunt atât de stricte, aşa cum poate par la
prima vedere. De exemplu, chiar dacă nu dispunem de un interpreter PHP pe calculatorul
nostru, aceasta nu înseamnă că nu putem să creăm codul, iar apoi să-l activăm pe un alt
calculator. De asemenea, serverul/baza de date MySQL nu trebuie neapărat să fie pe acelaşi
calculator pe care se află şi serverul web. Acesta nu trebuie să se afle pe un singur calculator şi
nu este necesar să fie exact serverul web Apache (PHP poate fi efectuat şi pe serverul web MS
IIS). Cu alte cuvinte, există diferite variante care se pot implementa în funcţie de necesităţile
întregului sistem, dar care sunt, de asemenea, irelevante în momentul studierii bazelor limbajului
de programare. De aceea, pentru familiarizarea noastră cu limbajul, vom utiliza procedura
liniară, deşi aceasta poate nu va produce cele mai eficiente rezultate sau nu va reda imaginea
perfect în oglindă a unui sistem real. Ceea ce este important este să producem în mediul de lucru
condiţii cât mai apropiate de mediul de executare, pentru a facilita cât mai mult implementarea.
Coordonarea lui PHP cu serverul web

Rolul fiecărui server web se reduce, mai mult sau mai puţin, la o singură funcţie, aceasta fiind
acceptarea unei cereri trimise de utilizator prin internet, procesarea acesteia (care
presupune găsirea documentului conţinut în această cerere) şi trimiterea răspunsului către
utilizator.

Dacă cererea de utilizator conţine numele şi tipul documentului care există pe serverul web într-o
formă statică, serverul web va prelua documentul din sistemul de fişiere şi-l va livra
utilizatorului prin intermediul internetului. Totuşi, dacă cererea nu se referă la un document
existent, ci este cerut un conţinut care va fi generat în mod dinamic, serverul web trebuie să
creeze răspunsul prin pornirea scriptului conţinut de cerere şi să implementeze rezultatul în
documentul în care se află scriptul, după care să-l expedieze către utilizator. În final,
deoarece scriptul/programul este implementat într-un document, utilizatorul va primi rezultatul
sub forma unui document HTML valid.

Pentru acest proces, serverul web şi clientul (când spunem client, ne referim la un browser
precum Internet Explorer, Firefox, Chrome etc.) utilizează acelaşi limbaj - protocol de
comunicare. Limbajul se numeşte HTTP (HyperText Transfer Protocol) şi este modul principal
de comunicare între calculatoare pe internet.

Atunci, care este rolul lui PHP? Rolul lui PHP este să traducă şi să pornească scriptul menţionat,
dar şi să expedieze rezultatul obţinut către client. Trebuie să se ştie că PHP nu este singurul
limbaj care poate să facă acest lucru. Există şi alte limbaje care se descurcă destul de bine cu
această operaţiune (C#, VB, Java etc.), cu condiţia ca serverul să ştie despre care dintre ele este
vorba şi când trebuie să activeze şi unde să găsească interpreterii pentru acestea.

Dacă am vrea ca ceea ce am scris în paragraful precedent să fie prezentat sub forma unei
ilustraţii, aceasta ar arăta în felul următor:

1.1 - Ilustrarea transportului de date


Imaginea de mai sus arată deplasarea datelor de la client până la server. Mai întâi, clientul
generează cererea şi o împachetează în forma unei cereri HTTP, după care o expediază (1). Deşi
cererea poate avea diferite caracteristici, la bază aceasta are următorul conţinut (2):

GET /index.html HTTP/1.1


Host: www.some_site.com

Când cererea ajunge la server, acesta observă modul în care o va trata. Vedem că pe primul rând
al cererii este scris index.html. Aceasta este denumirea documentului pe care clientul îl solicită
de la server. Având în vedere că documentul are extensia html, serverul concluzionează că nu
trebuie să activeze codul de server, ci doar să transmită documentul înapoi la client, deoarece
HTML este limbajul pe care clientul îl înţelege în totalitate (3a). Dacă documentul ar avea
extensia .php, serverul ar angaja interpreterul php şi îi va trimite documentul (3b). Interpreterul
php va traduce şi va executa documentul (respectiv, codul php care se află în el), apoi va crea
răspunsul HTTP (4) şi îl va trimite clientului. O astfel de interpretare trebuie neapărat executată
pe server, deoarece clientul (browserul web) nu înţelege limbajul PHP şi, dacă acesta ar ajunge la
el, pe pagină s-ar afişa un simplu text, fiindcă clientul nu va fi capabil să-l interpreteze.
Răspunsul HTTP nu diferă mult de cererea HTTP. Aici, serverul descrie documentul pe care îl
trimite clientului. O parte a răspunsului arată cam aşa (4):

HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=UTF-8

În a doua parte a răspunsului, se află documentul în sine.

După obţinerea răspunsului, browserul îl analizează, apoi preia documentul, traduce conţinutul
HTML în forma înţeleasă de utilizator şi îl reprezintă pe pagină.

Identificarea limbajului de scripting

Pentru ca serverul web să recunoască cererea utilizatorului pentru executarea unui script, trebuie
îndeplinită cel puţin o condiţie. Această condiţie este ca documentul să aibă extensia potrivită. În
cazul lui PHP, această extensie este .php. Dacă ar fi fost vorba de un alt limbaj, extensia ar fi fost
diferită (de ex. C#, VB, J# - .aspx sau .asp, Java - .jsp etc.).

O altă condiţie este ca acest document să conţină un script. Aceasta nu este o condiţie propriu-
zisă de expediere a documentului către utilizator, deoarece chiar dacă nu conţine un script,
conţinutul său va fi expediat. Pur şi simplu, serverul web va porni PHP (interpreterul), care va
trece prin document, dar având în vedere că acest document nu conţine un script, nu va fi activat
nimic, iar documentul va fi expediat către client în forma sa iniţială. Dar, dacă vrem (şi vrem) ca
un script să se execute în documentul nostru, trebuie să înştiinţăm interpreterul despre acest
lucru. Soluţia este parsarea.
Ştim că întregul univers al HTML-ului este alcătuit din tag-uri, respectiv markere care
delimitează şi identifică anumite unităţi. Când o pagină cu extensia .php este expediată către
PHP, ea este parsată, adică îi sunt analizate toate tagurile. PHP-ul expediază toate tagurile
neinteresante sub forma în care le-a citit, până când ajunge la tagul care se referă numai la el.
Acest tag se marchează cu <?php ?>, <? ?> sau <?= ?>. Foarte rar, aproape niciodată, pentru
PHP se folosesc şi următoarele taguri <% %>. Aceste taguri sunt cunoscute şi ca taguri ASP şi
trebuie activate special în setările lui PHP pentru a putea fi folosite (până la versiunea PHP 5.4,
acelaşi lucru era valabil şi pentru tagurile <? ?> şi <?= ?>).

Notă:

PHP7 prevede eliminarea tagurilor ASP (<% %>) şi script (<script


language="php”></script>), aşadar utilizarea acestora nu va mai fi suportată.

Când parserul PHP recunoaşte acest tag, conţinutul tagului se activează şi se execută scriptul.

Trebuie avut în vedere că am marcat tagurile PHP cu <?php ?>, <? ?> sau <?= ?>, deşi acest
"sau" nu este o regulă. De fapt, setarea implicită a configurării lui PHP este să recunoască doar
tagurile de deschidere clar marcate, adică pe cele mai lungi (<?php ?>). Această setare se
schimbă deseori, astfel încât PHP recunoaşte şi tagurile prescurtate, dar în cazul în care pe
serverul de hosting (pe care vrem să ţinem permanent site-ul nostru) setările au rămas la valorile
implicite, tagul de deschidere mai lung este varianta cea mai sigură, fiindcă cel mai probabil nu
vom avea acces la fişierele de configurare (dacă nu schimbăm setările la nivelul scriptului), în
cazul în care această opţiune este dezactivată. În acest curs, vom utiliza numai tagurile de
deschidere lungi.

Este foarte important să menţionăm (deşi acest lucru reiese logic din textul de mai sus) că PHP
nu face posibilă nicio activitate după ce documentul este expediat către client. Aşadar, din
momentul în care PHP a executat scriptul, a generat HTML-ul prin intermediul scriptului şi a
expediat pagina, această pagină nu mai poate fi accesată. De aceea, în PHP nu putem crea
animaţii sau alt tip de mişcări în browser. Pentru acestea utilizăm alte instrumente de programare,
precum JavaScript, ActionScript Silverlight sau Java (Java Applet şi JavaFX).

Concluzie

Din această introducere tragem concluzia că scopul cursului este producerea scripturilor PHP
puse în slujba HTML-ului. Tocmai acesta este şi scopul-ţintă, deoarece PHP domină în
infrastructura menţionată. Fără HTML, studierea PHP-ului s-ar reduce la gestionarea numerelor
şi operaţiunilor matematice şi logice, la condiţii şi la alte calificative ale limbajelor de
programare. Fără aceste componente, bineînţeles că nu vom ajunge departe în PHP, dar studierea
lor va fi desigur mult mai interesantă făcând legătura cu HTML.
Mai multe informaţii

Apariţia lui PHP

PHP, în forma sa primară, a apărut în anul 1995. A fost creat de programatorul danez Rasmus
Lerdorf, din dorinţa de a urmări prin script numărul vizitatorilor de pe pagina web a CV-ului său.
Rasmus a numit acest limbaj Personal Home Pages.

Această versiune primitivă a limbajului (moştenită de la limbajul C) a fost doar baza pentru
dezvoltarea lui ulterioară. Ramus şi-a declarat foarte rapid proiectul ca Open Source, pentru a-l
dezvolta cu ajutorul unui număr mai mare de programatori.

Cel mai mare progres în perfecţionarea limbajului l-au făcut Zeev Suraski şi Andi Gutman în
anul 1997, prelucrând parserul principal complet al limbajului. Adăugându-i un nou nume
(PHP/FI), au adăugat şi suport pentru baza de date, prin care limbajul a obţinut forma pe care o
are mai mult sau mai puţin şi în zilele noastre.

În acest moment, se consideră că în jur de 60% dintre serverele web din lume funcţionează pe
baza tehnologiei Apache şi astfel, în majoritatea cazurilor, se subînţelege procesarea datelor în
PHP. Dacă adăugăm şi faptul că PHP (deşi nu prea des) se foloseşte şi pe alte platforme (IIS),
este clar că avem de-a face cu un limbaj cu funcţionalitate complexă.

Suraski şi Gutman (uniţi sub numele Zend) sunt şi astăzi principalii dezvoltatori şi promotori
ai limbajului PHP. Numele complet al PHP-ului astăzi este PHP-Hypertext Processor.

Instalarea manuală a PHP-ului

Pachetul binar pentru instalarea PHP-ului se află la adresa http://www.php.net/downloads.php. În


fişierele pe care le veţi descărca, veţi găsi şi instrucţiunile pentru instalare. De exemplu, pentru
sistemul de operare Windows 7 este necesar să facem următoarele:

1. Să instalăm un server web (Apache sau Microsoft Internet Information Server - IIS);
2. Să instalăm PHP;
3. Să conectăm PHP-ul instalat la server.

La adresa sus-menţionată sunt câteva fişiere. Unul dintre ele se numeşte installer.exe. Dacă
descărcați acest fişier, prin pornirea lui va fi instalat PHP-ul şi vor fi setate automat anumite
servere web. Alt mod de instalare este prin fişierul .zip, de pe aceeaşi adresă, dar atunci trebuie
să setaţi singuri şi serverul web. Instrucţiunile complete de instalare sunt parte constitutivă a
acestui fişier.

Descriere detaliată a descărcării şi instalării serverului Wamp


1. Accesaţi URL-ul: http://www.wampserver.com/en/;
2. Selectaţi opţiunea versiunii WampServer care corespunde cu sistemul dvs. de operare;

1.2 - Alegerea versiunii de WampServer

3. Selectaţi hyperlinkul download directly;

Notă:

Dacă înainte de instalarea serverului WAMP sistemul dvs. necesită şi instalarea lui Visual
Studio 2012 : VC 11 vcredist_x64/86.exe , atunci descărcaţi-l şi instalaţi-l şi pe acesta de la
linkul dat mai sus.

1.3 - Pagina de descărcare a lui WampServer


4. O să vă apară un mesaj în partea de sus a paginii:

1.4 - Linkul direct de descărcare WampServer

5. Alegeţi locaţia pentru salvarea pe harddiskul dvs. şi astfel va începe descărcarea;


6. După finalizarea descărcării, porniţi instalarea programului descărcat:

1.5 - Caseta de instalare a lui WampServer

7. Selectând folderul de instalare (care este singurul pas interactiv şi important pentru instalare),
veţi selecta şi folderul unde se va afla serverul dvs. MySQL, serverul Apache, precum şi
conţinutul web:

1.6 - Selectarea locației în care va fi instalat WampServer

8. Paşii pentru selectarea browserului implicit şi a serverului de mail pot fi lăsaţi la valorile
implicite;
9. La ultimul pas, lăsaţi selectată opţiunea "Launch WampServer now" pentru activarea automată
a sistemului;
10. În Tray, va apărea iconiţa lui WampServer. Dacă toate serviciile funcţionează corect, iconiţa
va arăta astfel:
1.7 - WampServer OK

Toate celelalte variante ale iconiţei, precum, de exemplu:

1.8. WampServer Error

arată că unul dintre servere nu este în stare bună de funcţionare. De obicei, acest lucru se
întâmplă dacă unul dintre porturile TCP/IP necesare pentru funcţionarea serviciului este închis
(MySQL server: 3306 sau Apache server: 80). Una dintre cele mai frecvente cauze este Skype-
ul, ceea ce înseamnă că acesta trebuie dezactivat (mai târziu, această problemă se va rezolva într-
un mod mult mai elegant).

11. Testaţi funcţionarea corectă a serverului web în felul următor:

 Porniţi browser-ul web;


 În câmpul Address al browser-ului, introduceţi adresa: http://localhost/

Rezultatul ar trebui să fie deschiderea următoarei pagini:


1.9 - WampServer - localhost

O astfel de pagină în browser înseamnă că serverul web funcţionează.

Pentru a verifica dacă funcţionează şi celelalte servicii (PHP şi MySQL), selectaţi unul dintre
hyperlinkurile de dedesubt de subtitlul Tools (phpinfo(), pentru PHP, şi phpmyadmin, pentru
MySQL).

Dacă rezultatele celor două ferestre arată ca în imaginile de mai jos, înseamnă că ambele servicii
(PHP, respectiv MySQL) funcţionează şi că instalarea a fost realizată cu succes:
1.10 - PHP_INFO
1.11 - PhpMyAdmin

La final, este recomandată activarea opţiunii prin care paginile stocate în cache să fie
încărcate din nou în browser, asta pentru a evita situaţia în care browserul nu afişează
schimbările făcute în codul paginii la care lucrăm.

Pentru a realiza aceasta, trebuie să mergem la elementul Tools - Internet Options al meniului
derulant Internet Explorer, să selectăm opţiunea Settings din Temporary Internet Files şi
apoi, în fereastra nou deschisă, să bifăm elementul Every visit to the page. Faceţi aceasta chiar
dacă în acest moment nu vi se pare un lucru deosebit de important.
1.12 - Internet Properties
1.13 - Temporary Internet Files and History Settings

Descriere detaliată a descărcării şi instalării lui Notepad++

1. Accesaţi adresa http://notepad-plus.sourceforge.net/uk/site.htm

2. Alegeţi opţiunea Download.


1.14 - Pagina de descărcare a lui Notepad++

3. Dați click pe Download.

4. După ce aţi descărcat fişierul, porniţi instalarea. Setaţi câţiva paşi liniari (citirea licenţei şi
alegerea folderului) cu componentele ca în imaginea de mai jos (dacă nu este deja setat astfel):

1.15 - Setarea lui Notepad++

5. În ultimul pas al instalării, lăsaţi bifat câmpul pentru pornirea aplicaţiei, iar după pornire setaţi
în aplicaţie limbajul la PHP, după care puteţi închide aplicaţia:
1.16 - Notepad++ Language

După ce mediul a fost pregătit pentru lucru, puteţi crea propria pagină PHP. Accesaţi directorul
c:/wamp/www (cu menţiunea că wamp poate fi instalat şi în alt director). În cadrul directorului
www, puteţi pune propriul fişier oarecare, în care vreţi să se afle codul dvs. php. De exemplu,
acesta poate fi fişierul test.php.

În fişierul test.php, creaţi următorul conţinut:

1<?php
2echo "Hello!";
3?>

Apoi, în browser tastaţi adresa până la fişier:


http://localhost/test.php

Dacă aţi făcut totul în mod corect, pe pagină va apărea mesajul:

Hello!

Lucrul cu fişierele de configurare

În interfaţa sa de utilizator, Wamp face posibilă accesarea simplă a tuturor fişierelor de


configurare ale serviciilor, care funcţionează sub el. Pentru a accesa fişierul de configurare
pentru PHP, este necesar:

 să deschidem opţiunile lui WampServer cu clic stânga în Tray;


 să selectăm opţiunea php.ini din submeniul PHP;

1.17 - WAMP - php.ini

 să schimbăm opţiunile dorite în fişierul de configurare;


 să salvăm fişierul de configurare;
 să restartăm serviciile.
1.18 - WAMP - Restart All Services

Acelaşi lucru îl putem face şi într-un mod mai complicat. Pentru aceasta, trebuie să mergem la
folderul în care se află PHP (de obicei, acesta este wamp/php), să deschidem şi să schimbăm
manual fişierul php.ini. Mai simplu este dacă în interfaţa de utilizator a lui Wamp alegem
opţiunea PHP settings şi, pur şi simplu, activăm sau dezactivăm opţiunea dorită.

Bineînţeles, această abordare este valabilă doar pentru mediul WampServer.

Instalarea PHP-ului pe sistemul de operare Linux

Descărcaţi versiunea de PHP de la următoarea adresă http://www.php.net/downloads.php.


1.19 - PHP Download

Apoi, în consolă găsiţi locaţia fişierului descărcat (cel mai probabil, numele fişierului va fi:
php5.x.x.tar.gz, dar numele exact depinde de versiunea PHP descărcată) şi poziţionaţi-vă în acest
director.

Despachetaţi arhiva descărcată cu ajutorul comenzii:

tar –xzf php5.x.x.tar.gz

Apoi, treceţi în folderul creat automat (php5.x.x) şi porniţi instalarea prin comanda:

./configure –prefix=/usr/local/php –with-apxs2=/usr/local/apache2/bin/apxs –


1with-mysql=/usr/local/mysql

sau printr-una din următoarele două comenzi, dacă nu ştiţi datele exacte de pe serverul Apache
sau MySQL:

1./configure –prefix=/usr/local/php –with-mysql=/usr/local/mysql


./configure –prefix=/usr/local/php<span style="font-size: 14px; text-align:
2justify;"> </span>

O astfel de instalare presupune că aveţi deja instalate serverele Apache sau MySQL pe
calculatorul pe care se află Linux. Astfel, veţi putea să asociaţi căile acestor două aplicaţii cu
instalarea.

După instalarea efectuată cu succes, faceţi compilarea prin comanda: make


şi instalarea prin comanda: make install

Zend şi CakePHP Framework

Având în vedere îmbunătăţirile şi cerinţele tot mai mare din partea utilizatorilor, a început să fie
utilizat şi framework-urile PHP. Cele mai populare sunt Zend şi Cake Framework.

Zend Framework este un Framework Open Source pentru dezvoltarea aplicaţiilor şi a serviciilor
web, utilizând PHP 5.3+. Având în vedere seriozitatea aplicării, acesta se foloseşte în cadrul
blocurilor orientate pe obiect, care nu aparţin tematicii acestui curs, dar despre a cărui utilizare
ne vorbeşte practic numărul de descărcări de peste 15 milioane.
Acesta se poate descărca de la următorul link:

http://framework.zend.com/downloads/latest

1.20 - Logoul Zend Framework

CakePHP este un Framework de dezvoltare Open Source gratuit şi rapid pentru PHP. Acesta
permite ca munca programatorilor să se desfăşoare într-un mod rapid şi structurat, fără pierderea
flexibilităţii. Este îmbunătăţit în privinţa tuturor instrumentelor necesare, care permit scrierea
codului şi se bazează pe esenţa ajungerii la o soluţie. Se poate descărca de la linkul:
http://cakephp.org/
1.21 - Logoul CakePHP Framework

Introducere în PHP7

Anul 2015 este considerat ca un an foarte important pentru dezvoltarea PHP-ului, deoarece la
sfârşitul anului se prevede prezentarea celei mai noi versiuni a acestui limbaj, PHP7. În afară de
noile funcţionalităţi pe care le va oferi PHP7, acesta va avea şi performanţe mai bune.
Îmbunătăţirea performanţelor se consideră ca unul dintre cele mai importante motive de
actualizare la noua versiune. Conform indicatorilor oficiali de până acum, un număr mare de
aplicaţii, care în momentul de faţă funcţionează pe versiunea PHP 5.6, vor funcţiona de două ori
mai rapid pe versiunea PHP7. În favoarea acestei afirmaţii sunt date şi rezultatele cercetării,
despre care puteţi afla mai multe la următorul link: http://talks.php.net/oz15#/ . Aici, vom
prezenta doar două diagrame prin care sunt ilustrate comparativ WordPress CMS şi Moodle
LMS, pe diferite versiuni de PHP:
1.22 - Wordpress - PHP7

1.23 - Moodle - PHP7


Deoarece în momentul de faţă nu cunoaştem sintaxa limbajului PHP, în lecţiile ce urmează vom
face referire la schimbările în sintaxă pe care le aduce versiunea PHP7.

Tagul PHP scris corect este:


<*php *>
<<>>
<?php ?>
………………………………………………….

Tipurile de date
În această lecţie, vom învăţa ce tipuri de date există în PHP. Când este vorba de variabile şi de
tipurile lor, PHP are un sistem de funcţionare foarte flexibil. Mai mult, acest sistem este atât de
flexibil, încât practic nici nu trebuie să ştim ce tipuri de date gestionăm şi nici care sunt
restricţiile lor. Pur şi simplu, PHP va încerca să extragă ceea ce poate din informaţiile care îi sunt
prezentate.

Însă, o astfel de deschidere faţă de programator nu înseamnă că tipurile într-adevăr nu există, ci


că lucrul cu ele este încapsulat într-un obiect simplu, pentru ca programarea să fie mai simplă şi
mai rapidă.

Tipurile în PHP

În clasificarea generală a tipurilor de date (acest lucru este valabil pentru aproape toate limbajele
de programare), distingem tipuri simple şi complexe. În afară de clasificarea dată, putem folosi şi
următoarea clasificare pentru tipurile de date:

 Tipurile scalare;
 Tipurile compozite;
 Tipurile speciale.

Tipurile simple sau scalare sunt tipurile care presupun doar o singură valoare la un moment
dat. PHP recunoaşte 4 tipuri simple de date:

 Integer: Reprezintă tipul de număr întreg a cărui valoare depinde de magistrala


procesorului şi de mediu (sistemul de operare). Dacă procesorul operează pe 32 de biţi,
dimensiunea acestui tip poate fi de la -2147483647 până la 2147483647. Pentru un
procesor pe 64 de biţi, valoarea maximă a acestui tip este de până la
9223372036854775807;
 Float: Tipul float se utilizează în PHP pentru toate operaţiile cu virgulă mobilă;
 String: Tipul string conţine valori textuale;
 Boolean: Conţine valoarea logică (true sau false). Boolean reprezintă două stări posibile:
adevărat şi fals. Valorile logice se utilizează predominant pentru compararea condiţiilor.
În PHP, valoarea false corespunde uneia dintre următoarele valori: număr întreg 0, real
0.0, string gol, caracterul '0' şi constanta NULL. Orice altă valoare se consideră adevărată
(true).

Avem şi 2 tipuri complexe (compozite).

Tipurile complexe sunt tratate, de obicei, ca depozite sau colecţii de alte date:

 Array: Conţine un şir de date. Acest şir conţine date de acelaşi tip sau de tip diferit, chiar
şi alte şiruri (array). Variabila care reprezintă acest tip este, de fapt, adresa din
memorie de unde începe colecţia acestor date;

 Object: Conţine un obiect. Cât despre obiecte, acestea sunt nişte structuri complexe de
date care conţin date şi funcţionalitate. Obiectele sunt simbolul programării orientate pe
obiect şi a limbajelor de programare orientate pe obiect, inclusiv PHP, motiv pentru care
vom acorda o atenţie specială obiectelor în acest curs.

Pe lângă această clasificare, mai există şi divizarea în tipuri numerice, stringuri şi Boolean.
Acestea sunt, de fapt, subcategorii în cadrul clasificării generale a tipurilor.

De ce ne interesează pe noi acest lucru? De ce am folosi ceva ce conţine o valoare corectă sau
falsă, un număr sau un text?

Să vedem formularul Facebook pentru crearea unui cont:


2.1 - Pagina de creare a unui cont Facebook
În multitudinea de informaţii care se pot introduce în acest formular, sunt marcate trei. Prima (1)
este Keep me logged in. Această opţiune poate fi activată sau dezactivată, aşadar pentru salvarea
acestei informaţii este nevoie doar de o stare din două posibile. Aceasta se suprapune cu tipul
Boolean descris în prima parte a lecţiei. Când data ajunge la server, o vom transforma în acest tip
şi vom continua să lucrăm cu ea în această formă. Evident, data naşterii se introduce prin trei
meniuri derulante (controlul Select). Fiecare dintre acestea conţine o listă de numere întregi. Prin
urmare, pentru toate cele trei informaţii, ideal va fi tocmai tipul de număr întreg (int/Integer)
descris mai devreme. În final, pentru datele reprezentate prin căsuțe text în formular există o
mare probabilitate că va fi folosit tipul string.

Tipurile numerice

Din acest grup fac parte integer şi float. Caracteristica acestora este că păstrează o valoare
numerică. PHP îşi va da seama de tipul valorii, în funcţie de modul în care o vom introduce.

Despre tipul integer am vorbit deja. Acest tip subînţelege valori marcate (negative şi pozitive), cu
o dimensiune permisă de sistem. Mai mult, acesta acceptă trei tipuri diferite de notaţie: zecimală,
octală şi hexazecimală.

Când este vorba de notaţia zecimală, manipularea este simplă, pentru că folosim această notaţie
şi în viaţa cotidiană. De exemplu, pentru a reprezenta numărul zece, vom scrie 10.

Notaţia octală şi hexazecimală sunt oarecum mai complicat de utilizat, însă nu se folosesc foarte
des. De fapt, notaţia octală se foloseşte cel mai des atunci când sunt manipulate drepturile în
stilul UNIX (0666, 0667, 0777).

Fiţi atenţi când manipulaţi numerele prin notaţia octală. Această notaţie se activează prin semnul
zero în faţa numărului, lucru pe care îl puteţi face din greşeală şi atunci când lucraţi cu un număr
zecimal. Acest lucru poate duce la rezultate incorecte în executarea programului.

De exemplu, în PHP, 100 desemnează numărul 100, dar 0100 desemnează numărul 64.

Notaţia hexazecimală subînţelege marcajul 0x (sau 0X, deoarece acest tip de notaţie nu este
sensibil la litere majuscule şi minuscule), după care se scrie valoarea hexazecimală.

Float (care se mai numeşte şi Double) subînţelege, de asemenea, valori marcate (pozitive şi
negative), dar, spre deosebire de integer, acest tip acceptă şi valori cu virgulă mobilă (valori
zecimale).

Float cunoaşte două tipuri de notaţie - zecimală şi exponenţială (Decimal şi Exponential).

Notaţia zecimală recunoaşte tipul tradiţional de scriere: 10.5, 0.55, etc. Vom recunoaşte scrierea
exponenţială prin marcajul e (sau E - de asemenea, nu este sensibil la majuscule şi minuscule),
care precedă baza numărului, urmat de numărul care desemnează numărul zero după
multiplicator.
De exemplu: 1e2 = 1 * 100 = 100 sau 1.2e2 = 1.2 * 100 = 120.

La manipularea tipurilor numerice, trebuie avut grijă la câteva elemente simple, dar foarte
importante, care pot afecta în mod negativ fluxul programului:

 Deja am menţionat că mărimea valorilor depinde mai ales de sistemul în care sunt
executate. Aceasta înseamnă că, trecând de la un sistem la altul, aplicaţia noastră poate da
rezultate diferite, asta în funcţie de performanţele sistemului.
 În PHP, tipurile Float pot da rezultate neaşteptate în timpul conversiei. De exemplu, dacă
convertim următoarea expresie în tipul integer: ((0.1 + 0.7) * 10), rezultatul conversiei,
deşi ar trebui să fie logic 8, va fi numărul 7. Aceasta pentru că în PHP rezultatul adunării
(0.1 + 0.7)* 10 este numărul 7.999999. La conversia în integer, zecimalele acestui număr
sunt pur şi simplu îndepărtate.

Stringurile

În PHP, stringul este un tip de date care conţine o colecţie sortată de valori binare, care poate să
reprezinte orice structură binară (imagine, sunet, text etc.). Totuşi, când spunem string, ne
referim în primul rând la un conţinut textual şi este cel mai bine să-l ţinem minte ca purtător de
conţinut textual.

Boolean

Despre tipul Boolean am spus mai multe în partea în care am abordat enumerarea tipurilor,
aşadar vom menţiona doar câteva caracteristici ale conversiei:

 La conversia din valoarea numerică în Boolean, toate valorile care nu sunt zero vor fi
convertite în true (până şi valorile negative);
 La conversia stringului în valoare Boolean, doar stringurile care nu au conţinut sau conţin
doar un caracter (0) vor fi convertite în false.

Pe lângă cele menţionate, PHP recunoaşte şi două tipuri de date speciale.

Resource

Acesta este un tip de date care este, de fapt, o referinţă la o anumită sursă de date. Este un tip
special şi există funcţii speciale pentru manipularea acestui tip. Din punct de vedere fizic, acesta
reprezintă un flux de date. De aceea, variabilele de acest tip se mai numesc şi Resource Stream
sau doar Stream.

Să luăm ca exemplu un fişier textual. Acest fişier nu este parte constitutivă a aplicaţiei, dar în el
(de exemplu) există anumite date necesare pentru funcţionarea acesteia. Pentru ca un
programator să poată accesa acest fişier, el trebuie tratat într-un anumit mod pe
parcursul executării programului. Dar, pentru a face aceasta, este nevoie de un obiect care să
reprezinte acest fişier în cod. Acest obiect se numeşte resursă/resource.

NULL

De fapt, acesta nu este un tip de date propriu-zis, ci mai degrabă o valoare fixă, care, de obicei,
aparţine obiectelor a căror valoare nu a fost atribuită sau a fost ştearsă. Tipul NULL poate avea
doar o singură valoare: NULL.

Conversia tipurilor

În majoritatea cazurilor, PHP are singur grijă de conversia unui tip în altul. Puteţi scrie simplu
"1" + 2 şi rezultatul va fi 3, deşi un tip este string şi altul este număr.

Totuşi, aceste conversii implicite funcţionează atunci când este vorba de tipuri simple de date,
dar nu şi în cazul tipurilor complexe. Tipul simplu nu se poate converti în resursă. Pe de altă
parte, ipotetic vorbind, resursa se poate converti în string, dar veţi obţine doar o reprezentare
textuală a acestei resurse.

Pentru a converti o valoare dintr-un tip în altul, folosim paranteze rotunde, în felul următor:

(tipul în care vrem să facem conversia) valoare

De exemplu, dacă am vrea să transformăm numărul 10 în string, am scrie:

1(string)10;

Dacă am vrea să transformăm un string în număr întreg, am scrie:

1(int)"10";

Bineînţeles, pentru ca o astfel de conversie să aibă sens, ar trebui să fie pus între ghilimele ceva
ce se poate traduce cu succes în număr (cum ar fi numărul 10 în exemplul precedent). Dacă nu
asigurăm o astfel de dată, PHP nu va crea probleme, ci va face conversia cât mai calitativ posibil.
În exemplul următor, ca rezultat al conversiei vom obţine cifra 0.

1(int)"a";

Următorul exemplu converteşte numărul 015 în valoare de tip număr întreg. Logic ar fi să nu se
întâmple nimic şi la ieşire să obţinem numărul 15, dar rezultatul nu va fi acesta.

1$x = 015;
2echo (int)$x;
În loc de cifra 15, vom obţine cifra 13. Acesta este, de fapt, un comportament normal, deoarece
valoarea $x este definită ca octală (are zero la început) şi de aceea, când se transformă în valoare
zecimală, nu este 15, ci 13. De fapt, valoarea 13 am fi obţinut-o şi dacă nu am fi executat
conversia, cu excepţia cazului în care hotărâm să formatăm numărul într-un alt fel la ieşire.

Formatarea numerelor

Deseori, la scrierea numerelor va fi nevoie şi de formatarea acestora, în cazul în care doriţi să


scrieţi cifre separate cu un anumit semn sau, de exemplu, să folosiţi separatorul pentru
zecimale. Pentru formatarea în formă de număr întreg, se foloseşte funcţia number_format():

1$number= 879.22;
2echo number_format($number);

Scrierea la ieşire va fi: 879

Funcţia number_format() rotunjeşte numărul pe care îl formatează la cel mai apropiat număr
întreg.

Valorile care se introduc în paranteze în timpul apelării funcţiei se numesc argumente sau
parametri. Aceste valori pot oferi funcţiilor informaţii suplimentare, referitoare la
comportamentul lor. Argumentele se separă prin virgulă. Pentru formatarea în formă de număr
zecimal, se stabileşte numărul locurilor zecimale ca al doilea argument în apelarea funcţiei. Dacă
în funcţie folosim numărul 879.223456:

1echo number_format($number, 2);

scrierea la ieşire va fi: 879.22

După cum putem vedea, funcţia number_format() poate funcţiona doar cu unul sau cu ambii
parametri. De asemenea, această funcţie poate accepta şi al treilea, şi al patrulea parametru, care
este opţional, ca şi al doilea. Al treilea parametru reprezintă definiţia marcajului care se va folosi
pentru separarea înregistrării zecimale, în timp ce al patrulea parametru reprezintă marcajul
pentru separarea miilor în înregistrarea numărului.

Exemplu:

1$x = 123456789.123;
2echo number_format($x, 2, "*", "/");

Scrierea la ieşire va fi: 123/456/789*12

De asemenea, în timpul lucrului va fi necesară şi formatarea valorilor monetare, de aceea vom


explica pe scurt bazele acestei formatări. Folosind funcţia money_format(), se formatează
numărul în aşa fel încât se introduce semnul pentru valuta dorită, separatorul locurilor zecimale
şi separatoarele grupurilor formate din câte trei cifre care corespund regiunii date. Ca primul
argument al funcţiei se apelează %n pentru ca cifra să se scrie în formatul american pentru valută
sau %i care reprezintă formatul standard pentru valuta care se foloseşte pe plan internaţional sau
local. Funcţia setlocale() setează regiunea şi datele locale.

Exemplu:

1
<?php
2 $number = 2234.16;
3 setlocale(LC_MONETARY, 'en_US');
4 print money_format('%n', $number);
5 print money_format('%i',$number);
6
7 setlocale(LC_MONETARY, 'fr_FR');
print money_format('%i', $number);
8
9 ?>
10

Notă:

Funcţia money_format() va funcţiona doar pe sistemul Linux, ceea ce înseamnă că nu este


suportată de sistemul Windows.

După executare, pe pagină apare următorul rezultat:

SAD: $2,234.16
USD: 2,234.16
2 234.56 EUR

Formatarea se poate face şi cu funcţia printf. Aceasta este ceva cu care persoanele cu experienţă
în limbajul de programare C sunt familiarizate deja. În exemplul următor, numărul definit este
prezentat în trei moduri: octal, zecimal şi binar, cu ajutorul funcţiei printf:

1$x = 015;
2printf("Octal x is: %o, decimal is %d, and binary is %b",$x,$x,$x);

Despre funcţia printf vom discuta mai târziu, acum vom spune pe scurt că în partea cuprinsă între
ghilimele se află textul care trebuie afişat şi că în acest text se află semne în locul cărora se va
afla parametrul corespunzător din lista de parametri aflată după partea din ghilimele. Aceste
semne încep cu semnul % urmat de semnul tipului. o este tipul numeric octal, d este zecimal, iar
b este binar. În string, avem trei apariţii, iar după string avem trei parametri dintre care fiecare
corespunde cu o anumită poziţie din string. Ca rezultat, vom obţine următoarea scriere pe pagină:
Octal x is: 15, decimal is 13, and binary is 1101

Time and Date (Data şi ora)

Data şi ora sunt elemente foarte importante în dezvoltarea paginilor şi a aplicaţiilor web. PHP vă
permite să lucraţi cu datele acestea în mod diferit faţă de stringuri. Calculatorul păstrează data şi
ora într-un format care se numeşte timestamp. Acest format exprimă o anumită dată şi ora prin
secunde. Fiindcă o astfel de exprimare a timpului nu este inteligibilă pentru utilizatorul obişnuit,
PHP o converteşte într-o formă utilizată de oamenii obişnuiţi.

Câteva dintre funcţiile PHP pentru lucrul cu ora și data sunt:

 date(format) - returnează data curentă, formatată după instrucţiunile în argumentul


format;
 checkdate(lună, zi, an) - verifică validitatea datei, adică dacă valorile pentru lună, zi şi an
sunt în intervalul corespunzător;
 time() - restaurează timpul curent, exprimat în secunde, începând de la 01 ianuarie 1970.

În tabelul de mai jos, sunt afişate formatele valide pe care le puteţi utiliza cu funcţia date():

a Scrie "am" sau "pm"


A Scrie "AM" sau "PM"
h Orele exprimate de la 01 la 12
H Orele exprimate de la 00 la 23
g Orele exprimate de la 1 la 12, fără zerouri în faţă
G Orele exprimate de la 0 la 23, fără zerouri în faţă
i Minutele (de la 00 la 59)
s Secundele (de la 00 la 59)
d Ziua din lună exprimată cu două cifre (01-31)
D Ziua din săptămână exprimată prin text abreviat (Mon – Sun)
I Ziua din săptămână exprimată prin text (Monday – Sunday)
F Întreaga denumire a lunii (January – December)
n Luna exprimată prin cifre (1-12)
Y Anul scris cu 4 cifre (2005)
y Anul scris cu 2 cifre (05)
s Sufixele englezeşti (th, nd, st)

Tabelul 2.1

Codul care urmează afişează data și ora curentă în cadrul paginii web:
1<?php
2echo 'Current date: '. date('d-n-Y');
3echo '<br/>';
4echo 'Current time:'. date('g:i:s a');
5?>

După executare, la ieşire vom obţine:

Current date: 31-1-2013


Current time: 11:33:26 am

Funcţia getdate() returnează un şir de perechi cheie-valoare. Valoarea pentru chei se obţine prin
punerea denumirii cheii scrise între ghilimele, în paranteze drepte, imediat după numele
variabilei. Mai multe despre această temă aflaţi în lecţia „Lucrul cu şiruri”.

Valorile returnate ale funcţiei getdate() sunt:

Value Key
Seconds seconds
Minutes minutes
Hours hours
Day of the month mday
Day of the week, numeric (Sunday is 0, wday
Saturday is 6)
Month, numeric mon
Year, numeric (4 digits) year
Day of the year, numeric (e.g., 299) yday
Day of the week, textual, full (e.g., weekday
“Friday")
Month, textual, full (e.g., “January") month
Seconds since epoch (what time( ) 0
returns)

Tabelul 2.2

1<?php
2$time= getdate();
3printf('%s,%d,%d',$time['month'],$time['mday'],$time['year']);
4?>

Pentru crearea unei variabile noi, care va conţine informaţii despre data şi ora care nu este una
curentă (deci este legată de trecut sau viitor), folosim funcţia date_create(). Această funcţie
acceptă scrierea timpului dorit.
De exemplu:

1$newDate = date_create('2015-3-20 10:15:55');


2echo date_format($newDate, 'd.m.Y / H-i-s');

După aceste linii de cod, rezultatul afişat pe pagină va fi:

20.03.2015 / 10-15-55

Clasa DateTime

Este important de menţionat că utilizarea funcţiilor prevăzute pentru formatarea şi prezentarea


datei şi a timpului nu este singurul mod de a lucra cu datele menţionate. Clasa DateTime în PHP
este ceva mai avansată decât tematica acestui curs, de aceea nu ne vom opri la ea mult timp.
Clasa DateTime aparţine stilului orientat pe obiect şi în continuare vom menţiona diferenţa dintre
scrierea de până acum şi cea orientată pe obiect. În exemplele precedente, pentru o scriere la
ieşire precum 2015-01-01 00:00:00 am folosit următorul cod:

1<?php
2$date = date_create('2015-01-01');
3echo date_format($date, 'Y-m-d H:i:s');
4?>

Însă, pentru stilul orientat pe obiect, codul este:

1<?php
2$date=new DateTime ('2015-01-01');
3echo $date->format('Y-m-d H:i:s');
4?>

Având în vedere că acum aveţi două moduri diferite de codare şi două cereri diferite de scriere şi
formatare a datei şi a orei, dvs. puteţi decide cum doriţi să lucraţi în continuare.

Alegeţi tipul compozit de date:


Integer
Boolean
Array
Float
String

Tipul de dată Boolean poate avea valoarea:


10.50
my text
TRUE
array()

Problema nr. 1

În aplicaţie, parola de identificare a utilizatorului se memorează în felul următor:

1<?php
2$pass = 11793847250045684;
3?>

La emiterea acestui număr, la ieşire apare următoarea valoare:

1.1793847250046E+16

Asupra acestui număr (parolă) nu se fac niciun fel de operaţii aritmetice, dar la ieşire parola
trebuie să fie afişată în modul adecvat.

Rezolvare:

Cel mai bine este ca valorile numerice mai mari, care nu necesită operaţii aritmetice, să se
reprezinte sub formă de string:

1<?php
2$x = "11793847250045684";
3?>

Problema nr. 2

În cadrul aplicaţiei PHP, se află o linie care emite date despre data și ora curente:

1<?php
2echo "Current time: " . Date("h:i") . "h, day is: " . Date("D/M/y");
3?>

Linia emite următorul rezultat:

Current time: 11:45h, day is: Wed/Jan/13

Utilizatorul doreşte să reprezinte data în următorul format:


Current time: 11:45, day is: 16/01/2013

Rezolvare:

1<?php
2echo "Current time: " . Date("h:i") . ", day is: " . Date("d/m/Y");
3?>

În stabilirea sarcinii, ca argument al funcţiei Date este folosit stringul cu structura "D/M/y". Cu
acest string definim formatul datei care va fi prezentat. Deja în stabilirea sarcinii se poate
observa că astfel de definiţie a formatului datei va returna scrierea Wed/Jan/13. În rezolvare,
avem stringul modificat care se transmite funcţiei şi arată astfel: "d/m/Y". Din acest motiv va fi
schimbat şi rezultatul prezentat pe pagină şi acum va fi scris astfel: 16/01/2013. În tabelul dat în
conţinutul lecţiei, puteţi să vedeţi şi celelalte variante posibile pentru formatarea orei şi a datei.

Problema nr. 3

În cadrul aplicaţiei, trebuie să se facă un sistem care va monitoriza operaţia de logare (dacă
utilizatorul este logat sau nu). Trebuie să se determine tipul de dată în care va fi depozitată
această informaţie.

Rezolvare:

Acest tip poate fi Boolean (true sau false), deoarece există două valori posibile, adevărat sau fals.

………………………………………….

Variabilele
În această lecţie, accentul va fi pus pe definiţia variabilei şi pe implementarea ei în limbajul PHP.

Variabilele în PHP

Variabilele sunt containere temporare de depozitare a anumitor valori. După ce o valoare se


depozitează în memorie, ea este reprezentată prin variabilă.

Tipurile de date pe care o variabilă le poate reprezenta sunt, bineînţeles, toate tipurile studiate în
lecţia precedentă.
În lecţia precedentă, am menţionat că PHP este capabil să convertească în mod automat şi
implicit un tip de dată în altul, asta în funcţie de operaţia executată asupra sa. Această
caracteristică a limbajului se numeşte Loosely typed (există şi Strong typed).

Aceasta înseamnă că nu va fi nevoie să acordăm o mare atenţie asupra modulului în care am


declarat un anumit tip, atâta timp cât ne adresăm acestui tip în mod adecvat.

De fapt, atunci când vorbim de variabile în PHP, există doar câteva reguli de care trebuie să
ţinem cont:

 Variabilele trebuie să aibă semnul $ înainte de o denumire concretă;


o Exemplu: $x sau $first_name

 Denumirea variabilei trebuie să înceapă cu o literă sau cu underscore (_);


o Exemplu: $a sau $_a

 Denumirea variabilei poate avea şi litere (a-z,A-Z), cifre (0-9) şi semnul (_);
 PHP este sensibil la litere majuscule şi minuscule, atunci când este vorba de variabile;
o Exemplu: $c_number şi $C_number sunt două variabile diferite.

 Denumirile pentru variabile nu pot conţine spaţiu gol (spaţiu/white space), ci în loc de
acesta se poate folosi underscore (_);
o Exemplul unei denumiri incorecte: $first name
o Exemplul unei denumiri corecte: $first_name

Deşi atunci când denumim variabilele nu trebuie să respectăm niciun fel de reguli de limbaj, este
de preferat să folosim una din convenţiile de scriere. Una dintre cele mai populare este notaţia
"Camel Case", care subînţelege litera majusculă la începutul fiecărui cuvânt din variabilă. De ex.
$MyVariabile sau $thisIsMyVariabile.

Să zicem că vrem ca în program să existe o variabilă cu denumirea $x şi care are valoarea 10.
Vom scrie:

1$x = 10;

În continuarea programului, vom avea la dispoziţie variabila $x cu valoarea 10. Şi, dacă scriem:

1echo $x;

pe pagină va fi scrisă cifra 10.

Dacă scriem:

1$myVar = "Hello!";
2echo $myVar;
pe pagină va fi scris mesajul Hello!

În PHP, la denumirea unei variable se poate atribui valoarea unei alte variabile. De exemplu:

1$mp = "myVar";
2$$mp = "content of myVar";

În acest caz, la denumirea unei alte variabile am atribuit valoarea primei variabile (mp), astfel
încât acum se poate ajunge la valoarea celeilalte variabile prin variabila:

1$myVar;

De asemenea, această valoare se poate obţine şi prin variabila:

1$$mp;

Dar şi când definim variabilele astfel, trebuie respectate regulile referitoare la numele
variabilelor. De exemplu, dacă definim variabila 123 în modul următor:

1$mp = "1myVar";
2$$mp = "content of myVar";

atunci când apelăm această variabilă ($myVar), s-ar produce o eroare, deoarece nu este permisă
utilizarea numerelor la începutul variabilei. Cu toate acestea, variabila şi valoarea care îi este
acordată vor fi depozitate în memorie şi vor fi accesibile prin următoarea sintaxă:

1${'1myVar'}

Trebuie să acordăm o deosebită atenţie unei astfel de abordări pentru că, dacă este inadecvată, în
aplicaţie pot apărea uşor probleme de securitate.

În PHP, nu există niciun mod de a securiza în totalitate existenţa unei variabile dintr-un anumit
punct din program, ceea ce poate duce la probleme funcţionale şi de securitate. De aceea, pentru
a reduce problema cauzată de acest dezavantaj, se foloseşte funcţia isset(), care examinează
existenţa unei variabile.

Această funcţie acceptă numele variabilei ca parametru şi returnează valoarea de tip Boolean ca
rezultat.

isset($myVar)

Dacă $myVar este definită anterior în cod, funcţia isset va returna valoarea true. În caz contrar,
această funcţie va returna valoarea false (vom vorbi mai mult despre funcţii în lecţiile
următoare).
Cu toate acestea, dacă manipulaţi variabile inexistente, PHP va fi capabil să proceseze astfel de
variabile în mod adecvat. De exemplu:

$a + 2

În cazul în care variabila $a nu există în codul anterior, PHP o va trata ca şi cum aceasta a avut
valoarea zero, iar rezultatul acestei expresii va fi 2. Un lucru similar se va întâmpla şi dacă
expresia este:

$a + $b

iar atunci rezultatul va fi zero, deoarece ambele variabile sunt tratate ca zerouri, chiar dacă nu au
fost definite în prealabil.

Acest rezultat va depinde de setările din fişierul php.ini. Inexistenţa variabilei poate produce o
eroare.

Domeniul variabilei

Declararea variabilelor nu se limitează la declaraţie în funcţie de valoare sau referinţă, ci acestea


pot fi declarate oriunde, bineînţeles, în cadrul scripturilor php. Însă, când este vorba de locaţia
variabilei, poate apărea o problemă de disponibilitate. Problema apare dacă declaraţi variabila
într-o parte a aplicaţiei şi o apelaţi în altă parte, mai exact dacă declaraţi variabila în cadrul unei
bucle, funcţii sau clase şi doriţi să o accesaţi în afara acestor cadre, programul se va alarma şi va
spune că variabila nu există. Astfel, ajungem la domeniul de accesibilitate a variabilelor.

Variabilele PHP pot să aparţină unuia dintre cele patru domenii de vizibilitate:

 Variabile locale;
 Parametrii funcţiilor;
 Variabile globale;
 Variabile statice.

Variabile locale - Variabilele care sunt declarate doar în cadrul funcţiei se numesc locale şi se
pot folosi doar în cadrul funcţiei respective. Dacă am încerca să-i atribuim variabilei o valoare în
afara corpului funcţiei, PHP va trata variabila respectivă ca pe una complet diferită, care nu are
legătură cu ceea ce este declarat în corpul funcţiei.

Variabilele locale se folosesc pentru eliminarea eventualelor efecte secundare reprezentate


printre altele şi modificări întâmplătoare sau intenţionate ale variabilelor accesibile global.

În următoarea ilustraţie, putem vedea o variabilă definită în cadrul funcţiei php şi una definită în
afara ei:
3.1 - Variabile cu acelaşi nume, definite în afara şi în cadrul funcţiei

Aceste variabile nu se vor influenţa una pe cealaltă.

Dacă vreţi să demonstraţi acest lucru într-un exemplu, puteţi scrie următorul cod (unele elemente
ale exemplului încă nu sunt explicate în această parte a cursului, dar sunt necesare pentru ca
exemplul să fie complet):

1
2 // Defines the variable with name x and the value 20
3 $x = 20;
4 //defines function f
function f(){
5 //Within a function, defines the variable x with value 10
6 $x = 10;
7 //Printing variables on the screen
8 echo $x;
}
9 //Calling function f
10f();
11//Printing variable x
12echo $x;
13

Parametrii funcţiilor – Despre funcţii vom discuta în detaliu în continuarea cursului. Acum, ne
vom ocupa doar de parametrii funcţiei, respectiv de argumentele funcţiei. După cum se ştie deja,
fiecare funcţie care acceptă nişte parametri (de exemplu, de la intrare) trebuie să aibă anumite
argumente în antetul său (de fapt, aceste argumente sunt parametri). Este important de menţionat
că argumentele obţin valori în afara corpului funcţiei căreia îi aparţin şi acestea nu pot fi accesate
după finalizarea executării funcţiei. Aceste tipuri de variabile (parametrii funcţiei) se declară
după introducerea denumirii funcţiei între paranteze.

Exemplu:

1//Function f is defined
2function f($x)
3{
4//Variable x increases by 5
5$x = $x + 5;
}
6

Pentru ca această funcţie să fie iniţiată, va trebui să scriem:


1f(10);

Respectiv, am putea scrie:

1//Variable x is defined with the value 10


2$x = 10;
3//Calling function f i with argument x
4f($x);
5//Value of variable x shows on display
echo $x;
6

Dacă am porni codul precedent (în combinaţie cu funcţia definită înainte), la ieşire ar fi afişată
cifra 10. Fiindcă variabila este introdusă în funcţie ca parametru, aceasta este tratată în interiorul
ei şi nu influenţează funcţia externă.

Variabile globale – Putem spune că variabilele globale sunt opusul variabilelor locale pe care le-
am explicat. Variabilele globale pot fi accesate din orice parte a programului. Pentru a avea
posibilitatea să modificăm o variabilă, aceasta trebuie declarată explicit ca şi globală în cadrul
funcţiei în care vrem să facem modificarea. Setarea variabilei globale trebuie menţionată cu
ajutorul cuvântului-cheie global în faţa variabilei dorite.

Exemplu:

1
2 $my_variable = 10;
3
4 //Function without arguments
function f()
5 {
6 //Variable my_variable is global
7 global $my_variable;
8 //Variable my_variable increases by 1
9 $my_variable++;
}
10f();
11//Result shows on display
12echo "Result is " . $my_variable;
13

După execuţia funcţiei, rezultatul este 11, însă, dacă am omite definirea variabilei drept globală
(global $my_variable), variabila $my_variable ar avea o valoare nedefinită după execuţia
funcţiei, deoarece în acest caz este tratată ca variabilă locală.

Al doilea mod de utilizare a variabilelor globale este prin declararea variabilei sub formă de
câmp $GLOBALS. Acum, vom modifica exemplul precedent astfel încât variabila $my_variable
să fie globală cu ajutorul şirului $GLOBALS:

$my_variable=10;
1function f() {
2 $GLOBALS["my_variable"]++;
3 }
f();
4echo "Result is ". $my_variable;
5
6

După executarea acestui cod, pe pagină obţinem următoarea reprezentare:

Result is 11

deoarece în funcţie nu am creat o nouă variabilă, ci am accesat-o pe cea globală, folosind şirul
$GLOBALS.

Variabile statice – spre deosebire de variabilele pe care le-am menţionat în cadrul domeniului
parametrilor funcţiilor, variabilele statice nu sunt distruse după realizarea calculelor care se fac în
funcţie. Variabila statică nu-şi pierde valoarea după execuţia funcţiei, ci valoarea variabilei
rămâne şi la următorul apel al aceleiaşi funcţii.

Variabilele statice se utilizează, de obicei, pentru crearea funcţiilor recursive. Cu alte cuvinte,
funcţiile recursive sunt acele funcţii care se apelează singure până când este îndeplinită condiţia
corespunzătoare care se stabileşte în avans.

Utilizarea variabilelor statice

Când vrem ca variabila locală să-şi menţină propria valoare între apelurile funcţiei, trebuie să o
declarăm statică, respectiv să o declarăm cu ajutorul cuvântului rezervat static, de exemplu:

static $a = 1;

Exemplu fără utilizarea variabilei statice:

1
2<?php
function incrementFunc(){
3 $x = 10;
4 echo ++$x . "<br>";
5}
6incrementFunc();
7incrementFunc();
incrementFunc();
8?>
9

Pentru că în urma fiecărei apelări a funcţiei a fost creată o nouă variabilă locală $x, care nu este
statică, astfel şi valoarea sa iniţială va fi întotdeauna 10. De aceea, pe ecran va fi afişat următorul
rezultat:
11
11
11

Iată un exemplu în care este folosită variabila statică:

1
2<?php
function incrementFunc(){
3 static $x = 10;
4 echo ++$x . "<br>";
5}
6incrementFunc();
incrementFunc();
7incrementFunc();
8?>
9

Rezultatul obţinut pe ecran este:

11
12
13

Variabilele statice sunt strâns legate de utilizarea claselor (conceptul orientat pe obiect).

Variabile superglobale
PHP-ul oferă posibilitatea de utilizare a unui număr mare de variabile predefinite, care se
accesează în interiorul scriptului care se execută, dar care vă pot oferi posibilitatea de a avea o
imagine asupra informaţiilor suplimentare legate de mediu. Informaţiile de acest tip pot fi, de
exemplu, informaţii despre client, software-ul de server etc. Încercaţi să executaţi codul din
următorul exemplu şi să analizaţi scrierea obţinută, pentru a observa informaţiile returnate
de către server:

Exemplu:

1foreach ($_SERVER as $var => $value)


2 echo $var . ":" . $value . '<br />';

Prin executarea codului, veţi obţine un număr mare de informaţii care probabil nu vor însemna
mare lucru pentru dvs., însă, dacă aveţi nevoie de o informaţie specifică, de exemplu adresa IP a
calculatorului dvs., o puteţi prelua de aici:

1printf(Your IP address is: %s ', $_SERVER['REMOTE_ADDR'] );


Constante

În ceea ce priveşte valorile definite de utilizator, pe lângă variabile mai există un tip a cărui
valoare odată iniţializată rămâne fixă. Aceste tipuri se numesc constante. Utilizăm constantele
atunci când ştim sigur că valoarea iniţializată nu se va schimba pe parcursul executării
programului. O altă caracteristică a constantelor (pe lângă regulile tipice pentru variabile) este că
acestea nu trebuie să conţină semnul $ în faţa denumirii variabilei. Cel mai bun exemplu de
valoare a unei constante este 3.14 (respectiv PI).

Constantele se creează prin comanda define ("numele constantei", valoarea). De exemplu:

1define("CURRENCY", 80.2);
2define("UNIVERSITY", "ITS");
3define("PI", 3.14);

Conform convenţiei, constantele primesc denumiri scrise cu litere majuscule, dar aceasta nu este
o regulă. PHP acceptă şi litere minuscule în denumirea constantei. Atunci când denumim
constantele, trebuie să avem grijă să nu folosim cuvintele-cheie PHP.

PHP are multe constante încorporate, pe care le puteţi utiliza în codul dvs. Unele dintre acestea
sunt:

__LINE__ - numărul liniei pe care este apelată constanta;


__FILE__ - numele fişierului în care este apelată constanta.

La iniţializare, trebuie să reţinem că constanta poate accepta numai date de tip scalar.

Declararea variabilelor

În alte limbaje de programare, este necesar ca variabila să fie declarată înainte de a-i fi atribuită
valoarea. În PHP, este suficient doar să i se atribuie valoare variabilei. Înainte de depozitarea
valorii în memorie, PHP determină singur tipul de valoare şi o înregistrează în formatul
corespunzător. Dacă trebuie, PHP converteşte automat un tip de date în altul. De exemplu:

1$first_number = 1; // like integer


$second_number = 1.1; // like float
2$sum = $first_number + $second_number;<span style="font-size: 14px; text-
3align: justify;"> </span>

În a treia comandă, se adună două valori diferite. Înainte de adunare, PHP converteşte valoarea
de tip număr întreg într-unul real, pentru ca adunarea să fie posibilă.

Pentru atribuirea sau schimbarea valorii unei variabile, folosim operatori.


Greşeli în timpul folosirii operatorilor = şi ==

Dacă trebuie să comparaţi o anumită valoare cu o variabilă, trebuie să fiţi atenţi să nu atribuiţi
valoarea variabilei cu care faceţi comparaţia. Deşi vi se poate părea confuz, iată explicaţia care
vă va împiedica să faceţi cea mai frecventă greşeală a începătorilor.

Codul dvs. trebuie să arate astfel:

if($my_variable==10)
{ ... }

În niciun caz astfel:

if($my_variable=10)
{ ... }

De comanda if ne vom ocupa în detaliu în lecţiile care urmează, aşadar explicaţia acestui
exemplu va fi suficientă dacă spunem că prin comanda if verificăm dacă este îndeplinită o
anumită condiţie (în cazul nostru, dacă variabila $my_variable are valoarea 10). Dacă este
îndeplinită condiţia, atunci blocul de cod specificat între paranteze acolade va fi executat. Pe de
altă parte, dacă condiţia nu este îndeplinită, acest bloc de cod va fi omis. Tocmai o astfel de
verificare se execută cu operatorul ==. Dacă vrem să atribuim o valoare variabilei $my_variable,
vom folosi operatorul de atribuire =. Scopul acestei părţi din lecţie este explicarea diferenţei
dintre cei doi operatori.

Atribuirea valorilor implicite variabilelor

Alocarea valorilor implicite variabilelor o putem face în mai multe feluri. În primul rând, vom
folosi funcţia isset() în felul următor:

1// Checking existence of variable


2if (!isset ($cars)){
3// If the variable does not exist, it will be created
4$cars = $default_cars;
5}

Când vrem să adăugăm o valoare implicită unei variabile care înainte nu avea atribuită o altă
valoare, putem folosi şi operatorul ternar (a ? b : c) în felul următor (despre operatorul ternar
vom mai discuta în următoarele lecţii):

1$cars = isset($_REQUEST['cars'])? $_REQUEST['cars']:$default_cars;

Dacă $_REQUEST['cars'] nu există, variabilei îi va fi atribuită valoarea $default_cars. În caz


contrar, valoarea variabilei $cars va fi atribuită din variabila superglobală $_REQUEST['cars'].

Funcţia isset() verifică:


existenţa unei variabile
dacă o variabilă are o valoare de tip număr întreg
dacă o variabilă este string
dacă utilizatorul este logat

Problema nr. 1

În aplicaţia existentă, există un set de variabile conectate la baza de date creat în felul următor:

1<?php
2 $s = "localhost";
3 $k = "root";
4 $s = "";
5 $b = "myDB";
?>
6

Trebuie modificate variabilele pentru a fi mai intuitive.

Rezolvare:

Aceste variabile nu au denumiri intuitive şi este foarte posibil să coincidă cu alte variabile în
cadrul aplicaţiei. Denumiri mai bune ar fi, de exemplu:

1<?php
2 $dbServer = "localhost";
3 $dbUtilizator = "root";
4 $dbParola = "";
5 $dbBaza = "myDB";
?>
6

Problema nr. 2

Nu funcţionează o aplicaţie simplă care adună două numere şi emite rezultatul la ieşire. Trebuie
corectată eroarea:

1<?php
2 $x = 10;
3 $y = 20;
4 echo $x+$Y;
5?>
Rezolvare

PHP este sensibil la litere mari şi mici, iar în ultima linie a aplicaţiei, în loc de $y se află $Y,
ceea ce cauzează o eroare, deoarece variabila $Y nu există:

1<?php
2 $x = 10;
3 $y = 20;
4 echo $x+$y;
5?>

Problema nr. 3

Trebuie realizat un set de constante, care vor fi utilizate pentru manipularea bazei de date. În
acest moment, există variabilele:

1<?php
2 $dbServer = "localhost";
3 $dbUtilizator = "root";
4 $dbParola = "myPass";
5 $dbBaza = "myDB";
?><br><br>
6

Rezolvare:

<?php define("DB_SERVER","localhost"); define("DB_UTILIZATOR","root");


define("DB_PAROLA","myPass"); define("DB_BAZA","myDB"); ?>

Crearea constantei se face cu ajutorul funcţiei define(). Această funcţie creează implicit
constantele case-sensitive (sensibile la majuscule și minuscule). Primul parametru al funcţiei este
numele constantei, în timp ce al doilea este valoarea ei. Se poate seta şi al treilea parametru
opţional, cu care s-ar putea stabili dacă numele constantei nu este sensibil la majuscule și
minuscule (case-insensitive).

…………………….

Operatorii
Principalul subiect al acestei lecţii va fi reprezentat de operatorii în PHP. Pentru a crea un
program, mai mult sau mai puţin funcţional în orice limbaj, pe lângă variabile, mai avem nevoie
şi de operatori. Aceştia se clasifică în: operatori de atribuire, operatori aritmetici, operatori de
comparaţie şi operatori logici. Mai există și câteva categorii de operatori (operatori string,
operatori de incrementare şi decrementare, operatori array), dar aceştia, după cum veţi vedea în
continuare, se bazează, în general, pe cele patru tipuri de operatori menţionaţi anterior.

Operatorii de atribuire subînţeleg atribuirea unei valorii pentru o anumită variabilă:

1$a=10;
2$x='Hello world!';
3$z=3;

Este clar că principalul operator de atribuire este semnul =

Totuşi, există şi anumite combinaţii de semne care au, de asemenea, posibilitate de atribuire,
dar despre ele se poate spune mai degrabă că sunt abrevieri decât operatori (despre ele vom
discuta mai târziu):

$x+=5; //is same like $x=$x+5;


$x-=1; //is same like $x=$x-1;

Atribuirea implicită a valorilor pentru variabile este prin valoare. Aceasta înseamnă că, în
momentul în care o valoare este atribuită unei anumite variabile, această valoare va fi, de fapt,
cuprinsă în variabila respectivă:

Când scriem următoarele:

1$x=3;

programul nostru ocupă o porţiune mică din memoria calculatorului, iar în această porţiune pune
numărul 3. De asemenea, ne-a informat că această porţiune mică de memorie va răspunde la
„numele” x.

Aceasta înseamnă că, dacă scriem:

1$x=3;
2$y=$x;
3$x=5;

variabila $y va avea valoarea 3, după ce toate liniile vor fi executate.

Acest lucru este foarte logic. Am creat variabila x, i-am atribuit valoarea 3, apoi am creat
variabila y şi i-am acordat valoarea variabilei x (3), iar apoi am schimbat valoarea variabilei x în
5, dar valoarea variabilei y continuă să fie 3, deoarece în linia $y=$x; valoarea atribuită a fost
deja executată:
4.1 - Starea în memorie în timpul atribuirii variabilelor

Acum, să analizăm un alt exemplu. De fapt, este vorba despre acelaşi exemplu, dar cu semnul &
adăugat pe al doilea rând. În programare, acest semn reprezintă o adresă de memorie.

1$x=3;
2$y=&$x;
3$x=5;

După executarea acestui cod, valoarea variabilei y va fi 5, situaţie pe care o vom explica imediat.
Mai devreme, am descris procesul de atribuire prin valoare, când valoarea a fost localizată direct
în memorie, dar în cazul atribuirii prin referinţă (din al doilea exemplu), în memorie se stochează
doar adresa.

Aceasta înseamnă că, dacă scriem următorul lucru:

$y=&$x;

programul nostru va lua din nou o porţiune mică de memorie, dar de data aceasta nu stochează în
ea numărul 3, ci numărul care reprezintă adresa de memorie a variabilei x:
4.2 - Starea în memorie după atribuirea referinţei

Dacă acest lucru sună destul de complicat, gândiţi-vă la redirecţionarea apelurilor de pe telefonul
dvs. Funcționează în același fel.

Nu trebuie să vă preocupaţi foarte mult de atribuirea prin referinţă. În PHP, o veţi folosi foarte
rar din proprie iniţiativă. Pe lângă faptul că este mai complicată, această abordare în PHP este
mai lentă decât atribuirea prin valoare (ţineţi minte că PHP este unul dintre puţinele limbaje în
care expedierea prin referinţă este mai lentă decât expedierea prin valoare).

Pe de altă parte, sunt anumite situaţii când veţi atribui valori prin referinţă fără să vă daţi seama.
De exemplu, atunci când utilizaţi obiecte sau şiruri, acestea pot funcţiona numai astfel.

Crearea variabilelor dinamice

Uneori, de exemplu, când lucraţi cu baza de date şi doriţi ca variabilele dvs. să aibă aceleaşi
nume precum câmpurile din baza de date sau, pur şi simplu, când nu ştiţi cum se numeşte o
variabilă înainte să o folosiţi, folosiţi variabile dinamice. În PHP, variabilele dinamice se creează
prin punerea în faţa numelui variabilei, a cărei valoare este la fel ca numele variabilei, a
prefixului $.

Într-un exemplu concret, aceasta arată astfel:

1<?php
2$car = 'opel';
3$opel = 23;
print $$car;
4?>
5

După pornire va fi scrisă cifra 23, deoarece doar variabila $opel a fost apelată dinamic.

Ce se întâmplă în PHP în momentul specificării dinamice? Când prefixul este $$, PHP specifică
faptul că ia valoarea din partea dreaptă şi că acest nume îl foloseşte ca nume al adevăratei
variabile. Acest lucru este, de fapt, foarte logic, deoarece, dacă avem o variabilă care se numeşte
$car, dar şi un string a cărui valoare este „opel”, trebuie să le unim pe cele două într-un anumit
mod şi să scriem ceva de genul $"opel", lucru pe care îl obţinem, de fapt, cu variabilele
dinamice.

Operatorii aritmetici

Fiecare operaţie aritmetică necesită un operator aritmetic (+, -, *, /, %). Semnele pentru adunare
şi scădere sunt clare, în timp ce ceilalţi trei operatori sunt: * pentru înmulţire, / pentru împărţire
şi % pentru rest.

Operatorul pentru rest reprezintă un număr întreg care este restul împărţirii a două numere:

10%3 dă valoarea 1 (ca rezultat)


10%4 dă valoarea 2

Atunci când efectuăm operaţii aritmetice, trebuie să fim atenţi la ordinea de executare a
acestora. În PHP, operaţiile matematice urmează aceeaşi ordine de executare ca în matematică.
Înmulţirea şi împărţirea au prioritate în faţa adunării şi scăderii. Ordinea de executare
a operaţiilor se poate schimba prin utilizarea parantezelor.

Atunci când încercaţi să aplicaţi unul dintre aceşti operatori asupra variabilelor, rezultatul
operaţiei va depinde de tipul de dată stocată în variabile. De exemplu, după executarea
următoarelor comenzi:

1$number1 = 1;
2$number2 = 2;
3$result = $number1 + $number2;

variabila result va conţine valoarea 3. Variabilele $number1 şi $number2 sunt definite ca


variabile numerice, prin urmare rezultatul adunării lor este suma numerelor conţinute. Totuşi,
situaţia se schimbă dacă creaţi una dintre variabile ca variabilă de tip string. De exemplu, după
executarea comenzii:

$number1 = "1";
1$number2 = 2;
2$result = $number1 + $number2;
3

variabila $number1 este creată ca variabilă de tip string. Înaintea adunării, PHP va converti în
mod automat valoarea textuală în număr. În acest caz, valoarea "1" va fi convertită în numărul 1,
iar rezultatul adunării va fi 3, ca în cazul precedent. Însă, în următoarele comenzi:

1$number1 = "x";
2$number2 = 2;
3$result = $number1 + $number2;

având în vedere că valoarea primei variabile nu este număr, PHP va converti variabila $number1
în numărul 0, astfel că valoarea variabilei $result va fi 2. În majoritatea cazurilor, PHP va
converti valoarea de tip string într-un număr necorespunzător. Priviţi următorul exemplu:

1$number1 = "2,000";
2$number2 = 2;
3$result = $number1 + $number2;

Valoarea primei variabile ar trebui să fie 2000 sau cel puţin aşa o înţeleg oamenii, dar PHP
înţelege virgula ca fiind sfârşitul numărului, aşadar variabila $number1 va fi convertită în
numărul 2, iar rezultatul adunării va fi numărul 4. De aceea, nu trebuie să ne bazăm pe conversia
automată, ci trebuie să avem grijă ca fiecare variabilă să aibă atribuită valoarea corectă atunci
când este creată, pentru a putea fi supusă oricărei operaţii.

Notă:

Începând cu versiunea PHP 5.6, este inclus încă un operator aritmetic. Este vorba de
operatorul pentru expresia exponenţială (numit şi operator exponenţial), respectiv operatorul
de putere. Puterea este o operaţie matematică binară, care se scrie ca: ab unde a reprezintă
baza, iar b este exponentul.

Semnul pentru acest operator este: **

Aplicare: În partea stângă a operatorului se introduce baza, iar în partea dreaptă se introduce
exponentul.

Exemplu:

$x = 10 ** 2;

Această operaţie ar fi dat acelaşi rezultat ca şi 10 * 10, respectiv 100.

Trebuie avut în vedere că acest operator nu va fi disponibil dacă se foloseşte WampServer,


care suportă o versiune de PHP mai veche decât versiunea 5.6.
Pe lângă operatorii matematici de bază, PHP oferă şi operatori de incrementare şi decrementare
(de mărire şi micşorare a valorilor):

Operator Utilizare Semnificaţie


++ $număr++; $număr=$număr+1;
-- $număr--; $număr=$număr-1;
+= $număr+=2; $număr=$număr+2;
-= $număr-=2; $număr=$număr-2;
*= $număr*=2; $număr=$număr*2;
/= $număr/=2; $număr=$număr/2;

Tabelul 4.1 - Tabelul operatorilor prescurtaţi

După cum se vede şi în tabel, unii dintre operatori sunt unari, adică necesită doar o singură
valoare pentru a funcţiona. În unele cazuri, dacă dorim să facem incrementarea prin valoare
explicită (valoarea implicită este 1), atunci vom folosi şi a doua valoare în operator.

În cazul operatorilor de incrementare şi decrementare, poziţia operatorului este foarte importantă.


Deşi următoarele două expresii sunt identice în ceea ce priveşte valoarea finală a variabilei $a:

$a++
++$a

viaţa acestei variabile pe parcursul executării operatorului nu este la fel. Acest lucru se poate
constata foarte uşor prin următorul exemplu:

1$a=1;
2$x=$a++;

După executarea liniilor de cod, variabila x va avea valoarea 1, dar dacă schimbăm a doua linie
cu:

1$x=++$a;

variabila x va avea valoarea 2.

Aşadar, este clar ce s-a întâmplat. În primul exemplu, incrementarea este executată după
atribuirea valorii, iar în al doilea, atribuirea valorii s-a desfăşurat după incrementare.

Este de prisos să vorbim despre consecinţele pe care le poate produce manipularea neatentă a
operatorilor de incrementare.
În afară de operatori, pentru lucrul cu numere se pot folosi şi funcţiile integrate ale PHP-ului,
cum ar fi: funcţia sqrt() pentru calcularea rădăcinii pătrate a unui număr, funcţia abs() pentru
calcularea valorii absolute a numărului, funcţia ceil() care rotunjeşte numărul la primul număr
întreg care este mai mare, funcţia floor() care rotunjeşte numărul la primul număr întreg care
este mai mic, funcţiile max() şi min() care calculează valoarea maximă şi valoarea minimă şi
altele. Mai ţineţi minte problemele referitoare la conversia numărului zecimal în număr întreg
(când numărul 7.999999 dădea ca rezultat numărul 7)? Astfel de probleme se rezolvă tocmai prin
funcţiile matematice.

Lista funcţiilor matematice o puteţi găsi la următoarea adresă:

http://php.net/manual/en/ref.math.php

Operatorii de concatenare a stringurilor

Nu vom acorda multă atenţie acestei părţi, din două motive. Primul motiv este că nu sunt foarte
multe de spus despre acest subiect, iar al doilea, că vom studia stringurile în detaliu într-o lecţie
următoare.

Concatenarea (unirea stringurilor) se face prin semnul de punctuaţie . (punct)

Următoarea linie:

1$name = "Link" . " Group";

va acorda variabilei name valoarea „Link Group”.

De asemenea, şi aici puteţi utiliza un anumit tip de operatori de incrementare (cu condiţia ca
name să aibă deja valoarea din exemplul precedent ("Link Group")), astfel încât după
următoarea linie valoarea variabilei name va fi “Link Group d.o.o.”.

1$name .= " d.o.o.";

şi, bineînţeles, versiunea extinsă a aceleiaşi linii:

1$name = $name . " d.o.o.";

De ce am folosi un astfel de operator?

Să vedem următoarea ilustraţie. În ea se află două părţi ale site-ului Facebook. Una este Sign Up,
formular prin intermediul căruia ne putem înregistra la Facebook, iar a doua este statusul
utilizatorului, respectiv panoul care reprezintă statusul utilizatorului logat.
Focusul este pe prenume şi nume. Vedem că în formularul Sign Up prenumele şi numele sunt
separate. Asta înseamnă că aceste date vor fi separate şi în baza de date, şi în scriptul PHP.
Acestea vor fi reprezentate prin intermediul a două variabile. De exemplu: $prenume şi
$nume. În statusul utilizatorului, aceste date sunt unite: Peter Jackson. Pentru ca datele să fie
unite, cel mai probabil autorul scriptului a folosit tocmai operatorul pentru concatenarea
stringurilor.

4.3 - Reprezentarea panoului de utilizator Facebook şi a părţii din formularul Sign Up

Operatorii de comparaţie

Acest tip de operatori compară anumite valori şi, ca rezultat, dau valori de tip Boolean.
Marcajele sunt:

 == este egal (operanzii au aceeaşi valoare, însă nu trebuie neapărat să fie de acelaşi tip);
 != nu este egal;
 < mai mic decât;
 > mai mare decât;
 >= mai mare decât sau egal cu;
 <= mai mic decât sau egal cu;
 === este identic (operanzii au aceeaşi valoare şi acelaşi tip);
 !=== valoarea nu este egală sau tipul nu este egal.

Să vedem câteva exemple:

Dacă am avea două variabile, $x şi $y, unde $x=10, iar $y=20, am putea compara valorile lor cu
ajutorul operatorului de comparaţie.
Dacă am vrea să întrebăm dacă $x este egal cu $y, am scrie:

$x==$y

Codul scris astfel va da ca rezultat tipul Boolean. În acest caz, valoarea este false, deoarece $x şi
$y nu au aceeaşi valoare.

Bineînţeles, dacă am scrie doar comparaţia a două valori, codul nu ar avea niciun sens. De aceea,
operatorii de comparaţie se folosesc cel mai des în combinaţie cu expresiile condiţionate.

De exemplu, dacă vrem să scriem mesajul "Hello!", dacă $x este egal cu $y, vom scrie:

1if($x==$y) echo "Hello!";

Dacă pornim codul scris mai devreme, nu vom obţine mesajul "Hello!", deoarece $x nu este egal
cu $y.

De aceea, am putea să schimbăm condiţia şi să scriem: dacă $x nu este egal cu $y, scrie
mesajul. Atunci am putea să folosim negaţia şi să scriem:

if($x!=$y) echo "Hello!";<span style="font-size: 14px; text-align:


justify;"> </span>

Apoi, pe baza aceluiaşi principiu am putea să folosim şi toţi ceilalţi operatori menţionaţi.

Ultimii doi operatori sunt puţin mai greu de înţeles în acest moment, motiv pentru care este bine
să îi clarificăm prin practică.

Să luăm următorul bloc:

1$x = 1;
2$y = "1";
3$z = $x == $y;

Valoarea variabilei $z după acest cod ar fi true, deoarece variabilele $x şi $y au aceeaşi valoare.

Dar, după executarea următorului cod:

1$x = 1;
2$y = "1";
3$z = $x === $y;

valoarea variabilei z va fi false, pentru că, deşi variabilele $x şi $y au aceeaşi valoare, tipurile lor
diferă.

Operatorii logici
Operatorii logici se folosesc pentru operaţii de algebră logice. Cel mai des se pot întâlni în
combinaţie cu operatorii de comparaţie, unde se folosesc pentru executarea comparaţiilor
complexe cu mai multe variabile. Operatorii logicii returnează ca rezultat o valoare Boolean.

Aceşti operatori leagă mai multe expresii dacă este îndeplinită o anumită condiţie şi, de
asemenea, dau o valoare de tip Boolean:

 prima expresie && a doua expresie – dacă ambele expresii sunt corecte, rezultatul
este true (adevărat);
 prima expresie || a doua expresie – dacă prima sau a doua expresie este corectă,
rezultatul este true (adevărat);
 semnul negaţiei ! valoare sau expresie - converteşte operandul în valoare Boolean
şi apoi execută negaţia acestuia.

Conjuncţia logică (&&)

Operatorul && (logic AND) execută o conjuncţie logică pentru doi operanzi. Aceasta înseamnă
că valoarea returnată va fi true numai dacă ambii operanzi au valoarea true. Totuşi, mai trebuie
menţionat că este suficient ca un singur operand să aibă valoarea false ca rezultatul să fie false.

Exemple generale:

$a1 = true && true; //Variabila a1 obţine valoarea true


$a2 = true && false; //Variabila a2 obţine valoarea false
$a3 = false && true; //Variabila a3 obţine valoarea false
$a4 = false && false; //Variabila a4 obţine valoarea false

În loc de valori logice, putem folosi şi expresii:

1$a1 = (3 > 0) && (3 < 5); // Variable a1 gets value true

De exemplu, dacă am fi dorit să verificăm dacă un utilizator are peste 13 ani şi mai puţin de 25
de ani, am fi scris:

1$user_age = 20;
2if($user_age>13 && $user_age<25)
3 echo "User is younger than 25 and older than 13 years";

În acest caz, textul: "User is younger than 25 and older than 13 years" s-ar fi scris pe pagină.
Pentru o verificare, trebuie să schimbaţi valoarea variabilei user_age şi să mai verificaţi şi
comportamentul programului.

Disjuncţia logică (||)


Operatorul || (logic OR) execută disjuncţia logică pentru doi operanzi. Ca şi operatorul precedent
(&&), şi operatorul || este binar, ceea ce înseamnă că manipulează doi operanzi. Returnează
valoarea logică true, dacă cel puţin unul dintre operanzi returnează true:

$o1 = true || true; // Variabila o1 obţine valoarea true


$o2 = false || true; // Variabila o2 obţine valoarea true
$o3 = true || false; // Variabila o3 obţine valoarea true
$o4 = false || false; // Variabila o4 obţine valoarea false

Am putea să verificăm dacă utilizatorul are 13 sau 25 de ani, însă în acest caz ar trebui să folosim
operatorul logic OR/SAU (||):

1$user_age = 13;
2if($user_age==13 || $user_age==25)
3 echo "User is 13 or 25 years old";

De asemenea, putem să şi combinăm aceşti operatori:

1$user_age = 13;
2$user_gender = "male";
3if(($user_age == 13 || $user_age == 25) && ($user_gender == "male")){
4 echo "Valid user";
}
5

Negaţia logică (!)

Spre dosebire de cei doi operatori menţionaţi mai devreme, acest operator nu este binar, ci unar.
Deci, pentru operaţiile sale nu foloseşte doi, ci un singur operand. Operandul poate fi o valoare
logică sau o expresie. Scopul acestui operator este inversarea operandului logic lângă care se
află:

$n1 = !true; // Variabila n1 obţine valoarea false


$n2 = !false; // Valoarea n2 obţine valoarea true

Mai multe informaţii interesante: Dacă operatorul ! este introdus lângă un operand care nu este
o valoare logică, operatorul va converti mai întâi operandul în valoarea logică corespunzătoare,
iar apoi va executa negaţia valorii respective. Aceasta ne indică faptul că o valoare care nu e
logică se poate converti într-una logică prin executarea asupra acesteia a unei negaţii dublă (!!x).
De exemplu:

1$x = 10;
2$x = !!$x;

Acum, variabila x a devenit o valoare Boolean care este true:


Operator Denumire Exemplu Rezultat
and And $x and $y Este true dacă şi variabila $x, şi variabila $y sunt true.
or Or $x or $y Este true dacă cel puţin o variabilă este true.
xor Xor $x xor $y Este true dacă una sau cealaltă variabilă este true, dar
nu şi dacă ambele sunt true.
&& And $x && $y Este true dacă şi variabila $x, şi variabila $y sunt true.
|| Or $x || $y Este true dacă cel puţin o variabilă este true.
! Not !$x Este true dacă $x este false sau este false dacă
variabila $x este true.

Tabelul 4.2

Este bine să ştiţi că PHP întotdeauna încearcă să trateze optim orice comparaţie. De exemplu,
dacă scriem următoarele:

if($a==10 || $b==20)...

variabila $a are valoarea 10, iar comparaţiile nu vor fi executate (deoarece nu este necesar).

Pe de altă parte, dacă în următorul cod:

if($a==10 && $b==20)...

variabila $a nu are valoarea 10, verificarea va fi întreruptă momentan, deoarece condiţia nu poate
fi îndeplinită.

Operatorii la nivel de bit (operaţii cu biţi)

Fiindcă cea mai mică unitate care poate fi manipulată în PHP este byte-ul, PHP permite ca
anumiţi operatori să poată fi manipulaţi prin valori la nivel de bit.

Aceştia sunt operatorii shift şi operatorii OR, AND şi XOR.

Operatorii shift (<< şi >>) permit mutarea biţilor în stânga sau în dreapta, în interiorul unui
byte. De exemplu:

1$a=10;
2$b=$a<<1;

Valoarea variabilei $a este 10. În scrierea binară, aceasta va fi numărul: 1010. Când valoarea
$a<<1 este atribuită variabilei $b, toţi biţii din variabila $a sunt mutaţi cu un loc spre stânga, iar
această valoare nouă este atribuită variabilei $b. Acum, această valoare este 10100 (sau dacă vă
este mai simplu: 00010100 sau 0000000000010100).

Valoarea variabilei $b va fi acum 10100 sau 20.


Dacă doriţi să vedeţi reprezentarea binară a numărului, este bine să utilizaţi funcţia printf şi să
formataţi ieşirea binară a valorii:

1printf("%b",$b);

Operatorul binar NOT (complement) (~) este operatorul care inversează conţinutul de biţi al
variabilei curente.

Dacă valoarea binară a variabilei a fost 1010, acum aceasta va fi 0101. Respectiv,
11111111111111111111111111110101, ceea ce puteţi încerca prin următorul exemplu:

1$a=10;
2printf("%b",~$a);

Operatorul binar AND (&) dă o valoare nouă ca rezultat. Această valoare se obţine prin
compararea biţilor care se află pe aceeaşi poziţie în ambii operanzi. Dacă cei doi biţi
comparaţi au valori diferite sau valoarea 0, rezultatul va fi 0. Numai dacă cei doi biţi au valoarea
1, rezultatul va fi 1.

De exemplu:

0101 &
1011 este
0001

Operatorul binar OR (|) oferă, de asemenea, o valoare nouă ca rezultat. Dar, în acest caz,
această valoare este alcătuită din toţi biţii, unde măcar una dintre valorile comparate are valoarea
1.

De exemplu:

0101 |
1011 este
1111

Operatorul binar XOR (eXclusive OR) (^). Acest operator ia în considerare numai biţii în care
oricare dintre cele două variabile are valoarea 1, dar nu şi dacă ambele variabile au această
valoare.

1010 ^
1000 este
0010

Operatorul error suppression (supresorul erorilor)


Acesta este un operator simplu, care împiedică emiterea erorii cauzate de comanda pe care o
precede. Încercaţi să executaţi în codul dvs. următoarea comandă (cu condiţia ca într-adevăr să
nu aveţi fişierul "abcd" în folderul în care se află fişierul PHP):

include "abcd";

Dacă încercaţi să executaţi această comandă, PHP va semnala o eroare, dar, dacă
adăugaţi operatorul @ la această comandă:

@include "abcd";

eroarea nu va fi emisă.

Cât de eficient este acest lucru depinde de situaţia în care vă aflaţi. Uneori, dacă eroarea nu
este emisă, acest lucru are o semnificaţie aparte, dar uneori poate şi să cauzeze dificultăţi.

Operatorul Backtick (ghilimele înclinate)

Permite executarea unei comenzi de sistem şi emiterea ieşirii ei într-o variabilă:

echo `dir`;

Dacă încercaţi să executaţi acest exemplu, pe pagină va fi emis conţinutul folderului care conţine
aplicaţia dvs. PHP.

După cum am menţionat deja într-una din lecţiile anterioare, la sfârşitul anul 2015 se aşteaptă
lansarea noii versiuni de PHP, cu marcajul PHP7. Tocmai această versiune de PHP aduce şi doi
operatori noi. Este vorba de operatorul spaceship (sau operatorul comparaţiei combinate) şi
operatorul null coalesce.

Operatorul spaceship

Semnul pentru acest operator este următorul:

<=>

Este vorba de un operator care foloseşte doi operanzi şi se foloseşte pentru comparaţia acestora
doi. Dacă am fi vrut să comparăm variabilele $a şi $b cu operatorul, am fi scris următoarele:

$a <=> $b

Pentru ca exemplul să fie mai evident, scriem următoarele:


1$a = 5;
2$b = 10;
3$z = $a <=> $b;

În acest caz, valoarea variabilei $z ar fi -1. Spaceship returnează valoarea -1, în caz că primul
operand este mai mic decât al doilea operand. În caz că ambii operanzi au aceeaşi valoare,
rezultatul returnat va fi 0. La final, dacă primul operand ar fi fost mai mare decât al doilea
operand, ca rezultat s-ar fi returnat numărul 1.

Mai multe informaţii interesante

Operatorul Spaceship reprezintă, de fapt, o formă prescurtată a următoarei expresii:

($a < $b) ? -1 : (($a > $b) ? 1 : 0)

Deoarece pentru înţelegerea acestei expresii trebuie să cunoaşteţi operatorul ternar despre
care vom vorbi mai târziu, aici vom da doar o scurtă explicaţie. Exemplul dat reprezintă un
cod care se poate scrie în versiunile de PHP înainte de versiunea 7 şi în care va funcţiona
perfect. În primul rând, acest cod verifică dacă primul operand este mai mic decât al doilea
şi, dacă este mai mic, atunci returnează valoarea -1 (ceea ce şi face operatorul spaceship).
Dacă nu acesta este cazul, se trece la partea alternativă a codului, în care se verifică dacă
primul operand este mai mare. Dacă este îndeplinită această condiţie, se va returna valoarea
1. Dacă nici această condiţie nu este îndeplinită, este clar că operanzii sunt egali, aşadar ca
rezultat va fi returnat numărul 0.

Operatorul null coalesce

Semnul pentru operatorul null coalesce este următorul:

??

Scopul acestui operator este să verifice dacă variabila posedă o valoare utilă, iar pe baza acestui
test atribuie variabilei noastre respectiva valoare utilă sau o altă valoarea subînţeleasă.

Pentru a vă explica cât mai bine acest operator, imaginaţi-vă următoarea situaţie: dorim să
atribuim variabilei $a valoarea pe care o are variabila $b, dar nu suntem siguri dacă există
variabila $b. În caz că există, vrem valoarea ei, iar în caz că nu există această variabilă, vrem ca
variabila noastră $a să obţină o valoare implicită, de exemplu 10.

Utilizând operatorul coalesce, am putea să scriem următoarele:

1$a = $b ?? 10;
Mai multe informaţii interesante

Şi acest operator, la fel ca şi spaceship, despre care am vorbit, reprezintă, de fapt, o sintaxă
prescurtată care exista şi în trecut. De fapt, funcţia acestui operator am putea să o exectăm şi
în mod tradiţional, dacă scriem următoarele:

$a = isset($b) ? $b : 10;

Şi aici putem vedea utilizarea operatorului ternar despre care vom vorbi mai târziu.

Formatarea diferitelor tipuri de reprezentări numerice

Deseori, este necesar să reprezentăm anumite valori numerice într-un anumit format. De
exemplu, dacă aceste valori numerice reprezintă sume de bani, atunci este necesar să fie
reprezentate cu două spaţii zecimale, iar miile să fie despărţite prin virgulă.

Pentru a reprezenta un număr într-un anumit format, utilizaţi funcţia:

number_format(număr,numărZecimal,"separatorZeci","separatorMii")

Argumentele acestei funcţii sunt în ordinea următoare:

 număr - numărul care se formatează. Acest argument este obligatoriu;


 numărZecimal - numărul din spaţiile zecimale. Dacă acesta este omis, se subînţelege că
numărul din spaţiile zecimale este 0. Trebuie neapărat să fie specificat dacă se folosesc
argumentele separatorZeci şi separatorMii;
 separatorZeci - caracter folosit pentru separarea părţii zecimale a numărului.
Separatorul implicit este punctul;
 separatorMii - caracter folosit pentru separarea miilor. Separatorul implicit este virgula.

După formatare, numărul se converteşte în string. De aceea, este necesar să executăm toate
operaţiile aritmetice asupra numărului, înainte ca acesta să fie formatat.

Pentru formatările mai complicate ale numerelor, se pot utiliza funcţiile printf() şi sprintf().
Funcţia printf() doar prezintă numărul într-un anumit format. Funcţia sprintf() formatează
numărul şi îl stochează într-o variabilă. Aceste funcţii se folosesc şi pentru formatarea valorilor
string.

Exemple

Să creăm un program care adună două numere:

Exemplul 1
1
2 <?php
3 // the addition of two numbers
4
//assigning a value to a variable x
5 $x=1;
6 // assigning a value to a variable y
7 $y=2;
8 // assigning a value to a variable z
9 $z=$x+$y;
//printing result
10echo $z;
11?>
12

Rezultatul din browser ar trebui să fie numărul 3. Comentariile explică clar ce se întâmplă în
acest exemplu.

Nu trebuie să uităm că convenţiile limbajului PHP sunt valabile numai în interiorul tagului PHP.
De aceea, nu trebuie să încercăm executarea comenzii sau scrierea comentariilor în partea care se
află în afara acestor taguri.

Exemplul 2

În acest exemplu, vom calcula aria cercului.

Ştim că pentru aceasta avem nevoie de variabila r. De asemenea, pentru calcul, vom avea nevoie
şi de numărul PI. Fiindcă este vorba de o valoare fixă, putem utiliza constanta.

1
2 <?php
// calculating the area of a circle
3 // defining constants PI
4 define("PI", 3.14);
5 // defining variable r
6 $r=10;
7 //calculating p
$p = ($r*$r)*PI;
8 echo $p;
9 ?>
10

Acest program, deşi scurt, conţine câteva lucruri foarte interesante, în primul rând definirea
constantei. Procedura este destul de clară, funcţia define acceptă doi parametri (numele
constantei şi valoarea constantei). În acest mod, obţinem definiţia constantei:

define("PI", 3.14);
În loc de PI, puteam utiliza orice alt nume (din cadrul convenţiilor referitoare la numele
variabilelor). Pentru definirea constantei, nu suntem limitaţi numai la valori numerice. Constanta
poate purta orice tip de dată.

1define("nameSurname", "Peter Andersen"); // string


2define("age", 1980); //integer
3define("male", true); //boolean

În continuarea programului, după iniţializarea variabilei r, observăm că la iniţializarea variabilei


p o parte a expresiei este separată prin paranteze, iar constanta PI nu are semnul $ în faţa
numelui. Acest lucru este normal, deoarece constantele nu trebuie să aibă marcajul $ în faţa
numelui, în timp ce parantezele se folosesc pentru separarea logică a unităţilor pe
parcursul operaţiei aritmetice. De exemplu, următoarele două linii de cod nu vor produce
aceleaşi rezultate:

1echo 2-(3*3);
2echo (2-3)*3;

La final, în ultima linie, programul pur şi simplu emite rezultatul la ieşire.

Trebuie menţionat că în acest program rădăcina pătrată nu trebuie calculată manual, ci putem
utiliza o funcţie care serveşte acestui scop, din colecţia funcţiilor pentru lucrul cu operaţiile
matematice:

1pow($r,2);

unde primul număr este valoarea de intrare, iar al doilea este exponentul.

Rolul operatorului Error suppression este:


împiedicarea emiterii erorii cauzate de comanda pe care o precede
permiterea emiterii erorii cauzate de comanda pe care o precede
afişarea mesajului de eroare atunci când se pune după comanda echo

Exerciţiul nr. 1

Trebuie să se refacă următoarea aplicaţie, altfel încât rezultatul să fie un număr alcătuit din două
zecimale:

1<?php
2$price = 527.356;
$discount = 15;
3$pricewithdiscount = $price - (($discount/100)*$price);
4echo $pricewithdiscount;
5?>
6

Rezultatul curent al aplicaţiei este:

448.2526

Rezolvare:

1<?php
2$price = 527.356;
3$discount = 15;
4$pricewithdiscount = $price - (($discount/100)*$price);
5echo number_format($pricewithdiscount,2)
?>
6

Observaţi că în stabilirea sarcinii în linia 5 se află:


echo $pricewithdiscount;

Această expresie ne-ar prezenta pe document valoarea variabilei: $pricewithdiscount, fără niciun
fel de formatare, respectiv cu numărul total de zecimale, care în cazul nostru sunt 4. Cum la
ieşire vrem să prezentăm numărul cu două zecimale, în primul rând trebuie să formatăm
numărul. În acest scop, folosim funcţia number_format(). Această funcţie poate să accepte cel
mult 4 parametri. Primul parametru este numărul care se formatează, cu al doilea parametru se
determină numărul de zecimale, în timp ce al treilea parametru string va fi folosit pentru pentru
separarea părţii zecimale a numărului. La final, avem posibilitatea să definim parametrul 4, care
reprezintă stringul pentru separarea miilor. Primul parametru este obligatoriu, în timp ce celelalte
sunt opţionale. Pentru cererile sarcinii noastre este suficient să se definească doi parametri,
respectiv numărul care se formatează şi numărul de zecimale. De aceea, schimbăm linia 5 şi
înainte de scriere facem formatarea în felul următor:

echo number_format($pricewithdiscount,2)

Exerciţiul nr. 2

Aplicaţia trece prin numerele de la 0 la 1000. Trebuie reprezentate doar numerele care se împart
la trei, fără rest. Codul existent arată astfel:

1<?php
2 for($i=0;$i<1000;$i++)
3 if( AICI TREBUIE INTRODUSĂ CONDIŢIA )
4 echo $i . "<br>";
?>
5
Rezolvare:

Se poate utiliza operatorul modulo:

1<?php
2 for($i=0;$i<1000;$i++)
3 if($i%3 == 0 && $i != 0)
4 echo $i . "<br>";
?>
5

Acest exerciţiu este destinat în primul rând cursanţilor care au ceva cunoştinţe în domeniul
programării în orice limbaj. De aceea, vom explica pe scurt a doua şi a treia linie de cod, dar de
această sintaxă ne vom ocupa în detaliu în modulul următor, aşadar vă puteţi întoarce la acest
exemplu şi după lecţiile din modulul 2.

Deşi accentul acestei sarcini este pus pe definirea condiţiilor cu ajutorului operatorilor abordaţi
în lecţie, în câteva cuvinte vom explica for şi if, respectiv liniile 2 şi 3. Pe linia doi se află bucla
for, cu care se asigură executarea următoarei linii de cod (linia codului) de 1000 de ori. De
asemenea, în fiecare din aceste executări se poate folosi variabila $i, care de fiecare dată va avea
valoare mărită cu 1. Asta înseamnă că la prima executare a buclei variabilei $i va avea valoarea
0, apoi 1, 2 etc. La fiecare executare a buclei, se verifică condiţia definită în paranteză după if în
linia 3. Aici trebuie pusă expresia care va prezenta condiţia definită cu ajutorul operatorilor
abordaţi în această lecţie. Dacă condiţia este îndeplinită, respectiv dacă este returnată valoarea
true, se va executa şi următoarea linie de cod (linia 4). Cu a patra linie se asigură prezentarea
culorilor care corespund valorii variabilei $i.

Acum, putem să prezentăm condiţia definită între paranteze. În primul rând, verificăm dacă
valoarea care corespunde variabilei $i este 3. În acest scop, folosim operatorul modulo care
returnează valoare numerică prezentând restul după împărţire. Dacă după împărţire avem restul
0, înseamnă că numărul se împarte cu 3, fapt care se şi cere în exerciţiu. Pentru ca în şirul de
soluţii să nu fie prezentat şi zero, mai facem o testare, respectiv verificăm dacă numărul $i este
diferit de 0. Este important ca ambele condiţii să fie îndeplinite, aşadar din acest motiv între două
condiţionări setăm AND (&&) logic. Astfel, condiţiile noastre sunt verificate, iar exerciţiul este
gata.

………………………

Modul 2 Controlul fluxului

Instrucţiunile de ramificare
În această lecţie, ne vom ocupa de instrucţiunile de ramificare. Structurile de gestionare permit
manipularea în timpul executării programului. Pe baza structurii lor, le vom grupa în
instrucţiuni de ramificare sau condiţionale şi în instrucţiuni repetitive, dar care reprezintă
bucle de programare. Dacă vreţi ca procesarea datelor pe care le-a introdus utilizatorul să aibă
sens mai târziu, codul dvs. trebuie să ia anumite decizii.

Instrucţiunile dintr-un cod se execută predominant în ordinea în care sunt scrise. Uneori, este
însă necesar să schimbăm fluxul executării programului. Instrucţiunile de ramificare se utilizează
în cazurile în care (dacă condiţia este îndeplinită) trebuie să executăm o parte sau alta a codului.

Ramificarea condiţionată - if

Prima şi totodată instrucţiunea de ramificare de bază este if. Această instrucţiune este cunoscută
în aproape toate limbajele chiar aşa cum se numeşte: „dacă”.

Deoarece cuvântul „dacă” retoric nu prea are o anumită logică, aşa nu îl are nici în programare,
ci pe lângă acest cuvânt mai trebuie introdusă o anumită condiţie de care va depinde rezultatul
acestei instrucţiuni:

5.1 - Schema if

După cum putem vedea în schema de mai sus, programul se execută până ce ajunge la partea
care provoacă ramificarea (if), unde verifică condiţia. Dacă condiţia este îndeplinită (true), se
execută codul definit (if code). Dacă condiţia nu este îndeplinită (false), atunci va fi omis if code
(nu se va executa), ci se continuă cu încărcarea paginii.

if-else se poate deplasa de la condiţia de bază, cea minimă:


if (conditie)
instructiune;

care reprezintă doar o condiţie care trebuie îndeplinită pentru executarea unei anumite
instrucţiuni. Prin posibilităţile soluţiei alternative:

if (conditie)
{ instructiune }
else
{ instructiune2 };

deseori se va întâmpla să trebuiască să se ia de dinainte decizia dacă o anumită acţiune se va


executa, însă este mai important să se determine ce grup, din mai multe acţiuni oferite, va trebui
să se execute exact la momentul dat. Când este vorba de o astfel de problemă, folosim
instrucţiunea else în continuarea instrucţiunii condiţionate if. Instrucţiunea else se execută dacă
condiţia nu este îndeplinită.

5.2 - Schema if else

Deci, dacă condiţia este îndeplinită (true), se va executa blocul if din cod (if code) şi se va omite
blocul alternativ (else code). Pe de altă parte, dacă condiţia nu este îndeplinită (false), imediat se
trece la blocul de cod alternativ (else code), aşadar blocul de cod if (if code) este omis.

Să vedem sintaxa acestei scheme:

if (conditia care se testeaza) {


blocul de cod care va fi executat daca conditia este indeplinita
}else{
blocul de cod alternativ
}

După cum vedeţi, după închiderea blocului de cod if (paranteza acoladă închisă } ), inserăm
cuvântul-cheie else, după care este definit blocul de cod alternativ.

Iată cum arată condiţionarea în practică. De exemplu, avem o variabilă $x cu valoarea 10. Dacă
vrem să afişăm un mesaj doar atunci când variabila $x are valoarea 10, scriem următoarele:

1$x=10;
2if($x==10) echo "x is 10";

Notă: După cum puteţi vedea în exemplul anterior, după verificarea condiţiei (care a returnat
true), trebuie executată o singură linie de cod (această linie de cod nu trebuie neapărat introdusă
în paranteze acolade). Aceasta înseamnă că acelaşi exemplu s-ar putea scrie şi în felul următor:

$x=10;
if($x==10){
echo "x is 10";
}

Instrucţiunile if...elseif....else

Această instrucţiune are, în general, următoarea sintaxă:

if (conditie1) {
instructiune 1
}
elseif (conditie2) {
instructiune 2
}
else {
instructiune 3
}
5.3 - Schema if elseif

Vom explica comportamentul acestei structuri. În primul rând, se verifică prima condiţie şi, dacă
această condiţie este îndeplinită, atunci se execută code block 1, după aceea se părăseşte
structura. Numai dacă prima condiţie nu este îndeplinită, se trece la testarea condiţiei 2. Dacă a
doua condiţie este îndeplinită, atunci se execută blocul acesteia şi se părăseşte structura. Acelaşi
lucru se repetă şi pentru a treia condiţie. La sfârşit, în caz că niciuna dintre condţii nu este
îndeplinită, se execută blocul de cod alternativ (else).

Iată în ce fel am putea să scriem aceasta:

if (prima conditie) {
blocul de cod care se executa daca prima conditie este indeplinita
}elseif(a doua conditie){
blocul de cod care se executa daca a doua conditie este indeplinita
}elseif(a treia conditie){
blocul de cod care se executa daca a treia conditie este indeplinita
}else{
blocul de cod alternativ care se executa daca niciuna dintre conditii nu este indeplinita
}

În cadrul unei structuri if...else, pot exista mai multe blocuri elseif. Dacă câteva condiţii sunt
adevărate (true), se va executa doar prima dintre ele. Este evident că ceea ce manipulează
mecanismul de condiţionare este un tip Boolen, aşadar este clar că în expresie nu se poate insera
ceva care ca rezultat nu are acest tip. Totuşi, dacă vă mai amintiţi de ceea ce am vorbit în lecţiile
anterioare, am spus că PHP este capabil să convertească implicit tipurile, aşadar, chiar şi dacă
expresia condiţiei este doar un număr sau o operaţie aritmetică, PHP va fi capabil să interpreteze
şi aceasta în mod adecvat şi să pună o condiţie.

Cuvântul elseif îl puteţi scrie împreunat sau separat (else if), deoarece ambele forme sunt corecte.
În cadrul exemplelor, veţi întâlni ambele moduri de scriere.

Când folosiţi acest tip de scriere a codului, trebuie să ţineţi cont că doar un bloc (o instrucţiune
care este stabilită după condiţie) va fi executată. Condiţiile se pot exclude reciproc (doar una
poate fi executată dintre toate cele specificate), însă, dacă condiţiile sunt în aşa fel încât mai
multe trebuie să fie îndeplinite simultan, se execută doar o instrucţiune sau un bloc de
instrucţiuni după prima condiţie îndeplinită.

Condiţii încorporate

Din punct de vedere semantic, plasarea valorii numerice în expresia condiţiei nu este
corectă, motiv pentru care trebuie evitată.

De exemplu, următorul exemplu este corect din punct de vedere al funcţionalităţii programului,
dar în practică ar fi mai bine ca cifra 10 să nu fie o cifră, ci o variabilă.

1
2 <?php
3 $number = 15;
if ($number < 10) {
4 echo "Number is less than 10. ";
5 }
6 elseif ($number == 10) {
7 echo "Number is equal 10. ";
8 }
else {
9 echo "Number is greater than 10. ";
10}
11?>
12

Expresiile de ramificare se pot insera şi unele în cadrul altora, respectiv se pot încorpora în ele
însele. De exemplu:

1if(true)
if(true)
2 echo "This line of code is executed";
3

Acest exemplu (complet funcţional), pe lângă faptul că reprezintă o situaţie de condiţii


încorporate, reprezintă, de asemenea, şi un alt mod de utilizare a acestui operator: un corp fără
paranteze acolade. Această abordare este posibilă numai dacă respectivul corp subînţelege o
singură linie de cod. Dacă există mai multe linii (cel puţin două), atunci parantezele acolade sunt
obligatorii, altfel pot apărea nereguli logice în funcţionarea aplicaţiei.

Să privim exemplul:

1if (true)
2 echo "This line of code depends of condition <br>";
3 echo "This line of code will be executed in any case";

A doua linie va fi executată indiferent de situaţie. Ceea ce în exemplu este o problemă banală,
într-o aplicaţie serioasă poate duce la erori grave.

Se recomandă folosirea parantezelor acolade chiar şi atunci când aveţi o singură instrucţiune
după bloc, asta ca să fiţi siguri că instrucţiunea dvs. aparţine tocmai condiţiei respective.

Abordarea scrierii blocurilor condiţionate fără paranteze acolade se poate întâlni şi la alte
structuri pentru controlul fluxului, însă nu şi în funcţii sau clase. În afară de aceasta, de obicei
ceea ce v-aţi imaginat ca o linie (condiţionată) de cod se va transforma în mai multe linii, aşadar
cel mai bine ar fi să folosiţi paranteze acolade când manipulaţi fluxul.

Când apare nevoia de anumite operaţii logice mai complexe, există posibilitatea de localizare a
unei instrucţiuni if în alte instrucţiuni:

if (conditie1){
bloc de cod1;
}else{
if (conditie2){
bloc de cod 2;
}else{
bloc de cod 3;
}
}

Vom analiza acum acest caz. Dacă condiţia1 este îndeplinită, se va executa blocul de cod 1.
Dacă condiţia nu este îndeplinită, ramificarea externă trece la blocul de cod else în care se
găseşte ramificarea internă. Dacă este îndeplinită condiţia2, scrisă în ramificarea internă, se va
executa blocul de cod 2. Dacă nici această condiţie nu este îndeplinită, atunci se execută blocul
de cod 3.

Uneori, pentru condiţionare se foloseşte şi operatorul ternar. Acest operator se foloseşte


predominant pentru atribuirea valorii condiţionate şi nu conţine blocuri de cod, ceea ce înseamnă
că nu este o structură potrivită pentru controlul fluxului, ci este mai degrabă un operator de
atribuire. Cu toate acestea, valoarea este atribuită în mod condiţionat, motiv pentru care acest
operator influenţează fluxul aplicaţiei.

1$b = ( $a == 0 ) ? 10 : $a;

Operatorul ternar este alcătuit din patru părţi:

 Variabila căreia îi este acordată o valoare ($b);


 Condiţia ($a==0);
 Valoarea care se acordă dacă condiţia este îndeplinită (10);
 Valoarea care se acordă dacă condiţia nu este îndeplinită ($a).

Să presupunem că undeva în cod există variabila $a care are valoarea zero. Atunci când este
activat operatorul ternar, i-am spus de fapt programului să verifice o anumită condiţie şi i-am dat
alternativele pentru ambele rezultate posibile ale acestei condiţii: ? rezultat 1, în cazul în care
condiţia este îndeplinită, şi : rezultat 2, în cazul în care aceasta nu este îndeplinită. Operatorul
ternar, din exemplul de mai sus, reprezintă alternativa unei structuri if, precum cea de mai jos:

1if($a == 0){
2 $b = 10;
3}else{
4 $b = $a;
}
5

În exemplul care urmează, în primul rând se definesc trei variabile (day, month, year), care
conţin informaţii referitoare la dată. Ulterior, se foloseşte funcţia checkdate() pentru verificarea
valabilităţii datei. Prin ramificarea codului, determinăm ce mesaj va fi afişat pe pagină:

1
2 $day = 15;
3 $month = 2;
$year = 2013;
4
5 $result = checkdate( $month, $day, $year);
6
7 if ($result == true)
8 {
9 echo "Date is correct.";
10 }
else
11 {
12 echo "Date is incorrect.";
13 }
14
Notă:

Deoarece în paranteza de după cuvântul-cheie if se aşteaptă valoarea Boolean, aceasta nu


trebuie să apară drept consecinţă a comparaţiei, ci poate fi scrisă ca o valoare concretă.
Astfel, în exemplul precedent, în loc de expresia:

$result == true

am putut să scriem:

$result

În cele din urmă, iată şi cea mai frecventă eroare în crearea blocurilor condiţionate. Utilizarea
operatorului de atribuire (=) în locul operatorului de comparaţie (==):

1$a = 10;
2if($a = 5){
3 echo "Test.";
4}

Executarea acestui cod va duce la câteva consecinţe cruciale pentru executarea programului, din
cauza inserării operatorului de atribuire în locul operatorului de comparaţie:

 În condiţie, variabila $a va primi valoarea 5, pe care o va reţine pe parcursul


derulării programului, ceea ce probabil nu dorim să se întâmple;
 Într-o expresie condiţionată, după atribuirea valorii pentru variabila $a, aceasta va avea
valoarea 5. După cum am şi spus în lecţiile precedente, toate valorile număr întreg
(integer), în afară de zero, devin true atunci când se transformă în tip Boolean, chiar dacă
sunt negative. Singura situaţie în care integer se transformă în Boolean false este atunci
când integer este zero. În cazul numărului 5, se obţine true şi astfel această condiţie va fi
îndeplinită întotdeauna, indiferent de ce am face noi cu acest program, înainte sau după
această condiţie.

Dacă scrieţi următoarele: »else if« în loc de »elseif«, programul va semnala o eroare?
Programul nu va semnala eroare, deoarece ambele instrucţiuni sunt corecte din punct de
vedere sintactic.
Programul va semnala eroare, deoarece instrucţiunile nu sunt corecte din punct de vedere
sintactic.

Exerciţiul nr. 1
Pe pagină există variabila $page. În variabilă, este permisă existenţa uneia din două valori
pe baza cărora va fi încărcată pagina. Cele două valori sunt "index" şi "products". Dacă valoarea
este "index", se încarcă pagina index.html, dacă valoarea este "products", se încarcă pagina
products.html. Dacă nicio valoare nu coincide cu valoarea solicitată, se încarcă pagina
login.html.

Rezolvare:

1
2 <?php
3 $page = "index";
if( $page == "index" ){
4 $page = "index.html";
5 }elseif( $page == "products" ){
6 $page = "products.html";
7 }else{
$page = "login.html";
8 }
9 echo $page;
10?>
11

Ca să rezolvăm acest exercițiu, în primul rând definim variabila care va prezenta stringul pe care
îl testăm. În cazul nostru, aceasta este variabila $page aflată pe a doua linie de cod. În aceeaşi
linie, atribuim valoare acestei variabile, care iniţial este index. Apoi, folosim structura if, else if,
else pentru a prelucra fiecare scenariu care ne interesează aşa cum este definit în exerciţiu. În
primul rând, setăm if şi verificăm dacă $page este la fel ca şi "index":

1if( $page == "index" ){

Dacă această condiţie va fi îndeplinită, pe pagină va apărea textul: index.html.

Dacă această primă condiţie nu este îndeplinită, trebuie să o verificăm pe următoarea. Pentru asta
folosim else if:

1elseif( $page == "products" )

Astfel, verificăm dacă valoarea variabilei $page este la fel ca şi "products".

Dacă niciuna dintre cele două condiţii nu este îndeplinită, se va executa else block:

1else{
2
3 $page = "login.html";
4
5 }
şi pe pagină va apărea textul: login.html, care este cerinţa exerciţiului. Cu aceasta am terminat
exercițiul, dar, dacă vreţi să verificaţi dacă este complet funcţional, încercaţi să schimbaţi
valoarea iniţială pentru variabila: $page, după care verificaţi prezentarea pe pagină.

Exerciţiul nr. 2

În sistemul pentru monitorizarea autoturismelor, există patru statusuri ale autoturismelor: în


staționare, în mişcare, dispărut, necunoscut. Aceste statusuri sunt marcate cu cifrele 1, 2, 3 şi 4.

În aplicaţie, intră ultimul status cunoscut al autoturismului, precum şi statusul curent al acestuia.
Statusurile respective intră în variabilele $lastStatus şi $status:

$lastStatus = 2;
$status = 4;

Trebuie să se atribuie valoarea variabilei $statusName. Acest nume va conţine reprezentarea


textuală a statusului autoturismului (în mişcare, în staționare, necunoscut etc.).

Astfel, trebuie să se respecte următoarea regulă: dacă ultima stare a autoturismului a fost "în
mişcare", iar noul status este "necunoscut", noua stare trebuie să fie "dispărut".

Variabila $statusName trebuie emisă la ieşire.

Rezolvare:

1
2 $lastStatus = 2;
3 $status = 4;
4 $statusName = "unknown";
5
6 if($status == 1)
7 $statusName = "stays";
else if($status == 2)
8 $statusName = "moves";
9 else if($status == 3)
10 $statusName = "dissapear";
11else if($status == 4)
{
12 if($lastStatus == 2)
13 $statusName = "dissapear";
14 else
15 $statusName = "unknown";
16 }
echo $statusName;
17
18
Rezolvarea acestui exerciţiu urmăreşte o structură similară cu cea precedentă, cu diferenţa că aici
se cere ca executările condiţionate să fie puse una într-alta. Este menţionat că trebuie să se
respecte următoarea regulă: „...dacă ultima stare a autoturismului a fost "în mişcare", iar noua
stare este "necunoscut", noua stare trebuie să fie "dispărut"...". De aceea, la începutul codului
care prezintă soluţia, definim variabilele care vor fi folosite mai departe. Apoi, imediat punem
executarea condiţională definită prin definirea condiţiilor if şi trei else if. În fiecare condiţie,
verificăm $status (1,2 şi 3). Aceste trei statusuri trebuie verificate, iar pe baza lor se definește
imediat valoarea variabilei $statusName. Ca să respectăm cerinţa din exerciţiu pentru $status cu
care este confirmată valoarea 4, facem o nouă verificare internă. Aici, ţinem cont de valoarea
ultimului status, respectiv de valoarea variabilei: $lastStatus. Dacă ultimul status este 2, variabila
$statusName va primi valoarea "dissapear", iar în caz contrar, "unknown". Astfel, am respectat
toate cerinţele exerciţiului, iar testarea noastră este gata.

Mai rămâne doar să prezentăm pe pagină valoarea nou creată, iar asta facem cu linia:

1echo $statusName;

Exerciţiul nr. 3

Trebuie scris un program care permite utilizatorului să ghicească numărul definit în cod. De
asemenea, pentru ca utilizatorul să ştie cât este de aproape de răspuns, anunţaţi-l cu un mesaj în
cazul în care diferenţa dintre numărul ghicit şi cel real este mai mică de 10. Încercarea se
introduce prin parametrul GET "number".

Rezolvare:

1
2 $secretNumber = 765;
3 if ($_GET['number'] == $secretNumber )
4 {
echo ' <p> Congratulations!!! </p> ';
5 }
6 elseif( abs($_GET['number'] - $secretNumber) < 10 )
7 {
8 echo ' <p> You are near to the result!!! </p> ';
}
9 else
10 {
11 echo ' <p> Try again!!! </p> ';
12 }
13

După cum este menţionat în cerinţă, trebuie să se folosească parametrii GET, aşadar pentru asta
o să folosim parametrii GET, aşadar în primul rând o să vedem cum să definim parametrul GET
şi cum să folosim valoarea sa în codul PHP. Parametrii GET fac parte din URL, de aceea se pot
scrie pe URL-ul deja existent. Să zicem că codul pentru acest exemplu se află în fişierul
index.php aflat în următoarea locaţie:

C:\wamp\www\test\index.php

În acest caz, în căsuța de adrese a motorului de căutare am avea URL-ul cu următoarea structură:
http://localhost/test/index.php

Ca să împachetăm în acest URL parametrul GET numit "number", care are valoarea 760, pe
URL-ul existent am scrie:

1?number=760

Deci, acum adresa completă ar arăta astfel:

http://localhost/test/index.php?number=760

Dacă accesăm această adresă, PHP ar putea să recunoască parametrul GET cu numele "number".
Acest parametru l-am putea accesa cu următoarea linie:

1$_GET['number']

Acum, putem să trecem la codul PHP pentru rezolvarea problemei. În primul rând, definim
variabila $secretNumber, căreia îi atribuim valoarea pentru numărul solicitat (număr arbitrar).

Imediat după asta verificăm dacă utilizatorul a nimerit numărul ascuns. Asta facem cu următorul
cod:

1if ($_GET['number'] == $secretNumber )


2 {
3 echo ' <p> Congratulations!!! </p> ';
4 }

Dacă utilizatorul nu a nimerit numărul, ar trebui să verifice dacă este pe aproape. Asta se face cu
următorul cod:

1elseif( abs($_GET['number'] - $secretNumber) < 10 )


2 {
3 echo ' <p> You are near to the result!!! </p> ';
4 }

Ca să avem o explicaţie adecvată şi în cazurile în care utilizatorul a trimis prin GET un număr
mult mai mic decât cel căutat, în primul rând numărul trimis de către utilizator îl micşorăm cu
valoarea numărului ascuns, apoi calculăm valoarea absolută a acestui rezultat. Astfel, nu putem
să obţinem în rezultat un număr negativ. Valoarea absolută se calculează cu funcţia abs(), căreia
îi atribuim ca parametru numărul a cărui valoarea absolută trebuie să o calculăm.
Dacă niciuna dintre aceste condiţii nu este îndeplinită, trebuie asigurat un bloc de cod alternativ,
care se va executa în acest caz:

1else
2 {
3 echo ' <p> Try again!!! </p> ';
4 }

Cu aceasta am terminat exercițiul şi, modificând valoarea parametrului GET "number", putem să
verificăm cum funcţionează logica creată.

Exerciţiul nr. 4

La un magazin de mobilier de birou, proprietarii au stabilit reduceri în luna ianuarie pentru


achiziţionarea scaunelor de birou, conform următoarelor reguli:

 Pentru mai puţin de 10 scaune cumpărate – nu există reducere;


 Pentru 10 – 49 scaune cumpărate – reducere de 5%;
 Pentru 50 – 99 scaune cumpărate – reducere de 10%;
 Pentru 100 de scaune cumpărate sau mai multe – reducere de 15%.

Trebuie scris codul de programare care, folosind structurile if else, va calcula reducerile
în momentul achiziţionării. Recomandare: utilizaţi operatorul de conjuncţie ( &&).

Rezolvare:

1
2
$chairs = 10;
3 if ( $chairs < 10)
4 {
5 $discount = 0;
6 }
elseif ( $chairs >= 10 && $chairs <= 49 )
7 {
8 $discount = 5;
9 }
10elseif ( $chairs >= 50 && $chairs <= 99 )
11{
$discount = 10;
12}
13elseif ( $chairs >= 100 )
14{
15$discount = 15;
16}echo $discount;
17
18
După cum am explicat mai devreme, în codul precedent este folosită instrucţiunea elseif cu
condiţii care se exclud reciproc (doar una dintre condiţii poate fi îndeplinită). Deoarece ştim că
nu există verificarea viitoarei condiţii în caz că cea precedentă este îndeplinită, acest exemplu se
poate rezolva în felul următor:

1
2
$chairs = 100;
3 if ( $chairs < 10)
4 {
5 $discount = 0;
6 }
elseif ( $chairs <= 49 )
7 {
8 $discount = 5;
9 }
10elseif ( $chairs <= 99 )
11{
$discount = 10;
12}
13elseif ( $chairs >= 100 )
14{
15$discount = 15;
16}echo $discount;
17
18

………………………

Structura switch-case
În această lecţie, ne vom ocupa de instrucţiunea switch şi vom explica structura switch-case.

Instrucţiunea switch

Modul de condiţionare if..elseif..else, de executare a unui cod este bun, însă nu prea elegant
atunci când avem un număr mai mare de alternative elseif, aşadar pentru astfel de cazuri folosim
o structură switch case mai clară. Cu alte cuvinte, am putea spune că această structură este ideală
pentru testarea unei variabile sau declaraţii care poate avea mai multe valori aşteptate. Vom lua
ca exemplu nevoia de testare a unei variabile în cod, care ar trebui să conţină numele zilelor din
săptămână. Este clar că putem aştepta doar 7 valori.

Reprezentarea grafică a structurii switch case s-ar putea ilustra în felul următor:
6.1 - Schema switch

Să observăm următoarea sintaxă:

1 switch (expresie) {
2 case valoare1:
//Blocul de cod care se va executa în caz că expresia şi valoare 1
3 coincid
4 break; //Cuvântul-cheie cu care se întrerupe executarea codului în
5 structura switch
6 case valoare2:
7 //Blocul de cod care se va executa dacă expresia şi valoarea 2 coincid
break;
8 default:
9 //Blocul de cod care se va executa dacă nu există alte coincideri
10}

În structura switch, mai întâi se calculează expresia, iar apoi valoarea rezultată se compară cu
valorile specificate în marcajele case. Dacă valoarea expresiei este egală cu una dintre valorile
din marcajul case, este executat grupul de instrucţiuni care urmează după acest marcaj. Dacă
valoarea expresiei diferă de toate cele listate în case, este executat grupul de instrucţiuni care
urmează după marcajul default.
Această structură poate fi înlocuită de o structură if...elseif...else, dar în unele cazuri switch...case
este mai practic şi mai clar. De exemplu, în structura if-else, la fiecare verificare trebuie să
plasaţi variabilele în expresia condiţionată. În switch-case, acest lucru nu este necesar. Pe de altă
parte, la switch-case nu puteţi să schimbaţi variabila, ci doar expresiile acesteia. Mai mult,
switch-case, deşi este destul de clară, nu este adecvată pentru blocuri de condiţii mari. De obicei,
în ea sunt plasate acţiuni condiţionate sau funcţii scurte.

Să analizăm un exemplu:

1
2 $x = 2;
3 switch( $x ){
case 1:
4 echo "x is one";
5 break;
6 case 2:
7 echo "x is two";
break;
8 default:
9 echo "x is not one either two";
10}<span style="font-size: 14px;"> </span>
11

În exemplul de mai sus, am iniţializat mai întâi variabila $x, apoi am aşezat-o în structura switch.
Structura switch subînţelege blocuri de condiţii mărginite cu paranteze acolade. Fiecare condiţie
începe cu cuvântul-cheie case, urmat de valoarea condiţionată sau de condiţie şi două puncte
care desemnează începutul blocului. Puteţi să puneţi acest bloc între paranteze acolade (nu este
obligatoriu). Spre deosebire de blocurile de condiţii standard, în cazul blocurilor case va
fi executat tot blocul condiţionat (nu doar primul rând). Mai mult, dacă la un moment dat
condiţia este îndeplinită, se vor executa şi liniile care urmează, până când programul primeşte o
directivă care-l înştiinţează să părăsească structura în totalitate sau să nu execute structura în
întregime.

1
2$x = 1;
switch( $x ){
3 case 1:
4 echo "x is one";
5 case 2:
6 echo "x is two";
default:
7 echo "x is not one either two";
8}<span style="font-size: 14px;"> </span>
9

Drept rezultat, acest cod va da, în PHP, toate cele trei instrucţiuni echo, tocmai pentru că nu
există niciunde o ieşire din structură. Aceasta înseamnă că partea implicită a oricărui bloc case
este şi comanda break (părăsirea necondiţionată a structurii). Totuşi, există şi cazuri când
programatorul intenţionat nu vrea să insereze instrucţiunea break. Acestea sunt cazuri în care
două sau mai multe valori ale expresiei trebuie să execute acelaşi bloc de cod.
Haideţi să analizăm următorul exemplu, care ilustrează tocmai cele explicate în rândurile de mai
sus:

1
2 $x = 1;
3 switch( $x ){
case 1:
4
case 2:
5 echo "x is one or two";
6 break;
7 case 3:
8 case 4:
echo "x is three or four";
9 break;
10 default:
11 echo "x is not either one, either two,either three, either four";
12}
13

În ceea ce priveşte structura switch-case, PHP este foarte flexibil în comparaţie cu alte limbaje.
În timp ce în alte limbaje aceste expresii sunt deseori limitate doar la valori de tip numere întregi,
PHP poate accepta orice valoare în structură şi o poate procesa apoi corect prin intermediul
cazurilor:

//$d=3;
1 $d="Wed";
2 switch ($d)
3 {
4 case "Mon":
case 1:
5 echo "Today is Monday";
6 break;
7 case "Tue":
8 case 2:
9 echo "Today is Tuesday";
break;
10case "Wed":
11case 3:
12 echo "Today is Wednesday";
13 break;
case "Thu":
14case 4:
15 echo "Today is Thursday";
16 break;
17case "Fri":
18case 5:
echo "Today is Friday";
19 break;
20case "Sat":
21case 6:
22 echo "Today is Saturday";
break;
23case "Sun":
24case 7:
25 echo "Today is Sunday";
break;
26default:
27 echo "Wonder which day is this ?";
28}
29
30
31
32
33
34
35

În afară de valorile scalare, cazurile pot accepta şi expresii întregi. De exemplu, putem verifica
dacă o valoare este egală, mai mare sau mai mică decât cea de intrare:

case: $a > 1...

Putem verifica şi condiţiile din afara contextului:

1
2 $x = 7;
3 switch(true)
{
4 case $x%2 == 0;
5 echo "x is divisible by 2";
6 break;
7 case $x%3 == 0:
8 echo "x is not divisible by 2, but it is divisible by 3";
break;
9 default:
10 echo "x is not divisible by 2, either 3";
11}<span style="font-size: 14px;"> </span>
12

În condiţia case, putem pune de asemenea şi o funcţie:

1 $x = false;
2 switch(true)
3 {
case is_int($x):
4 echo "x is a integer";
5 break;
6 case is_string($x):
7 echo "x is a string";
break;
8 case is_bool($x):
9 echo "x is a boolean";
10 break;
11 }
12
13

Când este vorba de expresia case, puteţi utiliza variabile de tip integer, double şi string, în timp
ce şirurile şi obiectele nu pot fi acceptate ca variabile de intrare dacă nu sunt marcate ca tipuri
mai simple.

Mai multe despre instrucţiunea break

În toate exemplele de până acum, aţi putut vedea instrucţiunea break la finalul fiecărui bloc case.
Cu următorul exemplu, vom explica principalul rol al instrucţiunii break în cadrul blocurilor de
instrucţiuni switch-case:

1
2 $category = "news";
3
4 switch ( $category)
5 {
case "news" :
6
echo ' <p> News from the world ... </p> ';
7 break;
8 case "politics" :
9 echo ' <p> Politics... </p> ';
10 break;
case "sport" :
11 echo ' <p> Last sport results ... </p> ';
12 break;
13 default :
14 echo ' <p> Welcome... </p> ';
15 }
16

Exemplul prezentat are cadre şi sintaxe standard, pe care le-am explicat deja. Bineînţeles, se
subînţelege că variabila $category a fost declarată în partea precedentă a codului, lucru pe care l-
am şi făcut la începutul scriptului PHP:

$category= "news";

La final, programul nostru va scrie:

News from the world...

O astfel de funcţionare a programului şi a structurii switch-case este posibilă tocmai datorită


instrucţiunii break. Iată despre ce este vorba:

În momentul executării, programul verifică blocurile pentru a vedea care dintre ele satisface
valoarea variabilei $category. Când îl găseşte, întâlneşte şi instrucţiunea break şi opreşte
executarea în continuare a programului. Dacă am omite instrucţiunile break din codul precedent,
scriptul nostru PHP ar avea următoarea structură:

1
2 $category= "news";
3
4 switch ( $category )
{
5 case "news" :
6 echo ' <p> News from the world...</p> ';
7 case "politics" :
8 echo ' <p> Politics... </p> ';
9 case "sport" :
echo ' <p> Last sport results ... </p> ';
10 default :
11 echo ' <p> Welcome ... </p> ';
12 }
13

Fără break în cadrul blocurilor case, programul nostru execută toate blocurile case neglijând
variabila condiţională switch. După executare, rezultatul final va fi:

News from the world...


Politics...
Last sport results ...
Welcome ...

Instrucţiunea default

La finalul fiecărei structuri switch-sase, se află instrucţiunea default. Când pornim programul,
PHP încearcă să găsească unul dintre blocurile case care satisface în avans condiţia stabilită; în
cazul în care niciuna dintre instrucţiunile condiţionale nu satisface criteriile prevăzute, are loc
executarea instrucţiunii default. Pe scurt, comanda default este cea care se execută când niciuna
nu este îndeplinită. Iată şi un exemplu concret:

1 $i = 5; // sample
2 switch ( $i ) {
3 case 0:
echo "i is equal 0";
4 break;
5 case 1:
6 echo "i is equal 1";
7 break;
8 case 2:
echo "i is equal 2";
9 break;
10 default:
11 echo "i is not equal 0, 1 either 2";
12 }
13
14

După executarea programului, la final obţinem rezultatul:

i is not equal 0, 1 either 2

ceea ce reprezintă tocmai instrucţiunea noastră default.

Fiţi atenţi la faptul că poziţia cazurilor nu joacă niciun rol în fluxul structurii. Următorul exemplu
va da acelaşi rezultat precum cel de mai devreme, deşi ordinea cazurilor este alta:

1
2 $i = 5; // sample
3 switch ( $i ) {
4 default:
5 echo "i is not equal 0, 1 either 2";
break;
6 case 1:
7 echo "i is equal 1";
8 break;
9 case 0:
echo "i is equal 0";
10 break;
11 case 2:
12 echo "i is equal 2";
13 break;
14 }
15

Notă:

Trebuie să ştiţi că versiunea PHP 5.7 permite utilizarea blocurile default multiple, unde doar
ultimul bloc default s-ar fi executat fără probleme. Haideţi să vedem aceasta în următorul
exemplu:

1 <?php
2
$x = 4;
3
4 switch($x){
5 case 1:
6 echo 'Case 1';
7 break;
8
case 2:
9 echo 'Case 2';
10 break;
11
12 case 3:
13 echo 'Case 3';
break;
14
15 default:
16 echo 'Default 1';
17 break;
18
19 default:
echo 'Default 2';
20 break;
21}
22
23
24
25

Rezultatul pe pagină ar fi fost:

Default 2

În versiunea PHP7, nu mai există un astfel de comportament şi, dacă apar blocuri default
multiple, se va genera o eroare.

Dacă omitem instrucţiunea break în cadrul blocurilor case:


executăm toate blocurile case care urmează după coinciderea condiţiilor
oprim programul
va fi semnalată o eroare de sintaxă

Pe scurt, instrucţiunea/cazul default reprezintă:


cazul care se execută când nicio condiţie nu este îndeplinită
cazul care se execută în orice caz, chiar dacă una dintre condiţii este îndeplinită
cazul care nu va fi executat niciodată

Exemplul nr.1

Deseori, pe site-urile de vânzări întâlnim partea de completare a chestionarului "Cum aţi aflat de
noi". Astfel de chestionare funcţionează prin intermediul structurii switch-case.
6.2 - Exemplu de formular "How did you find us?"

Aspectul şi alegerea modului de conectare cu blocurile nu face parte din subiectul acestui curs şi
din acest motiv nu vom crea pagini HTML cu meniuri derulante care conţin valorile variabilei
noastre pentru condiţia switch. Acum, vom explica doar partea switch-case a scriptului PHP.

Când setăm ca variabila noastră $way (pe care am declarat-o) să conţină valorile a, b, c... care ne
servesc în continuare drept câmpuri selectate pe pagină, putem utiliza următorul cod:

1
2 $way = "b";
3 switch ($way){
4 case "a":
echo '<p> Regular customer ... </p>';
5 break;
6 case "b":
7 echo '<p> Customer has found us over the TV commercial.... </p>';
8 break;
9 case "c":
echo '<p> Recommendation... </p>';
10 break;
11 default :
12 echo '<p> We don't know how customer found us...</p>';
13 }
14
Pentru a observa funcţionarea programului, am atribuit variabilei $way valoarea "b" înaintea
structurii switch-case, pentru a simula alegerea modului în care clientul a aflat despre noi. După
execuţia programului, rezultatul va fi:

Customer has found us over the TV commercial...

Exemplul nr. 2

Din exemplul de mai jos, putem concluziona că în cadrul expresiei switch putem executa şi
operaţii de un grad mai mic, precum, de exemplu, operaţia de mărire:

1
2 <?php
3 $a = 0;
4
5 switch(++$a) {
6 case 3 :
echo 3;
7
break;
8 case 2:
9 echo 2;
10 break;
11 case 1:
echo 1;
12 break;
13 default :
14 echo "No matching...";
15 break;
16}
?>
17
18

După executarea programului, la ieşire obţinem rezultatul:

ceea ce confirmă că operaţia în cadrul lui switch este executată şi că variabila care la început
avea valoarea 0, după trecerea prin switch-case, a obţinut valoarea 1.

Exerciţiul nr. 1

Trebuie scris codul care va conţine cinci constante pentru zilele lucrătoare din săptămână
(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY).

De asemenea, codul trebuie să conţină partea care verifică constanta (ziua din săptămână) şi, pe
baza ei, afişează descrierea zilei prin intermediul structurii switch-case. Dacă este luni,
descrierea este "prima zi din săptămână" etc. Trebuie să se facă o testare a codului creat.
Rezolvare:

1
2
3 <?php
4 define( "MONDAY", 1 );
5 define( "TUESDAY", 2 );
6 define( "WEDNESDAY", 3 );
7 define( "THURSDAY", 4 );
define( "FRIDAY", 5 );
8
9 $day = MONDAY;
10
11 switch( $day ){
12 case MONDAY:
13 $description = "First day of week";
14 break;
case TUESDAY:
15 $description = "Second day of week";
16 break;
17 case WEDNESDAY:
18 $description = "Third day of week";
break;
19 case THURSDAY:
20 $description = "Forth day of week";
21 break;
22 case FRIDAY:
23 $description = "Fifth day of week";
break;
24 default:
25 $description = "no description";
26 break;
27 }
28
29echo $description;
?>
30
31
32

Prima cerere din această temă este crearea constantei. Să ne aducem aminte că constantele se
creează cu ajutorul funcţiei define(). Primul parametru al acestei funcţii este numele constantei,
în timp ce al doilea este valoarea ei.

De asemenea, definim şi valoarea pentru variabila $day, cu care stabilim ziua din săptămână.
Apoi, creăm switch şi între paranteze rotunde punem variabila pe care vrem să o testăm. Această
variabilă va fi comparată cu valorile care sunt definite după case, până când are loc
suprapunerea. Dacă aceasta nu are loc, se va executa default block al codului.

La final, este suficient ca prin comanda echo să prezentăm valoarea pentru $description.
Exerciţiul nr. 2

Trebuie scris un cod care, pe baza variabilelor $operator, $operand1 şi $operand2, va executa
operaţia de calcul şi va afişa rezultatul.

În acest scop, trebuie să se folosească structura switch-case.

Rezolvare:

1
2
3 <?php
4 $operator = "-";
$operand1 = 2;
5 $operand2 = 3;
6
7 switch($operator)
8 {
9 case "+":
10 $result = $operand1 + $operand2;
break;
11 case "-":
12 $result = $operand1 - $operand2;
13 break;
14 case "*":
$result = $operand1 * $operand2;
15 break;
16 case "/":
17 $result = $operand1 / $operand2;
18 break;
19 default:
$result = "Unknown result.";
20 }
21echo $result;
22?>
23
24

Rezolvarea acestei probleme este foarte asemănătoare cu cea precedentă după structură. În
primul rând, am creat trei variabile după cum este solicitat în enunţ şi le-am atribuit imediat
valori. Acum, prin switch trebuie să verificăm ce valoare are variabila $operator, ca pe baza
aceasta să putem executa operaţia de calcul corespunzătoare. Pentru fiecare dintre expresiile
potenţiale, punem rezultatul în variabila $result.

Dacă $operator string este cel care nu corespunde niciunei valori care este definită în switch, ca
rezultat se ia string: „Unknown result“.

Exerciţiul nr. 3
Trebuie creat un program care îl va informa pe utilizator despre activităţile sale din timpul
studierii unui curs. Se verifică numărul de accesări la o lecţie (de câte ori s-a deschis o lecţie) şi,
pe baza aceasta, utilizatorul este informat despre începerea procesului de învăţare, despre testul
pe modul şi despre finalizarea cursului.

Se foloseşte structura switch-case. Trebuie definită şi variabila pentru numărul de intrări căreia i
se atribuie valoarea 0, pentru a se putea face numărarea intrărilor în cod în continuare.

Rezolvare:

1
2 <?php
$numberOfEntries = 0;
3
4 switch ($numberOfEntries){
5 case 0 :
6 echo ' Welcome! You can start with learning...';
7 break;
case 20 :
8 echo ' It is time for test...';
9 break;
10 case 30 :
11 echo ' You have developed a condition for completion of the
12 course....';
break;
13}
14?>
15

La început, creăm variabila $numberOfEntries, care va prezenta numărul de intrări pe platforma


pentru studiu. Pentru utilizator, vrem să generăm diferite mesaje pentru trei numere de intrări, şi
anume: prima dată, după 20 şi după 30 de vizite. Folosim structura switch ca şi la exerciţiile
precedente, dar de data aceasta nu avem default clock code.

Notă:

După terminarea tuturor exerciţiilor, se recomandă și testarea codului. Puteţi testa codul
atribuind noi valori variabilelor declarate în cadrul exerciţiilor şi în acest fel puteţi verifica
comportamentul structurilor switch-case şi cu alte expresii condiţionate
…………………………………

Bucla for
Unitate: 7 din 19 00:29:35

+Rezumat
Subiectul lecţiei este bucla for şi variaţiile acesteia. Regulile nescrise ale practicii bune de
programare implică şi faptul că aceleaşi blocuri de cod nu ar trebui să se repete, adică să se
copieze de mai multe ori. Totuşi, deseori trebuie să executăm repetitiv anumite blocuri de cod.
Vom analiza acest caz practic: Am creat un bloc de cod prin care pe pagină este afişată o ştire. În
momentul în care decidem să afişăm pe pagină 10 ştiri, avem situaţia în care acelaşi bloc de cod,
sau unul similar, trebuie să-l copiem de 10 ori. Acest caz este cât de cât acceptabil, însă ce se
întâmplă dacă avem situaţia în care un bloc de cod trebuie repetat de 100 de ori sau chiar şi
situaţia în care nici măcar nu ştim de câte ori trebuie să se repete acelaşi bloc de cod? În astfel de
situaţii, în ajutor ne vin buclele. În buclă, putem insera un anumit bloc de cod, iar bucla va
executa blocul respectiv de câte ori este specificat. Fiecare trecere prin blocul de cod o numim
iteraţie.

PHP are câteva tipuri de bucle, dar, cu excepţia diverselor variaţiuni, numărul de bucle se reduce
la două: buclele for şi while. În această lecţie, vom vorbi despre bucla for şi despre variaţia
acesteia, foreach.

Bucla for

Bucla for se utilizează atunci când ştim în prealabil cu exactitate de câte ori trebuie executat
blocul de instrucţiuni. Această buclă are următoarea sintaxă:

for (iniţializare; condiţie; incrementare) {


bloc de instrucţiuni;
}

Primul parametru se foloseşte pentru crearea şi pentru setarea valorii iniţiale a


numărătorului/counter. Al doilea parametru conţine condiţia pentru counter, iar al treilea
determină cum anume este incrementat counterul.
7.1- Schema for

Chiar la început, bucla iniţializează variabila care va fi counter (deşi aici se pot iniţializa şi alte
variabile). După aceea, se verifică condiţia. În cazul în care condiţia este îndeplinită, se va
executa blocul de cod definit în corpul buclei. După executarea codului se execută incrementarea
counter-ului (totuşi, aceasta nu trebuie să fie neapărat doar incrementarea, ci poate fi şi orice altă
operaţie asupra counter-ului), după care din nou se verifică condiţia. O astfel de trecere prin
buclă se numeşte iteraţie. Când testarea condiţiei returnează ca rezultat valoarea false, executarea
buclei se întrerupe.

Mai multe detalii despre sintaxă:

for (iniţializare; condiţie; expresie_finală){


//Bloc de cod
}

Iniţializarea - cea mai des folosită şi totodată forma de bază a buclei for implică ca în partea de
cod prezentată mai sus ca initializare să se definească o variabilă (cel mai des variabila i), care se
va folosi ca şi counter. În majoritatea cazurilor, este foarte util ca valoarea iniţială a acestei
variabile să fie 0, deoarece deseori cu ajutorul acestei bucle trecem prin şirul a cărui indexare
începe cu zero. În afară de iniţializarea variabilei care va fi counter, aici se pot defini şi alte
variabile dacă este necesar.

Condiţia - în partea în care este scrisă condiţia, se defineşte expresia al cărei rezultat de
executare trebuie să vă returneze o valoare Boolean. Condiţia se construieşte cel mai des prin
compararea unei valori cu variabila definită în counter. În caz că această condiţie este îndeplinită,
se continuă cu executarea buclei for, în caz contrar executarea buclei se întrerupe.

Expresia_finală - codul definit în această parte se execută la sfârşitul fiecărei iteraţii. Cel mai
des se foloseşte pentru mărirea (sau modificarea) counter-ului.

Notă:

Iniţializarea, condiţia şi expresia_finală se separă prin punct şi virgulă (;), separarea fiind
obligatorie. În cazuri speciale, este permisă şi omiterea oricărui cod într-una din aceste părţi
(chiar şi în toate cele trei părţi), însă semnul punct şi virulă (;) introdus în paranteză trebuie,
totuşi, să existe.
Exemplu:

for ( ; ; ){

//Bloc de cod

Nu scrieţi un astfel de cod, dacă nu sunteţi sută la sută siguri ce vreţi să faceţi.

Următorul exemplu de cod scrie mesajul de întâmpinare de 4 ori:

1<?php
2for($counter=1; $counter < 5; $counter++) {
3 echo "Welcome! <br/>";
4 }
5?>

Mai întâi, valoarea variabilei $counter este setată la 1. Al doilea parametru conţine condiţia.
Blocul de instrucţiuni se va executa atâta timp cât această condiţie este îndeplinită. Al treilea
parametru măreşte variabila $counter cu 1.

Buclele for se folosesc deseori pentru trecerea prin şiruri. De exemplu:

1 <?php
2 // creates a new array of five elements
3 $colors = array('red', 'green', 'blue', 'yellow','white');
4
for ($i = 0; $i < sizeof($colors); $i++)
5 {
6 $br = $i + 1;
7 echo "Value of element $br is $colors[$i].";
8 }
9 ?>
10

Notă:

Deoarece sintaxa pentru crearea şi manipularea şirurilor încă nu este abordată în detaliu în
lecţie (dar urmează să fie abordată în lecţiile următoare), aici vom sublinia doar
caracteristicile de bază a şirurilor:

 Şirurile reprezintă colecţii de date. Aceasta înseamnă că o variabilă poate să conţină


mai multe valori diferite;
 Datele localizate în şir se deosebesc pe baza indexurilor (data localizată pe prima
poziţie are indexul 0, data localizată pe a doua poziţie are indexul 1);
 Indexarea elementelor în şir începe aproape întotdeauna cu 0.

Şirul creat mai sus are cinci elemente; indexurile elementelor sunt cuprinse între 0 şi 4. De aceea,
în condiţie se foloseşte o inegalitate strictă pentru a preveni programul să acceseze elementul cu
indexul 5, care nu există.

Ştim că există trei părţi de iniţializare a buclei for. În exemplele precedente, fiecare parte a avut
câte un parametru, dar aceasta nu este o structură obligatorie. Uneori, putem defini mai mulţi
parametri într-o singură iniţializare.

Următoarea buclă va iniţializa variabilele $i şi $a şi le va acorda diferite valori. Apoi, este setată
o condiţie (ca $i să fie mai mic decât 10), după care intervine la ambele valori, mărindu-le cu 1:

1<?php
2for($i=0,$a=5;$i<10;$i++,$a++)
3 echo $i . ":" . $a . "<br>";
4 ?>
Notă:

Din exemplul precedent se vede că, la fel ca şi la instrucţiunea if, nu este necesară
introducerea parantezelor acolade, în caz că vrem să depindă de buclă doar executarea primei
linii de cod care este cuprins de buclă.

Vom vedea aceasta în următorul exemplu:

<?php
for($i=0,$a=5;$i<10;$i++,$a++)
echo $i . ":" . $a . "<br>";
echo "This line do not depends of loop.";
?>

După executarea codului, pe ecran vom obţine următorul rezultat:

0:5
1:6
2:7
3:8
4:9
5:10
6:11
7:12
8:13
9:14
This line do not depends of loop.

Însă regulile de sintaxă nu subînţeleg introducerea tuturor celor trei parametri. Următorul
exemplu va fi, de asemenea, valid:

1for($i=0;$i<10;){
2 echo $i;
3 $i++;
4 }

În exemplu, al treilea parametru este omis, nu este definit. De fapt, acesta nu este omis, ci este
gol, lucru pe care îl arată marcajul ; situat după numărul 10.

După o astfel de iniţializare, incrementarea este executată în bloc, ceea ce poate fi foarte
periculos. Dacă incrementul este exclus, putem să ajungem într-o aşa-numită buclă moartă
(buclă care se execută la infinit) care, în cel mai bun caz, va bloca mediul.

Atenţie dacă aveţi o buclă moartă, deoarece există diverse moduri ca ea să se producă. Pur şi
simplu, fiţi atenţi ca bucla dvs. să nu aibă un aspect în care condiţiile sale de executare să poată fi
întotdeauna completate.
De exemplu:

1for($i=1;$i>0;) echo $i++;

Veţi observa că cele două exemple precedente sunt scrise pe un singur rând. Aceasta se datorează
aceleiaşi reguli care este valabilă şi pentru celelalte structuri de control al fluxului. După
condiţie, puteţi scrie doar o singură linie de cod fără paranteze. Dacă doriţi să scrieţi un bloc de
cod (două sau mai multe linii), trebuie să puneţi tot blocul între paranteze acolade.

Am văzut că este posibilă omiterea celui de-al treilea parametru şi rezolvarea funcţiei acestuia cu
o nouă linie de cod în propriul corp al buclei. Mai jos, avem un exemplu prin care reprezentăm
cum un lucru similar se poate face şi cu ceilalţi doi parametri:

1$i = 0;
2for(;;){
3 if($i > 9) break;
4 echo $i;
5 $i++;
}
6

Luaţi în considerare şi faptul că valoarea buclei va rămâne şi după executarea buclei.


Aşadar, dacă scrieţi:

1for($i=0;$i<10;$i++)
2 echo $i;

valoarea $i va fi 10 după executare. De aceea, este cel mai bine să respectaţi anumite denumiri
standard ale variabilelor, pe care le veţi utiliza numai în acest scop. De exemplu, litera i. Astfel,
veţi şti mereu că această literă este rezervată pentru buclă şi nu o veţi utiliza pentru variabilele
curente. Fireşte, acest lucru este doar un sfat. Pentru denumirile variabilelor din bucle, sunt
valabile aceleaşi reguli ca pentru toate celelalte variabile din PHP.

Buclele for pot fi încorporate una într-alta. În practică, veţi vedea că programele mai mari sunt
alcătuite din bucle care se află în bucle mai mari, care la rândul lor se află în bucle şi mai mari.
Când veţi începe să creaţi singuri structuri mai complexe (cu bucle încorporate), aveţi grijă la
ordinea de executare a buclelor. Nu uitaţi că programul dvs., oricât de complex ar fi, este
executat secvenţial şi că, dacă în orice moment iniţiaţi un proces, toate celelalte procese vor fi
oprite până când procesul iniţiat este terminat (bineînţeles, această regulă nu este valabilă pentru
programarea în timp real şi pentru programarea multitasking):

1for($i=0;$i<10;$i++){
2 for($u=0;$u<10;$u++){
echo $u . "<br>";
3 }
4 echo "---$i<br>";
5}
6

Se poate observa destul de clar că acest exemplu va scrie variabila $u de 100 de ori. Dar cât va fi
acea variabilă $u la fiecare moment al executării?

Deoarece bucla $i este bucla externă, iar bucla $u este executată în interiorul ei, de fiecare dată
când se desfăşoară o iteraţie a buclei $i, va fi executat un ciclul complet al buclei $u:

prima iteratie a buclei $i


prima iteratie a buclei $u
a doua iteratie a buclei $u
...
a zecea iteratie a buclei $u
a doua iteratie a buclei $i
....

şi tot aşa, până la ultima iteraţie a buclei $i, când va fi terminat şi ciclul ei întreg.

La începutul lecţiei, am menţionat că counter-ul buclei este incrementat. Aceasta nu este o regulă
obligatorie. Counter-ul poate fi şi decrementat sau (cum am şi văzut într-un exemplu) nu trebuie
neapărat să existe:

1for($i=10;$i>0;$i--) echo $i;

Bucla foreach

Această buclă este o variaţie a buclei for, menită exclusiv pentru lucrul cu şiruri, în special cu
cele asociative. Tocmai acesta este şi motivul pentru care nu vom intra prea în detaliu în
descrierea acestei bucle, ci vom spune doar câteva cuvinte despre bazele funcţionării ei, deoarece
încă nu am studiat şirurile. Totuşi, într-unele din lecţiile anterioare am menţionat şirurile şi aici
trebuie să vă reamintim că şirurile sunt colecţii de date marcate prin indexuri. Indexarea
elementelor în şir începe cu zero. Iată un exemplu de şir care conţine 3 stringuri:

1$colors = array('red', 'yellow', 'green');

Această buclă are două forme. Una subînţelege gestionarea valorilor, iar cealaltă, gestionarea
cheilor şi a valorilor.

Foreach funcţionează foarte simplu (pentru utilizator), deoarece nu este necesar să ştim nimic
despre şirul prin care dorim să trecem, în afară de numele său. La iniţializare, introducem
numele şirului şi numele variabilei care dorim să preia valoarea actuală a şirului pe parcursul
fiecărei iteraţii. Sau, într-o altă formă, actualele valori ale cheii şi valorile propriu-zise.

Prima formă subînţelege:


foreach($array as $value){
bloc de instructiuni
}

În cazul primei forme, se trece prin şir şi, la fiecare iteraţie, valoarea elementului curent este
plasată în variabila $value/valoare. Apoi, în blocul de instrucţiuni se poate utiliza această
variabilă fără a schimba astfel valoarea conţinută în elementul curent al şirului.

Priviţi următorul exemplu:

1
$colors = "";
2$myArray = array('red','green','blue');
3
4echo "Colors contained in array: ";
5
6foreach($myArray as $value){
7 $colors .= $value . " ";
8echo}$colors;
9

La fiecare trecere prin buclă, valoarea elementului curent este atribuită variabilei $value. Această
valoare se scrie apoi în dreptul variabilei $colors, împreună cu un caracter gol. La final,
rezultatul va fi:

Colors contained in array: red green blue.

A doua formă a buclei foreach este:

1foreach (array as $indeks => $value){


2 bloc de instructiuni
3 }

Ea are aceeaşi funcţionalitate ca prima formă, cu diferenţa că valoarea elementului utilizează


valoarea indexului şi o plasează în variabila $index.

După cum vedeţi, foreach operează destul de automat. Acest lucru are uneori avantaje, dar uneori
are şi dezavantaje. Atunci când lucrăm cu foreach, nu gestionăm membrii şirului explicit prin
indexuri, ci doar obţinem valorile lor, astfel încât despre foreach se poate spune că este bună
atunci când dorim să executăm citirea rapidă şi simplă a unui şir, dar nu şi pentru executarea
unor intervenţii mai serioase asupra sa.

Deşi în exemplele de mai sus fiecare buclă foreach precede blocul din paranteze acolade, şi în
acest caz este valabilă regula că nu trebuie neapărat să existe paranteze acolade pentru o singură
linie de cod:

1foreach($arr as $key => $value) echo $value;


Controlul de flux al buclei

Controlul de flux al buclei se poate executa în câteva moduri. Primul mod este, bineînţeles, prin
modificarea manuală a variabilei de control (counter).

1for($i=0;$i<10;$i++){
2 if($i>5) $i=10;
3 echo $i . "<br>";
4 }

În acest exemplu, i-am transmis buclei să fie executată atâta timp cât variabila i este mai mică
decât zece cu increment 1. Iar apoi în bloc ne-am răzgândit şi i-am spus că, în cazul în care
counter-ul este mai mare decât 5 (deci 6), acesta să obţină valoarea 10. Deoarece counter-ul a
obţinut o valoare cu care bucla nu îndeplineşte condiţiile de executare, bucla este părăsită.
Această soluţie va funcţiona, dar este destul de inadecvată, deoarece în cazul respectiv trebuie să
cunoaştem valoarea-ţintă a counter-ului, fapt care va fi deseori imposibil (de ex.
for($i=0;$i<$u;$i++)).

Al doilea mod (cel corect) este utilizarea cuvântului-cheie break. Am întâlnit acest cuvânt şi în
lecţia precedentă, când am spus că acesta întrerupe necondiţionat executarea blocului de cod:

1for($i=0;$i<10;$i++)
2 {
3 if($i>5) break;
4 echo $i;
}
5

Prin utilizarea acestui cuvânt-cheie, bucla noastră nu pierde mult din dimensiune, dar în schimb
obţine dinamică, deoarece acum nu mai trebuie să ştim valoarea finală a buclei.

Comanda break poate avea şi un parametru. Dacă îl introducem, break va părăsi blocurile la
adâncimea marcată în parametru:

1
for($i=0;$i<10;$i++){
2 for($u=0;$u<10;$u++){
3 if($u==5)
4 break 2;
5 }
echo $i;
6}
7

Dacă pornim acest exemplu, nu va fi afişat nimic pe ecran, deşi instrucţiunea break se află în
bucla internă, de care nu avem nevoie pentru executarea buclei externe. Însă, fiindcă în
momentul îndeplinirii condiţiei $u=5 în bucla internă, bucla externă încă nu şi-a terminat nicio
iteraţie şi nu a ajuns să scrie mesajul pe ecran, iar fiindcă condiţia activează instrucţiunea break
şi are parametrul 2 (deci întrerupe la adâncimea de două blocuri), va întrerupe executarea buclei
proprii şi a buclei de deasupra ei.

Dar, uneori vom dori să punem o condiţie pe parcursul duratei buclei, prin care (când se
îndeplineşte) nu vom dori să facem iteraţia buclei. De exemplu, să ne imaginăm o listă imensă
de persoane (câteva milioane). Toţi aceşti oameni se află într-o bază de date şi noi avem nevoie
să selectăm un anumit grup în care să fie incluse numai cadrele didactice.

De exemplu, citirea datelor despre ocupaţia fiecărui membru al listei durează o secundă, iar
citirea datelor complete despre fiecare membru durează 5 secunde.

Să presupunem acum că procedura de citire subînţelege: citirea datelor despre profesie, adresa de
domiciliu, citirea prenumelui, citirea numelui (ceea ce în totalitate durează 5 secunde). Dacă vom
trece prin procedura completă pentru fiecare membru, vom pierde câte 5 secunde per membru,
ceea ce pentru toţi membrii înseamnă foarte multe secunde. Pe de altă parte, putem să ne uităm
de la început dacă membrul este cadru didactic (pentru care vom avea nevoie de numai o
secundă) şi, dacă nu este, să preluăm imediat datele următorului membru din listă şi astfel să
economisim 4 secunde. Pentru o listă de câteva milioane de membri, acesta este un număr
considerabil de secunde.

Acest exemplu simplu arată un mecanism care pentru persoane funcţionează în mod automat, dar
pentru ca programul să gândească astfel este necesar să accentuăm procedura în mod explicit.
Această accentuare se face prin cuvântul-cheie continue.

Pseudo-codul exemplului menţionat, prin utilizarea cuvântului-cheie continue, va arăta astfel:

for($membruLista = 0; $membruLista < 1000000; $membruLista ++)


{
if($membruLista != "cadruDidactic")
continue;
//COD IMENS CARE CITESTE RESTUL DATELOR DESPRE MEMBRUL LISTEI
//......
}
Tipul de date (pe care le cunoaştem), cu care este specializată pentru lucru bucla foreach, este:
array
integer
float
resource

Exerciţiul nr. 1

Trebuie să se creeze un program care va desena următoarea structură:


XXXXXXXXXX
XXXXXXXXXX

Acest desen trebuie să fie realizat prin intermediul buclei for.

De asemenea, prin variabile trebuie determinat câte semne X vor fi pe un rând şi câte semne X
va avea structura completă.

Ajutor:

În momentul emiterii în HTML, un nou rând se poate realiza cu următoarea instrucţiune:

echo "<br>";

Rezolvare:

1
2 <?php
$numElements = 20;
3 $rowEl = 10;
4
5 for($i=0;$i<$numElements;$i++)
6 {
7 if($i%$rowEl==0 && $i>0)
8 echo "<br/>";
echo "X";
9 }
10?>
11

Explicaţia rezolvării:

În primul rând, am creat variabile care conţin numărul total de elemente (numElements) şi
numărul de elemente de pe un rând (rowEl). După aceea, creăm bucla externă for, care va
executa câte o iteraţie pentru fiecare element. În cadrul acestei bucle, punem ramificarea
condiţionată if şi cercetăm dacă variabila $i, care reprezintă counter-ul, se poate împărţi cu
numărul de elemente de pe un rând. În afară de aceasta, cercetăm şi dacă $i este mai mare decât
0. Dacă toate aceste condiţii sunt îndeplinite, trebuie să trecem pe un rând nou, aşadar scriem
tagul html "<br/>". După această cercetare, începem scrierea elementului, respectiv a
caracterului "X".

Exerciţiul nr. 2

În aplicaţie, intră un anumit număr care se află în variabila $selectedNumber. Trebuie să se facă
o buclă care se execută de atâtea ori cât este valoarea variabilei $selectedNumber şi cu ocazia
fiecărei iteraţii creşte la exponentul egal cu numărul iteraţiei curente a buclei (primul circuit al
buclei ^1, al doilea circuit ^2...).

Ajutor:

PHP cunoaşte funcţia pentru exponent: pow(valoare, exponent)

Rezolvare:

1$selectedNumber = 20;
2for($i=1;$i<=$selectedNumber;$i++)
3 echo pow($selectedNumber,$i) . "<br>";

Folosind bucla for, asigurăm executarea codului prin câteva iteraţii. Deoarece variabila $i are rol
de counter, iteraţiile se vor executa până când valoarea pentru $i este mai mică sau egală cu
numărul definit cu variabila $selectedNumber, începând de la 1. Cum după linia:

1for($i=1;$i<=$selectedNumber;$i++)

nu este definit blocul de cod, la fel executarea următoarei linii va depinde de buclă. Prin setare,
se solicită ca numărul selectat în fiecare iteraţie să fie ridicat la exponentul care corepunde
numărului de iteraţie. Ca să ridicăm un număr la exponentul dorit, folosim funcţia pow().
Aceasta lucrează cu doi parametri obligatorii. Primul parametru este baza, iar al doilea
exponentul.

Exerciţiul nr. 3

Pe baza următoarelor variabile:

$a = 5;
$b = 8;

şi a buclelor încorporate, trebuie să se obţină următoarea ieşire:

012345678
100000008
200000008
300000008
412345678

Rezolvare:

1 <?php
2 $a = 5;
3 $b = 8;
4 for($i = 0; $i < $a; $i++)
5 {
6 echo $i;
for($u = 1; $u <= $b; $u ++)
7 {
8 if($u == $b || $i == 0 || $i == $a-1)
9 echo $u;
10 else
echo "0";
11 }
12 echo "<br>";
13 }
14?>
15
16

Dacă ne uităm cu atenţie la structura tabelului de numere care este dat în cerinţă, observăm că
acesta este alcătuit din 5 rânduri şi 9 coloane. Asta înseamnă că probabil vom avea nevoie de
două bucle. Numărarea iteraţiilor în bucle o putem începe de la orice număr vrem, aşadar bucla
for care va control prezentarea rândurilor o vom începe de la 0, iar bucla care se referă la
numărul de coloane o vom începe de la 1. Astfel, vom crea imediat două variabile, care vor
prezenta numărul de rânduri şi coloane în acord cu această logică pentru counter-ele buclei:

1$a = 5;
2$b = 8;

Numărul de rânduri se defineşte cu bucla care foloseşte variabila $i ca şi counter, iar


condiţionarea o face comparativ cu variabila $a. Deci, acum avem următorul cod:

1$a = 5;
2 $b = 8;
3 for($i = 0; $i < $a; $i++){}

Rămâne să rezolvăm structura corpului buclei. Cum pe primul loc de pe fiecare rând o să scriem
numărul care corespunde iteraţiei (aminitim că iteraţiile se numără cu variabila $i), imediat setăm
codul pentru această scriere:

1echo $i;

Acum, definim a doua buclă la care numerotarea începe de la 1 şi ţine până când counter-ul ($u)
este mai mic sau egal cu valoarea variabilei $b. După finalizarea acestei bucle, înseamnă că am
terminat cu acest rând şi acum trebuie să trecem la următorul, aşadar setăm BR tag.

Codul nostru arată astfel:

1$a = 5;
2$b = 8;
for($i = 0; $i < $a; $i++)
3{
4 echo $i;
5 for($u = 1; $u <= $b; $u ++){}
6 echo "<br>";
}
7
8

Fiecare iteraţie a buclei interne va avea drept scop scrierea unui caracter pe rând. Ca să
respectăm formularul modelului dat în problemă, trebuie să facem condiţionarea cu care se
stabileşte dacă pe pagină va fi prezentat numărul care corespunde counter-ului $u sau cifra 0.
Dacă valoarea counter-ului buclei interne corespunde cu valoarea variabilei $b, trebuie
prezentată valoarea acestui counter şi de aceea prima noastră verificare este:

1$u == $b

De asemenea, pe primul rând trebuie prezentate pe rând numerele de la 0 la 8, fapt care va avea
loc când se îndeplineşte următoarea condiţie:

1$i == 0

La final, trebuie verificat şi dacă $i == $a-1, pentru a stabili dacă este vorba de ultimul rând
(amintim că $a trebuie redus cu 1, deoarece începem numărarea de la 1, iar counter-ul $i începe
de la 0).

Cu aceasta exemplul nostru este finalizat.

Exerciţiul nr. 4

În aplicaţie, intră două variabile:

$numberOfCharacters = 50;
$characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

Trebuie creată o aplicaţie care generează parola pe baza setului de caractere atribuit şi a
numărului. Parola trebuie să conţină majuscule şi minuscule din lista de caractere $characters.
De asemenea, parola trebuie să aibă atâtea caractere câte sunt indicate în variabila
$numberOfCharacters.

Parola trebuie emisă la ieşire.

Rezolvare:

1<?php
2$numberOfCharacters = 50;
3$characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$allCharacters = $characters . strtolower($characters);
4$pass = "";
5for($i=0;$i<$numberOfCharacters;$i++)
6 $pass.=$allCharacters[rand(0,strlen($allCharacters)-1)];
7echo $pass;
8?>
9

Explicaţia rezolvării:

Creăm variabila cu care determinăm lungimea parolei pe care o vom genera


($numberOfCharacters). Apoi, creăm baza de caractere prin definirea variabilei $characters.
Deoarece valoarea acestei variabile este alcătuită doar din majuscule, trebuie să adăugăm şi toate
minusculele. Ca să nu scriem toate aceste caractere, folosim funcţia strtolower(), care converteşte
toate literele din string în minuscule, iar rezultatul funcţionării funcţiei îl alăturăm celorlalte
caractere, după care în sfârşit obţinem variabila $allCharacters. Următoarea parolă va fi inserată
în valoarea $pass, de aceea creăm această variabilă la început, ca un string gol. Trecând prin
bucla for, în fiecare iteraţie accesăm un caracter aleatoriu al stringului $allCharacters, lucru pe
care îl obţinem prin funcţia rand(). După ce bucla trece şi ultima iteraţie, începem afişarea
variabilei $pass.

Bucla while
Unitate: 8 din 19 00:22:43

+Rezumat

În PHP, bucla while reprezintă cea mai simplă buclă. La fel ca şi instrucţiunea if, pe care am
abordat-o în lecţiile precedente, şi bucla while depinde de condiţii. Trebuie să facem o paralelă
între while şi if. Pentru a şti care instrucţiune este mai corectă pentru a fi utilizată, începeţi de la
instrucţiunea care trebuie să se execute după îndeplinirea condiţiilor. Principala deosebire este
tocmai faptul că instrucţiunea if execută doar o singură dată blocul de instrucţiuni care urmează
după îndeplinirea condiţiilor, în timp ce bucla while execută instrucţiunile atâta timp cât condiţia
este îndeplinită.

Mai jos, puteți vedea o reprezentare grafică a funcţionării acestei bucle:


8.1 - Schema while

Bucla while intră în categoria în care trebuie cunoscut în prealabil numărul de iteraţii. Pur şi
simplu, această buclă se execută de atâtea ori câte îi permite condiţia care se execută în ea. Bucla
while necesită o anumită condiţie, care se introduce ca şi parametru în timpul iniţializări buclei şi
se execută până ce condiţia este îndeplinită. Pentru asigurarea executării codului în interiorul
buclei while, condiţia definită la începutul instrucţiunii while trebuie să fie îndeplinită. Condiţia
pe care o definim în timpul creării buclei while nu se deosebeşte deloc de condiţia pe care am
utilizat-o în timpul definirii instrucţiunilor if. Condiţia are un rol foarte important, deoarece
uneori trebuie să întrerupem executarea buclei ca să nu ne găsim în deja menţionata buclă
moartă.

Să vedem acum sintaxa:

while (conditie) {
//Blocul de cod care se va executa daca conditia nu este indeplinita
}

Să analizăm următorul exemplu:

1
<?php
2$number = 5;
3
4while ($number >= 2)
5{
6 echo $number . "<br/>";
7 $number -= 1;
}
8?>
9
Variabila $number primeşte la începutul codului valoarea 5. Apoi, este verificată condiţia
($number >= 2). Fiindcă această condiţie este îndeplinită, programul începe să execute blocul de
instrucţiuni din interiorul buclei while. În interiorul acestui bloc, se scrie numărul curent, care
apoi se micşorează cu 1. După prima trecere prin blocul de instrucţiuni, se verifică încă o
dată condiţia. Se va repeta executarea instrucţiunilor din interiorul buclei atâta timp cât condiţia
este corectă. După ieşirea din buclă, rezultatul va fi următorul:

5
4
3
2

Vedem că în iniţializarea buclei nu există incrementare ca în bucla for. De fapt, această buclă
nici nu trebuie să gestioneze vreun counter. Singurul lucru de care aceasta are nevoie este ca, la
fiecare iteraţie care urmează, valoarea condiţiei să fie corectă/true. Acest lucru poate fi o
problemă, pentru că va trebui să controlăm manual acest tip de buclă.

De exemplu, ce s-ar întâmpla dacă am omite din exemplul precedent această parte:

$number -= 1;

Bucla s-ar transforma în buclă moartă şi probabil ar bloca întreaga aplicaţie.

Bucla while se utilizează des în aplicaţii care operează în timp real. De exemplu, probabil nu
există niciun joc care să nu conţină în mecanismul său principal o astfel de buclă. Dar, spre
deosebire de jocuri şi alte programe în timp real, PHP nu are contact direct cu utilizatorul şi nu
este capabil să recunoască intrarea utilizatorului (apăsarea unei taste sau a mouse-ului), aşadar în
PHP utilizarea buclei while se reduce la o iteraţie simplă prin datele provenite de la o sursă,
parsarea acestor date şi altele. De exemplu, citirea fişierelor, atunci când este necesar să citim un
fişier linie cu linie, până când liniile se termină.

De aceea, este foarte important să avem permanent în buclă un mijloc de gestionare a buclei (pe
lângă instrucţiunile break şi continue). Şi, de aceea, această buclă acceptă exclusiv tipul Boolean
ca rezultat al expresiei condiţionate, deşi nici dacă este utilizată o altă scriere nu va fi semnalată
o eroare de sintaxă. De exemplu, următorul exemplu se va executa, dar este complet inutilizabil
şi duce la o buclă moartă:

while( 1 + 3 )
echo "se executa";

Bucla while se foloseşte, de obicei, când nu se ştie de dinainte cât va fi iteraţia (de câte ori
trebuie să se execute comanda stabilită). Când numărul ciclurilor este cunoscut, folosim
bucla for.

De asemenea, bucla while se poate încorpora (embed). Desigur, trebuie să aveţi un control
complet asupra codului pentru a nu omite ceva şi, bineînţeles, pentru a nu interveni erori după
executarea programului. Se recomandă să folosiţi paranteze acolade când faceţi încorporarea
codului. Instrucţiunile while (în acest caz) sunt scrise una într-alta cu condiţii de îndeplinire şi
instrucţiuni de executare.

Să vedem următorul exemplu:

1
2 $i = 0;
3 while ($i++ < 3){
4 echo "first <br/>";
while (1){
5 echo "second <br/>";
6 while (1){
7 echo "third <br/>";
8 continue 3;
}
9 echo "This line will never be executed.<br/>";
10 }
11echo "This line either.<br/>";
12}
13

După executarea programului, la ieşire vom obţine următorul rezultat:

first
second
third
first
second
third
first
second
third

Bucla while se poate împărţi în două tipuri: while şi do while. Este vorba de bucla care nu se
execută nici măcar o dată, în cazul în care condiţia nu este îndeplinită (while), şi de bucla care se
execută cel puţin o singură dată, chiar dacă condiţia nu este îndeplinită (do while). Am văzut deja
primul tip. Nimic din interiorul buclei din exemplul dat nu se va executa dacă variabila $number
nu este mai mare sau egală cu numărul doi.

Dar ce se întâmplă dacă vrem ca totuşi corpul să se execute cel puţin o singură dată?

Bucla do...while

Această buclă este similară cu cea precedentă, cu deosebirea că la bucla do...while condiţia se
verifică după executarea blocului de instrucţiuni, şi nu înainte. Aceasta înseamnă că blocul de
instrucţiuni din interiorul buclei do...while se va executa cel puţin o dată, indiferent dacă condiţia
este îndeplinită sau nu.

Do while ne asigură ca în primul rând să se execute blocul de instrucţiuni în cadrul instrucţiunii


do, iar apoi să se treacă prin condiţie. Următoarele executări ale instrucţiunilor, respectiv dacă
partea din blocul do se va executa din nou, depinde de condiţie.

Să analizăm următoarea reprezentare grafică:

8.2 - Schema do...while

Analizând schema, ajungem la concluzia că blocul de cod al buclei va fi oricum executat o dată.
Abia după executarea codului, urmează testarea condiţiei. Dacă condiţia nu este îndeplinită,
bucla se părăseşte, în timp ce, dacă condiţia este îndeplinită, blocul se va executa din nou, după
care urmează iarăşi testarea condiţiei. Un astfel de circuit continuă până ce condiţia este
îndeplinită sau până ce cu instrucţiunea break se părăseşte bucla do...while.

do{
//Bloc de cod
}while(conditia care se testeaza);

Codul care urmează mai jos este similar cu unul dintre conturile anterioare, însă de această dată
blocul de cod se execută o singură dată, indiferent de condiţie. Abia pentru fiecare iteraţie care
urmează se execută verificarea condiţiei:

1$number = 5;
2do{
3 echo $number . "<br/>";
4 $number -= 1;
5 }
while($number >= 2);
6

În bucla while, sunt valabile aceleaşi reguli de sintaxă ca şi în celelalte structuri de flux: break,
continue şi regula de punere obligatorie între paranteze acolade, dacă blocul este mai lung decât
o singură linie.
Toate acestea sunt valabile şi pentru do while. Dar fiţi atenţi la scrierea fără paranteze acolade
pentru că, deşi pare că blocul este mărginit de structură (ca în cazurile switch-case), în bucla do
while nu numai că nu se va executa mai mult de o singură linie în interiorul buclei (fără
paranteze acolade), ci se va produce şi o eroare.

Acest cod se va executa fără probleme:

1$a = 5;
2do
3echo $a ++;
4while( $a < 5 );

Dar acest cod va semnala o eroare:

1$a = 5;
2do
3echo $a ++;
4echo "This line occurs error";
5while( $a < 5);

Observaţi şi faptul că în faţa instrucţiunii do nu există semnul ; , dar acest semn este obligatoriu
după linia care conţine instrucţiunea while (ultima linie).

Exerciţiul nr. 1

Se dă următorul cod:

$html = <<<HTML
<div style="#S#"> #I# </div>
HTML;
$divNum = 10;
$style = "border: 1px solid black; background: yellow; margin: 5px; padding:
4px;";

Cu ajutorul buclei, trebuie scris codul care va afişa codul html în variabila $html cel puţin o dată,
în timp ce numărul maxim de ori trebuie menţionat în variabila $divNum.

Cu ocazia fiecărei iteraţii, în tagul div în loc de semnul #I# va fi numărul iteraţiei, în timp ce în
loc de semnul #S# trebuie să fie stilizarea specificată în variabila $style.

Rezolvare:

1 <?php
2 $html = <<<HTML
3 <div style="#S#"> #I# </div>
4 HTML;
$divNum = 10;
5
6 $style = "border: 1px solid black; background: yellow; margin: 5px;
7 padding: 4px;";
8
$html = str_replace("#S#", $style, $html);
9 $i = 0;
10do
11 {
12 echo str_replace("#I#", $i, $html);
$i++;
13 } while ($i < $divNum);
14?>
15

Ca valoare a variabilei, definim stringul creat cu ajutorul sintaxei heredoc şi marcăm părţile care
vor fi modificare prin restul codului (#S# şi #I#). Următoarea variabilă este $divNum, care
reprezintă numărul de elemente DIV care vor fi create. Mai rămâne să creăm încă o
variabilă ($style), cu care definim stilizarea.

Deoarece trebuie făcută editarea stringului sub formă de schimb de semn cu stilizarea pregătită
anterior, folosim funcţia str_replace(). Primul parametru al funcţiei este stringul, care va fi
căutat. Al doilea parametru este stringul care îl va înlocui pe cel găsit, iar cu al treilea parametru
determinăm stringul unde se va face căutarea. Această funcţie poate avea şi al patrulea
parametru, opţional, cu care stabilim numărul maxim de astfel de schimbări.

Cu linia:

1$html = str_replace("#S#", $style, $html);

am rezolvat modificarea referitoare la stilizarea elementului. După asta setăm variabila $i care
iniţial are valoarea 0. Ca să fie scris cel puţin o dată tagul DIV, alegem bucla do-while.

În cadrul corpului acestei buclei, scriem elementul DIV pe pagină în felul următor:

1echo str_replace("#I#", $i, $html);

După cum putem observa, şi aici modificăm stringul ca la fiecare DIV tag să-i adăugăm
conţinutul care corespunde counter-ului iteraţiei ($i).

Ca să nu intrăm în bucla moartă, facem incrementarea counter-ului $i++.

Condiţia pentru executarea iteraţiilor este ca $i să fie mai mic decât numărul de taguri DIV, pe
care l-am determinat cu variabila $divNum, setând astfel condiţia:

$i < $divNum<br><br><span style="font-size: 14px; text-align:


1 justify;"> </span>
Notă:
În exemplu (pentru a fi realizat cu succes) apar şi elemente care încă nu au
fost abordate în această parte a cursului. Puteţi sări peste acestea şi să
aşteptaţi să fie explicate în lecţie sau vă puteţi informa pe scurt despre ele
în următoarele rânduri:

Semnele <<<HTML şi HTML; sunt partea heredoc string a sintaxei.


Aceasta permite ca stringul să fie scris şi salvat în forma originală, inclusiv
noile rânduri şi celelalte formatări. Aici am folosit această sintaxă pentru a
memora stringul cu tagul div.

Funcţia str_replace schimbă conţinutul stringului. Aceasta are trei


parametri. Primul este stringul căutat (în exemplu, sunt #S# şi #I#), al
doilea parametru este stringul cu care va fi înlocuit stringul găsit, iar al
treilea parametru este stringul pe care va fi executată intervenţia.

Exerciţiul nr. 2

Trebuie scris un program care va aduna numerele de la 1 la 10 şi va scrie sumele după fiecare
adunare a numărului cu suma, iar la final va scrie suma tuturor sumelor (Total) din perioada
precedentă a adunării. Trebuie să se folosească bucla do...while. După executare, programul
trebuie să scrie următorul conţinut:

0 + 1 este egal cu : 1
1 + 2 este egal cu : 3
3 + 3 este egal cu : 6
6 + 4 este egal cu : 10
10 + 5 este egal cu : 15
15 + 6 este egal cu : 21
21 + 7 este egal cu : 28
28 + 8 este egal cu : 36
36 + 9 este egal cu : 45
45 + 10 este egal cu : 55

Suma, respectiv totalul tuturor numerelor de la 1 la 10 este: 55

Rezolvare:

1 <?php
2
3 $amount = 0;
$number = 0;
4
5 do
6 {
7 $number ++;
8 echo $amount. " + ". $number. " este egal cu : ";
9 $amount = $amount + $number;
echo $amount. "<br />";
10
11 }
12 while ( $number!= 10 );
13
14 echo "<br />";
15 echo "Amount all numbers: ". $amount;
16
17?>
18
19

Esenţa logicii acestei probleme va fi finalizată în corpul buclei, aşadar la început vom crea
variabile de lucru şi le vom aloca valori, apoi vom crea bucla do-while şi la final prezentăm
sumele acestor valori. După asta, codul nostru va arăta astfel:

1$amount = 0;
2 $number = 0;
3
4 do{
5 }while ( $number!= 10 );
6
7 echo "<br />";
echo "Amount all numbers: ". $amount;
8

Acum, trebuie creat codul care se va afla în corpul buclei. În primul rând, vom face
incrementarea counter-ului, ca să nu intrăm în bucla moartă şi ca de fiecare dată să mărim
valoarea variabilei $number cu 1, ca să o folosim în continuare ca atare.

După asta, pe pagină prezentăm expresia care va fi calculată:

1echo $amount. " + ". $number. " este egal cu : ";

Imediat după asta se calculează această expresie şi o prezentăm utilizatorului:

1$amount = $amount + $number;


2echo $amount. "<br />";

Cu aceasta problema noastră este rezolvată.

Exerciţiul nr. 3

Trebuie să se facă un tabel ca în imaginea de mai jos. Programul trebuie să calculeze paşii
preţurilor, comparativ cu »Cantitate * Preţ« în funcţie de paşii de modificare a cantităţilor.
Valoarea iniţială este 10 şi merge până la 100, cu pasul de mărire cu 10. Suportul pentru
formatarea tabelului (codul HTML) se află în partea marcată cu roşu a rezolvării:

Cantitate Preţ
10 50
20 100
30 150
40 200
50 250
60 300
70 350
80 400
90 450
100 500

Rezolvare:

<?php
$price = 5;
$counter= 10;
echo "<table border = \"1\" align = \"center\" >";
echo "<tr><th> Quantity </th>";
echo "<th>Price </th></tr>";
while ( $counter<= 100 ) {
echo "<tr> <td>";
echo $counter;
echo "</td> <td>";
echo $price * $counter;
echo "</td> </tr>";
$counter = $counter + 10;
}
echo "</table>";
?>

Codul care prezintă soluţia problemelor, după structura sa, este foarte similar cu cel precedent,
aşadar nu ve vom opri prea mult asupra detaliilor, pe care deja le cunoaştem. Trebuie menţionat
că evitarea caracterelor speciale în string se face cu semnul (\). În cadrul buclei while, pentru
fiecare iteraţie prezentăm valoarea pentru $counter, precum şi valoarea pentru $counter * $price.
Stabilirea paşilor se face în ultima linie a codului pentru corpul buclei while:

1$counter = $counter + 10;


Exerciţiul nr. 4

Trebuie scris un program care, prin specificarea numărului dorit (atribuirea valorii variabilei
înainte de bucla while), la ieşire va scrie toate numerele din intervalul mai mare decât 200 şi mai
mic decât 400, dacă numărul dorit se află în intervalul prevăzut. Folosiţi bucla while.

De exemplu, dacă valoarea numărului dorit este egală cu 380, rezultatul va fi:

Number: 380
Number: 381
Number: 382
Number: 383
Number: 384
Number: 385
Number: 386
Number: 387
Number: 388
Number: 389
Number: 390
Number: 391
Number: 392
Number: 393
Number: 394
Number: 395
Number: 396
Number: 397
Number: 398
Number: 399

Rezolvare:

1
<?php
2$number = 380;
3do{
4 echo "Number: $number <br>";
5 $number++;
}while($number > 200 && $number < 400);
6?>
7

Urmărind cererile problemei şi ţinând cont să nu intrăm în bucla care se execută încontinuu,
creăm codul următor:

1$number = 380;
2do{
3 echo "Number: $number <br>";
4 $number++;
}while);
5
Rămâne cererea pentru definirea condiţiei, de care va depinde repetarea blocului de cod al buclei.
După cum este menţionat în cerinţa problemei, numerele trebuie să fie mai mari de 200 şi mai
mici de 400, aşadar definim următoarea expresie:

1$number > 200 && $number < 400

Exerciţiul nr. 5

Trebuie scris un program pentru vânzarea prin licitaţie, care va începe să se execute după
obţinerea valorii iniţiale (preţ), atribuind valoarea variabilei înainte de intrarea în buclă.
Programul scrie valorile mărindu-le cu unu şi publică anunţul cu privire la acceptarea articolului
pentru vânzare. Când preţul atinge o valoare peste 1000, statusul articolului este informaţia
despre posibilitatea vânzării. De exemplu, rezultatul la ieşire (dacă valoarea iniţială este setată la
999) poate arăta astfel:

Current price: 999. Still not for sale.


Current price: 1000. Still not for sale.
Current price: 1001. YOU CAN START WITH SALE !

Rezolvare:

1
<?php
2 $price = 999;
3
4 do{
5 echo "Current price: " . $price . " Still not for sale. </br>";
6 $price = $price + 1;
7 }while($price <= 1000);
8
echo "Current price: " . $price . " YOU CAN START WITH SALE !";
9 ?>
10

Rezolvarea problemei reprezintă un exemplu clasic de folosire a buclei do...while. În primul


rând, este creată variabila care se prezintă prin corpul buclei pe document şi se măreşte cu 1.
Întreaga buclă este supusă condiţiei aşteptate:

1$price <= 1000

În momentul în care variabila $price se schimbă astfel încât condiţia nu mai este îndeplinită, se
părăseşte bucla şi se execută ultima linie de cod:

1echo "Current price: " . $price . " YOU CAN START WITH SALE !";
Exerciţiul nr. 6

Trebuie scris un program care pentru temperatura stabilită va face o conversie din grade Celsius
(C) în Kelvin (K) şi Fahrenhait (F). Trebuie să se rezolve problema în cadrul buclei while, iar
condiţia pentru executarea instrucţiunii este ca temperatura stabilită să fie mai mică de 115
grade.

Rezolvare:

1
2 <?php
3 $ctemp = -10;
while ($ctemp < 115) {
4 print ("$ctemp degrees C converts to ");
5 print (32 + $ctemp / 5 * 9 );
6 print (" degrees F and to ");
7 print ($ctemp + 273.1 );
print (" degrees K<BR>");
8 $ctemp = $ctemp + 20;
9 }
10?>
11

Valoarea iniţială a variabilei $ctemp este -10. Prin bucla while se face convertirea gradelor
Celsius în Fahrenhait şi Kelvin. Pentru convertirea gradelor Celsius în Fahrenhait, folosim
formula:
32 + $ctemp / 5 * 9

în timp ce pentru convertirea gradelor Celsius în Kelvin, folosim formula:

1$ctemp + 273.1

La final, trebuie să stabilim un pas după care se va schimba variabila $ctemp. Ca să nu avem
prea multe rezultate pe pagină, setăm:

1$ctemp = $ctemp + 20;

În raport cu instrucţiunea if, bucla while se foloseşte:


când blocul de instrucţiuni trebuie executat de mai multe ori
când blocul de instrucţiuni trebuie executat doar o singură dată
niciodată nu se foloseşte bucla while, ci întotdeauna se foloseşte doar condiţia if
……………………………..

Modul 3 Funcţiile
Includerea fişierelor
Unitate: 9 din 19 00:13:19

+Rezumat

În această lecţie, vom lucra cu fişiere şi vom vedea cum putem include un fişier într-altul.
Utilizarea unui cod deja scris este o opţiune foarte utilă şi frecvent folosită în programare. De
exemplu, dacă un site web conţine un meniu care se repetă pe fiecare pagină, atunci este mult
mai simplu să scriem codul o dată şi apoi să-l includem în mod dinamic în paginile în care
trebuie să apară, decât să scriem codul în cadrul fiecărei pagini separat. Acest lucru este posibil
prin introducerea fişierelor din partea serverului.

Deşi în continuare vom aborda în total 4 funcţii al căror scop este includerea fişierelor, putem
spune că două dintre ele sunt de bază. Acestea sunt:

 include()
 require()

Aceste funcţii pot include conţinutul fişierului extern în codul de pe care sunt apelate, înainte de
începerea executării codului respectiv. Sunt foarte importante, deoarece se folosesc pentru
includerea aceluiaşi conţinut pe un număr mai mare de pagini (header, footer, segmente ale
paginii şi altele).

Fişierele care se includ conţin, de obicei, codul HTML sau PHP şi se salvează cu extensia .inc,
deşi pot fi salvate şi cu alte extensii. Conţinutul unor astfel de fişiere se codează o dată şi apoi
este apelat de către paginile care-l necesită. Dacă se fac modificări în fişierul original, acestea
vor fi vizibile pe toate paginile în care acesta se utilizează.

De exemplu, se întâmplă ca toate paginile unui site web să trebuiască să aibă în partea de
sus acelaşi header. Codul HTML al header-ului va fi:

1<div style = "border: ridge 1px; width: 95%; background-color: #F0F0F0;


padding: 5px" >
2<h3> Welcome to our site! </h3>
3</div>

Acest cod se poate salva în cadrul fişierului denumit header.inc. După crearea fişierului header,
este necesar ca acesta să fie inclus în fiecare pagină pe care trebuie afişat. Aceasta se face prin
instrucţiunile de includere a fişierelor externe:
1<?php
2require('header.inc');
3echo "<p> Some text..... </p>";
4?>

Dacă fişierele care sunt incluse conţin anumite informaţii confidenţiale, atunci acestea ar trebui
să fie salvate cu extensia .php, astfel încât utilizatorii să nu poată vedea conţinutul original, ci
doar codul HTML care este rezultatul executării codului.

După cum vedeţi, fişierul care este importat nu este limitat din punct de vedere al limbajului (în
exemplul de mai sus, este un fişier html) şi poate fi scris în orice alt limbaj (atâta timp cât se
respectă sintaxa).

Funcţia require nu este singura funcţie care poate să includă un fişier extern în scriptul PHP
actual. De fapt, există patru funcţii care pot face acest lucru, iar fiecare dintre ele are
caracteristicile sale.

Require

Funcţia require() apelează fişierul header.inc şi citeşte conţinutul lui. Acest conţinut va
fi afişat apoi ca parte a paginii de pe care a fost apelat. De exemplu, dacă avem un fişier PHP cu
următorul conţinut şi denumim fişierul myFile.php:

1<?php
2 echo "Hi!";
3?>

iar apoi mai creăm încă un fişier cu următorul conţinut:

1<?php
2require "myFile.php";
3?>

Dacă pornim acest fişier, acesta va afişa pe pagină următorul mesaj: Hi!, pentru că în el are
implementat conţinutul celuilalt fişier.

Trebuie să aveţi grijă atunci când implementaţi fişierul în acest mod, deoarece nu se
implementează conţinutul lui de ieşire, ci conţinutul lui sursă.

Aceasta înseamnă următorul lucru:

Fişierul myFile.php din exemplul de mai sus, dacă este pornit separat, va emite mesajul Hi!.
Aceasta va fi singura sa ieşire, pentru că aceasta este ceea ce emite interpreterul PHP. Dar, dacă
implementăm acest fişier într-un alt fişier PHP, cu ajutorul funcţiilor de implementare, în el va
intra codul său sursă PHP, acesta fiind echo "Hi";.
Dacă, de exemplu, am pune în conţinutul fişierului myFile.php următorul cod:

1<?php
2$a = "my variable";
3?>

şi am emite acest fişier direct în browser, pagina ar rămâne goală.

Dar, dacă includem acest fişier în codul PHP deja existent şi dacă cerem variabila $a, aceasta va
produce un rezultat corespunzător:

1<?php
2require "myFile.php";
3echo $a;
4?>

Exemplu:

Așa cum am menţionat deja, esența programării este ca fiecare cod să se scrie doar o singură
dată. În ceea ce priveşte crearea paginilor web, întotdeauna vor fi necesare părţile header și
footer, care se recomandă să fie la fel pe toate paginile. O astfel de formatare a paginilor o
obținem cu ajutorul următorului cod și utilizând funcția require:

1<?php require ('header.php'); ?>


2
3... content of page ....
4
5<?php require ('footer.php'); ?>

Cu acest mod de lucru, chiar dacă am scris un număr mare de pagini, avem posibilitatea să
modificăm header-ele și footer-ele lor doar într-un singur loc, iar conținutul va fi reprodus pe
toate paginile.

În cadrul acestui exemplu se utilizează, în general, o combinație de instrucţiuni HTML și PHP


care generează părțile dinamice ale paginii. Dacă trebuie să procesaţi conţinutul fişierelor ca un
text simplu, fără executarea codului php, o alternativă este funcția care doar încarcă conținutul
fișierului fără o analiză sintactică. Funcţia aceasta este readfile().

Include

Dacă conţinutul paginii depinde de conţinutul fişierului importat (de exemplu, în el se află nişte
variabile esenţiale), atunci puteţi utiliza funcţia require, pentru că ea va întrerupe executarea
programului dacă din diverse motive fişierul nu este inclus în codul existent.
Dar, dacă acest conţinut nu este foarte important (de exemplu, fişierul pe care îl includeţi este un
cititor de ştiri, care afişează ştirile într-un loc mai puţin important al paginii), puteţi utiliza
funcţia include. Sintaxa ei este similară cu cea pentru require, însă dacă încărcarea nu este
reuşită, executarea scriptului va continua.

Cel mai bine este să mascaţi funcţia include printr-un operator de tip error suppressor, pentru ca
problema să nu deranjeze definiţia aspectului paginii la încărcare:

1@include "myFile.php";

Include_once şi require_once()

Imaginaţi-vă următoarea situaţie:

1require( "myFile.php" );
2echo $a;
3$a = "some other value: ";
4require( "myFile.php" );
5echo $a;

Dacă folosim conţinutul fişierului myFile.php de mai sus, atunci acest program va emite de două
ori textul my variabile, ceea ce probabil nu este de dorit, pentru că în cursul codului am schimbat
valoarea variabilei.

Pentru a nu se întâmpla aşa ceva, vom utiliza instrucţiunea include_once şi funcţia


require_once.

Când PHP ajunge la funcţia require_once sau include_once, acesta va verifica dacă există deja
implementarea fişierului cu acest nume şi, dacă există, nu va executa o altă includere.

Ţineţi minte că, spre deosebire de instrucţiunea include, require nu returnează niciun rezultat,
fiindcă aceasta întrerupe momentan executarea programului. Asta înseamnă că următoarea
expresie nu va funcţiona:

1require( "nonexistentFile.php" ) or die( "no file" );

Dacă doriţi ca aşa ceva să funcţioneze, atunci poate ar fi bine să utilizaţi un mecanism diferit:

1if( !@include_once "nonexistentFile.php" )


2 echo "no file";

Sau puteţi verifica existenţa fişierului, iar apoi în funcţie de această verificare să executaţi
acţiunea care urmează:

1$file = "nonexistentFile.php";
2if( file_exists($file)){
3 require_once ( $file );
}else{
4 echo "file do not exist";
5}
6

Opţiunile auto_prepend_file şi auto_append_file

Există încă o modalitate ca pe fiecare pagină să adăugaţi un header și un footer, fără a fi nevoie
să utilizaţi instrucţiunile require() și include. Fişierul php.ini, printre altele, are şi două opțiuni de
configurare, auto_prepend_file şi auto_append_file. Dacă setați aceste opțiuni pentru a indica
header-ele şi footer-ele pe fişierele dvs., acestea se vor încărca la începutul și la sfârșitul fiecărei
pagini. Fișierele pe care le adăugați în acest mod se comportă ca şi când le-aţi adăugat utilizând
instrucţiunile require() și include(), ceea ce înseamnă că, dacă fișierul nu este disponibil, se va
semnala o eroare.

În Windows, aceste opţiuni sunt date în felul următor:

auto_prepend_file = "c:/path/to/files/header.php"
auto_append_file = "c:/path/to/files/footer.php"

Prin acest proces de includere a fişierelor fără a utiliza instrucţiunea include(), permiteţi
includerea fișierelor pe fiecare dintre paginile dvs., dar, în același timp, vă şi angajaţi că fiecare
pagină va avea un header și un footer. Ce înseamnă asta? Opțiunile pe care le-am explicat vă
impun fișiere incluse pe toate paginile, ceea ce reprezintă o problemă atunci când doriți să aveți o
pagină independentă, fără header și footer.

Utilizatorii serverului web Apache au posibilitatea să schimbe diferite opțiuni de configurare, în


acelaşi mod ca și directoarele individuale. Serverul trebuie să fie configurat în aşa fel încât să
permită redefinirea fişierelor de configurare. Pentru a defini header-ul şi footer-ul automat pentru
un anumit director, trebuie să creați în acel director extensia .htaccess și, într-un fişier astfel
creat, să scrieţi următorul conţinut:

php_value auto_prepend_file "path/to/files/header.php"


php_value auto_append_file "path/to/files/ footer.php"

Definirea diferitelor opțiuni în fişierul .htaccess în loc de fișierul php.ini sau în fişierul de
configurare a serverului web vă oferă o mare flexibilitate în timpul lucrului. Opțiunile de
configurare, care se setează într-un mediu multi-utilizator, se pot seta astfel încât să se aplice
numai în directorul fiecărui utilizator în parte. Totuşi, la fel ca orice altă metodă, şi aceasta are
dezavantaje. O problemă concretă apare atunci când utilizatorul încearcă să încarce un fișier
oarecare din acel director, și nu doar o dată, la început, ceea ce ne indică o încetinire a executării
programului.

Exerciţiul nr. 1
În aplicaţie, intră următoarele variabile:

$file = "test";
$validExtension = "php";

Trebuie scris un astfel de cod care, pe baza numelui fișierului și a extensiei permise, încarcă un
anumit fişier cu instrucţiunea include.

Rezolvare:

1
2 <?php
3 $file = "test";
4 $validExtension = "php";
5 switch( $validExtension )
{
6 case "php":
7 include $file . ".php";
8 break;
9 case "html":
10 include $file . ".html";
break;
11 case "js":
12 include $file . ".js";
13 break;
14 }
15?>
16

Variabilele $file şi $validExtension sunt stringuri. Prima variabilă reprezintă numele fişierului, în
timp ce a doua este string, care reprezintă extensia. Folosind switch, verificăm dacă extensia
menţionată este validă, respectiv dacă corespunde. În momentul în care extensia se suprapune cu
valoarea pentru case, se execută toate liniile codului până la break şi tocmai de aceea includem
aici fişierul. Ca să includem fişierul extern, trebuie să definim calea până la fişierul respectiv.
Atunci când fişierul, pe care vrem să-l includem, se află în acelaşi folder în care se află şi fişierul
pentru care scriem codul, practic calea este însuşi numele fişierului cu extensie.

Care este diferenţa dintre instrucţiunea/funcţia require şi include?


În require, dacă apare o eroare și fișierul nu poate fi încărcat dintr-un motiv oarecare,
programul întrerupe executarea și se produce o eroare, în timp ce în include nu este cazul.
În include, dacă apare o eroare și fișierul nu poate fi încărcat dintr-un motiv oarecare,
programul întrerupe executarea și se produce o eroare, în timp ce în require nu este cazul, căci
scriptul continuă pur și simplu executarea în pofida erorii.

Funcţiile
Unitate: 10 din 19 00:21:14

+Rezumat

În cadrul acestei lecţii, ne vom familiariza cu noţiunea de funcţii în PHP. Până acum, deşi nu am
abordat în mod explicit această noţiune, am întâlnit destule funcţii în PHP. De fapt, majoritatea
instrucţiunilor executate până acum au fost funcţii.

După următoarea descriere, vom recunoaşte cu uşurinţă momentele când am utilizat funcţiile în
lucrul nostru de până acum, prin formele lor caracteristice.

Mai întâi, să clarificăm ce este o funcţie. Funcţia este o structură de program care este capabilă
să execute o operaţiune pe baza unor parametri primiţi sau fără aceştia şi să returneze un rezultat
după completarea operaţiunii.

Într-adevăr, există multe motive pentru care funcţiile sunt utilizate în programare. Dar avantajele
caracteristicilor funcţiilor sunt:

 încapsularea;
 reducerea redundanţei codului;
 viteza de codare;
 portabilitatea.

Funcţiile au un rol important în programarea modernă orientată pe obiect, deoarece


funcţionalitatea claselor (care sunt baza programării orientate pe obiect) este localizată exact în
metodele acestor clase. Metodele claselor sunt, după cum veţi vedea în curând, nişte simple
funcţii. Însă, funcţiile sunt un instrument foarte des utilizat independent de OOP (Object
Oriented Programming).

Apare foarte frecvent nevoia de utilizare repetată a aceluiaşi bloc de cod în cadrul unui program.
Dacă funcţiile n-ar exista, acest cod ar trebui, în cel mai bun caz, copiat în fiecare loc unde avem
nevoie de el.

De exemplu, într-un cod vom scrie în mai multe locuri acelaşi text. De exemplu, steluţele din
exemplul următor:

<?php
echo "**********************************************";
echo "<br> title <br>";
echo "**********************************************";
echo "<br> Some text <br>";
echo "**********************************************";
?>

Este evident că partea care desenează steluţele se repetă de trei ori, însă în programare există o
regulă care susţine că acelaşi cod nu ar trebui să se repete.
Respectând această regulă, ajungem la concluzia că trebuie să rezolvăm problema repetării
steluţelor din codul de mai sus, iar cel mai eficient mod de a face acest lucru este prin utilizarea
funcţiei.

Astfel, dacă vom utiliza funcţia, versiunea codului de mai sus va arăta astfel:

1
2 // creating function stars
function stars(){
3 echo "**********************************************<br>";
4 }
5
6 //calling function stars
7 stars();
8 echo "title <br>";
//calling function stars
9 stars();
10echo "Some text";
11

În codul precedent, distingem două unităţi: una este definirea funcţiei, iar cealaltă, apelarea
funcţiei.

Când este vorba despre definirea funcţiei, în PHP trebuie respectate nişte reguli. Mai întâi,
funcţia trebuie să înceapă cu cuvântul-cheie function. Apoi, trebuie să aibă un nume, pentru
notaţia căruia sunt valabile aceleaşi reguli ca pentru variabile (exceptând semnul $ din faţa
numelui). După nume, în paranteze rotunde trebuie accentuată acceptarea parametrilor (prin lista
variabilelor separate prin virgule). Aceste paranteze pot fi lăsate goale dacă funcţia nu primeşte
parametri. Şi, într-un final, vom avea corpul funcţiei, respectiv codul pe care funcţia îl va
executa şi care trebuie pus între paranteze acolade, imediat după primirea parametrilor:

function myFunction($parameter1, $parameter2){


echo "this is the body";
}

Această abordare, nu numai că face posibilă reducerea dimensiunii codului, dar duce şi la
centralizarea codului, respectiv la manipularea simplificată a diverselor mecanisme care în cod
se execută prin funcţii.

Să presupunem că exemplul cu steluţele nu a demonstrat încă adevăratele avantaje ale funcţiilor


şi că este mai uşor dacă acest rând este copiat de mai multe ori. Dar să presupunem că ne dorim
ca ieşirea noastră cu steluţele să aibă un conţinut dinamic. De exemplu:

*********************** Belgrade *************************


Text about Belgrade
*********************** Paris ****************************
Text about Paris
*********************** London **************************
Text about London
În acest caz, pe lângă copierea steluţelor, ar mai trebui ca pe fiecare rând să scriem numele
oraşului, să ştergem şi să adăugăm steluţe la sfârşitul rândului, pentru a le alinia.

Codul ar arăta astfel:

<?php
1echo "************************************ Belgrade
2**************************************";
3echo "<br>Text about Belgrade<br>";
4echo "************************************* Paris
****************************************";
5echo "<br>Text about Paris<br>";
6echo "************************************* London
7**************************************";
8echo "<br>Text about London<br>";
?>

Folosind funcţia, acest cod s-ar putea rezolva astfel:

1
2 <?php
3 function stars( $cityName )
4 {
5 for( $i=0; $i<35; $i++ )
echo "*";
6 echo " " . $cityName . " ";
7 for( $x= ( $i + 2 ) + strlen ( $cityName ); $x < 90; $x++ )
8 echo "*";
9 }
10
11stars( "Belgrade" );
echo "< br > Text about Belgrade < br >";
12stars( "Paris" );
13echo "< br > Text about Paris < br >";
14stars( "London" );
15echo "< br > Text about London < br >";
16?><span style="font-size: 15.4px; text-align: justify;"> </span>
17

În cazul celor 3 oraşe, câte avem în exemplu, ne vom întreba care este scopul unei astfel de
funcţii. Dar după alte câteva oraşe, codul s-ar multiplica dacă nu ar exista această funcţie.

Mai mult, să presupunem că ne-am dori la un moment dat să reducem numărul steluţelor care
mărginesc numele oraşului.

În această funcţie, ar trebui schimbate doar două valori pentru acest lucru, în timp ce, fără
funcţie, ar trebui schimbat tot codul, de atâtea ori câte oraşe sunt.
Tipurile de funcţii

Ceea ce mai este interesant în exemplul precedent este că în cadrul funcţiei stars() mai apelăm
încă o funcţie, strlen(), care returnează lungimea unui string. În cazul nostru, acesta este numele
oraşului. Funcţia strlen() nu este o funcţie pe care o scriem manual, ci este implementată în PHP
ca parte constitutivă a acestuia, de unde ajungem la concluzia că PHP are două tipuri de funcţii,
cele definite de utilizator şi cele interne, predefinite (încorporate), care sunt parte a limbajului
PHP.

Funcţiile definite de utilizator sunt cele pe care le creăm singuri (precum funcţia stars), prin
utilizarea cuvântului-cheie function, ca în exemplul precedent şi în cel următor:

1function add($num1,$num2){
2 return $num1 + $num2;
3 }

Funcţia pe care tocmai am scris-o acceptă doi parametri şi adună valorile acestora. După aceea,
cu ajutorul instrucţiunii return, funcţia returnează rezultatul obţinut în locul de apelare.

O funcţie poate fi scrisă oriunde în cod, dar practica obişnuită este ca toate funcţiile să fie scrise
la începutul codului, înainte de celelalte instrucţiuni. De asemenea, o funcţie poate fi scrisă şi
într-un fişier separat. În cazul din urmă, va trebui să includem acest fişier în toate paginile care
vor folosi funcţiile sale.

Funcţiile pot fi apelate din orice parte a codului PHP. După apelarea funcţiei, aceasta preia
parametrii expediaţi (dacă aceştia există), apoi execută anumite instrucţiuni şi returnează
valoarea obţinută către program:

1function add($num1, $num2){


2 return $num1 + $num2;
3}
4echo "The sum of 5 and 2 is " . add(5, 2);

În exemplul de mai sus, funcţia este mai întâi definită, iar mai apoi este apelată în cadrul
instrucţiunii echo. Pentru apelarea funcţiei, sunt expediate către aceasta valorile true ale
parametrilor (5 şi 2). Funcţia preia aceste valori, le pune în variabilele $num1 şi $num2, execută
operaţia dată (le adună) şi returnează valoarea obţinută către instrucţiunea echo.

Este posibilă şi crearea funcţiei, care poate (dar nu trebuie neapărat) să primească parametri fără
ca o eroare să fie produsă. În acest scop, sunt setate valorile default ale parametrilor:

1function add($num1 = 3, $num2 = 4){


2 return $num1 + $num2;
3}
4echo "Result is " . add();
Variabilele care se utilizează în interiorul corpului funcţiei se numesc variabile locale. Acestea
nu pot fi accesate din afara funcţiei. Dacă, totuşi, trebuie să accesăm aceeaşi variabilă atât din
corpul funcţiei, cât şi din afara sa, această variabilă trebuie declarată ca fiind globală, utilizând
cuvântul-cheie global. Variabilele globale există şi în exteriorul funcţiilor în care sunt definite.

1function format_name( $first_name ,$last_name){


2 global $name;
3 $name = $first_name." - ".$last_name;
4 }
5format_name( "Peter", "Andersen" );
echo $name;
6

Variabila $name este creată în interiorul funcţiei, dar prin utilizarea cuvântului-cheie global este
declarată ca variabilă globală, ceea ce înseamnă că aceasta va exista şi în exteriorul funcţiei.
Când funcţia este apelată, variabila $name se creează şi i se acordă o valoare. Această valoare se
poate utiliza şi mai târziu în cod (instrucţiunea echo).

Unei funcţii i se pot atribui parametri de orice tip. Când funcţia este definită, se scriu parametri
utilizaţi de funcţie în cadrul parantezelor. Când funcţia este apelată, este necesar să-i expediem
valori concrete pentru parametri aşteptaţi. Aceste valori pot fi: numere, text, variabile, şiruri,
chiar şi expresii care poartă o valoare. Priviţi următoarea funcţie:

1function add_numbers($numbers){
2 for($i=0; $i < sizeof( $numbers ); $i++){
3 @$sum = $sum + $numbers[ $i ];
4 }
5 return $sum;
}
6

Această funcţie adună numerele care îi sunt expediate în formă de şir. Dacă atunci când funcţia
este apelată nu se expediază un şir, se va produce o eroare. De aceea, întotdeauna trebuie
verificat dacă valorile expediate sunt de tipul corespunzător. De exemplu:

1
2 function add_numbers($numbers = 0){
3 $sum = 0;
if(is_array($numbers)){
4
for( $i=0; $i < sizeof( $numbers ); $i++){
5 $sum = $sum + $numbers[$i];
6 }
7 return $sum;
8 }else{
echo 'Error with function argument!';
9 exit();
10 }
11}
12echo add_numbers();
13
Fiecare funcţie aşteaptă un anumit număr de parametri. Dacă în timpul apelării sunt expediate
mai puţine valori decât cele cerute de funcţie, funcţia va folosi valoarea NULL pentru cele care
lipsesc. Dacă expediaţi mai multe valori, funcţia le ignoră.

În PHP, se pot seta valori default pentru parametri, care vor fi utilizate dacă în timpul apelării
nu vor fi utilizate toate valorile parametrilor:

1function add_2_numbers( $num1=1, $num2=1 ){


2 $total = $num1 + $num2;
3 return $total;
4 }
5echo add_2_numbers(10);

Analizând comportamentul codului de mai sus, observăm că pentru valoarea parametrului $num1
este preluat numărul 10, care este apoi transmis în timpul apelării funcţiei. Deoarece al doilea
parametru nu este transmis, este preluată valoarea default 1. Din cauza unui astfel de
comportament, funcţia returnează valoarea 11.

Atunci când expediaţi o variabilă către o funcţie, se expediază de fapt valoarea ei. Orice
schimbare făcută asupra variabilei expediate nu va afecta valoarea sa originală. De exemplu:

1function add_1($num1){
2 $num1 = $num1 + 1;
3}
4$orig_num = 3;
5add_1($orig_num);
echo $orig_num;
6

În momentul apelării, către funcţia add_1() se transmite valoarea conţinută în variabila


$orig_num. Instrucţiunile din interiorul funcţiei nu afectează variabila, motiv pentru care
instrucţiunea echo va scrie numărul 3, adică valoarea iniţială a variabilei $orig_num.

În unele cazuri, va fi necesar ca o funcţie să schimbe valoarea unei variabile create în exteriorul
funcţiei. În acest caz, în locul valorii variabilei este expediată referinţa ei, prin operatorul &, în
felul următor:

1function add_1(&$num1){
2 $num1 = $num1 + 1;
3 }

În momentul apelării unei funcţii astfel definite, se atribuie referinţa variabilei (indicatorul) în
locul valorii localizate în ea. Acum, schimbările efectuate în interiorul corpului funcţiei vor
afecta valoarea originală. Instrucţiunile:

1function add_1(&$num1){
$num1 = $num1 + 1;
2}
3$orig_num = 3;
4add_1($orig_num);
echo $orig_num;
5
6

vor scrie acum valoarea 4 pe pagină.

Funcţiile anonimous

Uneori, o funcţie trebuie definită în cod la modul general. În acest caz, funcţia nu va avea un
nume, ci va fi doar activată prin cod. Astfel de funcţii se numesc funcţii anonimous.

1<?php
2$myAnonimousFunction = create_function('$a,$b','return $a + $b;');
3echo $ myAnonimousFunction(2, 4);
4?><span style="font-size: 14px; text-align: justify;"> </span>

Parametrii funcției create_function() reprezintă un şir, primul membru al şirului reprezintă


argumentele sale, în timp ce al doilea membru reprezintă doar corpul funcției. Funcția
create_function() nu se pune atunci când un corp mult mai complicat al funcției este foarte
încetinit. Din acest motiv, se evită folosirea ei, pentru a nu încetini paginile web.

Funcţia Anonimous o putem defini, de asemenea, şi în felul următor:

1$f = function(){
2 echo "Hello";
3 }
4$f();

Apelarea dinamică a funcţiei


PHP ne permite să atribuim variabilei denumirea funcţiei ca string, iar apoi variabila respectivă
se poate utiliza pentru apelarea funcţiei. Haideţi să vedem următorul exemplu:

1
<?php
2function helloFunction()
3{
4 echo "Hello<br />";
5}
6$function_holder = "helloFunction";
$function_holder();
7?>
8
Deci, în momentul creării, funcţia a primit denumirea de “helloFunction”. După aceea, variabilei
$function_holder îi este atribuit stringul cu conţinutul “helloFunction”, și anume cu conţinutul
identic denumirii funcţiei. La sfârşit, funcţia nu mai trebuie apelată doar cu ajutorul denumirii
sale, ci se poate apela şi cu ajutorul variabilei nou create: $function_holder().

Funcţia se poate crea şi în cadrul corpului funcţiei deja existente. De exemplu:

1
function func1(){
2 function func2(){
3 echo 'Test';
4 }
5 func2();
}
6func1();
7

Rezultatul pe pagină este: Test.

Care dintre variantele de răspuns nu reprezintă caracteristica funcţiei?


încapsularea
reducerea redundanţei codului
blocarea utilizării variabilelor globale
portabilitatea

Funcţia strlen() returnează:


lungimea unui string
tipul de dată expediată
utilizatorul momentan logat
această funcţie nu returnează nimic, deoarece nici nu există

Exerciţiul nr. 1

Trebuie creată o funcţie care acceptă un string şi returnează caracterele lui în ordine inversă (de
exemplu, stringul “my string” devine “gnirts ym”).

Rezolvare:

<?php
1 function str_reverse($str){
2 $rez = "";
3 for($i=strlen($str)-1; $i>=0; $i--){
4 $rez.=$str[$i];
}
5 return $rez;
6 }
$text = "my string";
7 echo str_reverse($text);
8 ?>
9
10
11

Funcţia care execută serviciul solicitat în conţinutul problemei o numim str_reverse. Deoarece
funcţia trebuie să prelucreze stringul alocat, punem un argument: $str. După finalizarea
serviciului, funcţia va returna rezultatul sub formă de string. Am putea să presupunem că
variabila care va prezenta rezultatul serviciului funcţiei noastre la început va fi un string gol, iar
mai târziu probabil un şir de caractere ceva mai complex. Pe baza celor menţionate, scriem codul
următor:

1function str_reverse($str){
2 $rez = "";
3 return $rez;
4 }

Stringurile PHP pot fi abordate ca şiruri. Asta înseamnă că PHP este în stare să numere încă o
dată caracterele în string, iar pe baza acestei poziţii să furnizeze caracterul special din string.
Aceste semne se numesc indecşi, iar în PHP indexarea începe de la zero.

Haideţi să creăm acum variabila $text şi să apelăm funcţia:

1function str_reverse($str){
2 $rez = "";
3 return $rez;
4}
5$text = "my string";
echo str_reverse($text);
6

Stringul pe care îl abordează funcţia în cazul nostru este: „my string”. Asta înseamnă că, dacă am
vrea să trecem prin acest string cu ajutorul buclei for, trebuie să stabilim numărul de caractere în
string ca pentru fiecare string să executăm o iteraţie. Asta putem să facem cu funcţia strlen().
Totuşi, indexarea începe de la zero, ceea ce înseamnă că cel mai mare index al stringului nostru
este cu unu mai puţin decât numărul de caractere, deoarece începem numărarea de la 1, iar
indexarea de la 0. De aceea, setăm următoarea buclă cu care scriem caracterul care corespunde
iteraţiei:

1for($i=strlen($str)-1; $i>=0; $i--){


2 $rez.=$str[$i];

La final, tema noastră este finalizată, iar funcţia este pregătită pentru uz.
Notă:

În exemplu, se lucrează cu şiruri pentru a atinge scopul acestuia, aşadar acest exerciţiu este
destinat cursanţilor ceva mai avansaţi. Şirurile vor fi abordate în lecţia următoare. Pe scurt,
ele sunt un mijloc de introducere a mai multor valori într-o variabilă. Valorile sunt accesate
prin utilizarea unei combinații de paranteze pătrate și poziții ale valorilor.

Exerciţiul nr. 2

Există următoarea intrare în aplicaţie:

define( "SQUARE", 0 );
define( "RECTANGLE", 1 );
define( "CIRCLE", 2 );
define( "PI", 3.14 );

Trebuie să se creeze o funcție care va accepta ca parametri tipul cu formă geometrică (pătrat,
dreptunghi sau cerc) și valorile a și b. În funcție de forma geometrică, se calculează aria sa și se
returnează rezultatul.

Este necesară testarea funcției.

Rezolvare:

1 <?php
2 define("SQUARE", 0);
3 define("RECTANGLE", 1);
4 define("CIRCLE", 2);
define("PI", 3.14);
5 function area($type, $a, $b = 0){
6 $rez = 0;
7 switch($type)
8 {
case SQUARE:
9 $rez = pow($a, 2);
10 break;
11 case RECTANGLE:
12 $rez = $a * $b;
13 break;
case CIRCLE:
14 $rez = pow($a, 2) * PI;
15 break;
16 }
17 return $rez;
}
18echo area(CIRCLE, 4);
19?><br><br>Această temă este un exemplu foarte bun de a combina cunoştinţele
20din diferite domenii PHP abordate până acum. În primul rând, în modul deja
21cunoscut am creat constantele care vor fi folosite în continuarea logicii
22de programare, după care am creat şi apelat funcţia. Funcţia lucrează cu
23trei parametri, dintre care doar ultimul are valoare implicită, care face
acest parametru opţional.

Cu ajutorul declaraţiei switch, verificăm valoarea parametrului $type şi stabilim cărei constante
îi corespunde. În funcţie de aceste valori, facem calculul după următoarele formulare:

1$rez = pow($a, 2);


2$rez = $a * $b;
3$rez = pow($a, 2) * PI;

Acum, rezultatul nostru este creat şi poate fi returnat în locul apelării funcţiei.

Modul 4 Şirurile
Lucrul cu şiruri
Unitate: 11 din 19 00:22:41

+Rezumat

În lecţiile prezentate până acum, am avut ocazia să ne familiarizăm cu şirurile şi cu baza sintaxei
pentru crearea acestora. În cadrul acestei lecţii, ne vom familiariza mai detaliat cu sintaxa pentru
manipularea şirurilor, precum şi cu diferite tipuri de şiruri disponibile în PHP.

Şirurile reprezintă anumite structuri de date care au posibilitatea să depoziteze una sau mai multe
valori pentru o variabilă. De exemplu, dacă vrem să depozităm 3 mărci de maşini, am putea crea
3 variabile diferite:

1$car1 = "BMW";
2$car2 = "Audi";
3$car3 = "Fiat";

Asta înseamnă că, dacă am avea nevoie să depozităm 100 de denumiri de mărci de automobile,
ar trebui să creăm 100 de variabile diferite? Adevărul este că nu este cea mai strălucită şi mai
elegantă soluţie pentru care ar trebui să folosim avantajele pe care ni le oferă şirurile.

Haideţi să vedem cum am putea să introducem într-un şir valorile pe care le-am creat mai sus:

1$cars = array("BMW", "Audi", "Fiat");

Tocmai am creat un şir inserat în variabila $cars, care are trei elemente. Acelaşi efect l-am putea
obţine şi cu următoarea sintaxă:

1$cars[0] = "BMW";
2$cars[1] = "Audi";
3$cars[2] = "Fiat";

În continuare, vom explica mai detaliat această sintaxă.

PHP deosebeşte 3 tipuri de şiruri:

1. Şiruri numerice;
2. Şiruri asociative;
3. Şiruri multidimensionale.

Şirurile numerice şi asociative

Spre deosebire de variabile, care salvează valori individuale, şirurile se utilizează pentru salvarea
unui ansamblu sau a unei secvenţe de valori. Orice şir este alcătuit din două părţi: index şi
valoare. Indexul şirului se foloseşte pentru identificarea şi accesarea elementului.

În PHP, un şir poate fi creat în câteva moduri. Unul dintre ele este prin atribuirea unei valori
pentru fiecare element în parte. De exemplu:

1$user[0] = "Thomas M.";


2$user[1] = "Peter L.";
3$user[2] = "George N.";

Astfel, este definit şirul $user cu trei elemente numerotate, începând de la 0. Şirurile indexate cu
numere se numesc şiruri numerice.

Elementele şirurilor pot fi indexate şi prin stringuri. Şirurile indexate astfel se numesc şiruri
asociative. De exemplu:

1$city['RO'] = "Bucuresti";
2$city['NY'] = "New York";
3$city['LA'] = "Los Angeles";

Dacă folosiţi următoarele comenzi:$city[] = "Bucuresti";

1$city[] = "New York";


2$city[] = "Los Angeles";

atunci se va crea un şir de trei elemente, unde elementele sunt numerotate automat prin numere,
începând cu numărul 0. Indexarea cu numere începând de la 0 este modul de indexare implicit în
PHP, doar dacă nu specificaţi altceva în mod explicit.

Un şir poate fi creat şi prin utilizarea funcţiei array(), într-unul din următoarele moduri:
1$city = array("Bucuresti", "New York", "Los Angeles");
$city = array(12 => "Bucuresti", "New York", "Los Angeles");
2$city = array(“RO” => "Bucuresti", "NY" => "New York","LA" => "Los
3Angeles");<span style="font-size: 15.4px; text-align: justify;"> </span>

Prima comandă creează un şir de trei elemente indexate cu numerele 0, 1 şi 2. A doua comandă
creează un şir ale cărui elemente sunt indexate cu numerele 12, 13 şi 14. A treia comandă
creează un şir în care elementele primesc stringuri pentru indexuri.

Toate modurile de creare a şirurilor presupun că programatorul trebuie să specifice valori pentru
fiecare element din şir. Uneori, acest lucru este inutil şi total lipsit de practică. De exemplu, dacă
dorim să păstrăm într-un şir numerele de la 1901 la 2000, este suficient să utilizăm
funcţia range() în felul următor:

1$twentiethCentury = range(1901, 2000);

Cu această comandă se creează un şir cu 100 de elemente, ale căror valori sunt numerele
cuprinse între 1901 şi 2000. Aceste elemente sunt indexate în mod automat cu indexurile de la 0
la 99.

După ce şirul este creat, elementele sale sunt accesate prin aceste indexuri. Fiecare element din
şir se utilizează în cod ca orice altă variabilă:

1
2 <html>
3 <head>
4 <title> Arrays </title>
</head>
5
<body>
6 <p>
7 <?php
8 $colors = array( 'red', 'green', 'blue' );
9 echo "First color in array " . $colors[0] . "<br>";
10echo "Second color in array " . $colors[1] . "<br>";
echo "Third color in array " . $colors[2] . "<br>";
11?>
12</p>
13</body>
14</html>
15

Variabila $colors[0] corespunde primului element din şir şi are valoarea 'red'. Ieşirea codului de
mai sus va fi:

First color in array is red


Second color in array is green
Third color in array is blue

Indexurile sunt atribuite în mod automat elementelor din şir, în momentul în care acestea sunt
create, unde primul element are indexul 0.
Uneori, este necesar ca, după crearea şirului, să eliminăm anumite elemente din el. Aceasta se
face cu comanda unset(). De exemplu, unset($user[2]) va elimina al doilea element din şirul
creat în primul exemplu. Atunci, şirul client va fi alcătuit doar din elementele $user[1] şi
$user[3]. Remarcaţi că, prin eliminarea unui element, indexurile celorlalte elemente nu se
schimbă.

Şirurile multidimensionale

Elementul unui şir poate fi orice tip de dată. Aceasta înseamnă că elementul şirului poate fi un
număr, un string, o valoare boolean, dar şi un alt şir. Când un şir conţine un alt şir ca element,
atunci spunem că acesta este un şir multidimensional.

De exemplu:

1$cars = array(
2 array("BMW",'525',2015),
3 array("Audi",'A8',2014),
4);array("Fiat",'500L',2015)
5
6foreach($cars as $car){
7 echo "Brand: " . $car[0] . ", model: " . $car[1] . ", age: " . $car[2] .
8".</br>";
9}

Şirurile multidimensionale vor fi abordate în detaliu în următoarea lecţie.

Funcţiile pentru lucrul cu şirurile


PHP conţine multe funcţii pentru lucrul cu şiruri. Utilizarea acestor funcţii facilitează lucrul cu
datele şi scrierea codului. De asemenea, atunci când sunt aplicate unui şir, majoritatea funcţiilor
obişnuite produc rezultate diferite în comparaţie cu aplicarea lor asupra unei simple variabile.

count(), sizeof()

Ambele funcţii returnează ca valoare numărul elementelor din şir. Exemplu:

1$my_array = array("red","green","blue","yellow","purple");
2
3echo(sizeOf($my_array));
4echo "<br/>";
5echo(count($my_array));
sort(), asort(), rsort(), ksort(), krsort()

Aceste funcţii se utilizează pentru sortarea elementelor din şir. PHP stochează elementele şirului
în ordinea în care au fost create, dar cu ajutorul funcţiilor este posibilă sortarea şirului în ordinea
dorită.

Funcţia sort() sortează şirul în ordine crescătoare în funcţie de valorile elementelor, după care se
execută din nou indexarea. Priviţi următorul şir:

$city[0] = "Bucuresti";
$city[1] = "New York";
$city[2] = "Los Angeles";

După comanda sort($city), şirul $city va avea următoarele elemente:

$city[0] = "Bucuresti";
$city[1] = "Los Angeles"
$city[2] = "New York";

Elementele sunt sortate în ordine alfabetică, motiv pentru care oraşele Los Angeles şi New York
și-au schimbat locurile. Dacă utilizaţi comanda sort() pentru şiruri asociative, elementelor li
se atribuie mai întâi numere ca indexuri, apoi şirul este sortat, iar elementele revin la vechile lor
indexuri. Practic, aceasta înseamnă că respectiva comandă sort() schimbă ordinea valorilor
elementelor, dar nu şi a indexurilor.

Dacă doriţi să sortaţi un şir asociativ, astfel încât fiecare element să-și păstreze indexul existent,
utilizaţi funcţia asort(). Funcţia rsort() ordonează şirul în ordine descrescătoare. Funcţia ksort()
ordonează şirul în ordine crescătoare, în funcţie de indexuri, iar funcţia krsort(), în ordine
descrescătoare.

shuffle()

Se utilizează pentru aranjarea arbitrară a elementelor din şir.

Exemplu:

1$my_array = array("red","green","blue","yellow","purple");
2
3shuffle($my_array);
4print_r($my_array);

array_slice( $numeSir, poziţie, lungime )


În PHP, se poate crea un şir nou ca o submulţime a unui şir deja existent, prin funcţia
array_slice(). De exemplu:

1$testarray = array("red", "green", "blue", "pink" );


2$subArray = array_slice( $testarray, 1, 2 );

Noul şir $subArray va conţine două elemente ale şirului $testArray, începând cu cel care
are indexul 1, respectiv:

[ 0 ] => green
[ 1 ] => blue

array_merge( $numeSir1, $numeSir2 )

Această funcţie vă oferă posibilitatea să uniţi două şiruri într-unul singur. De exemplu,
următoarele comenzi:

1$array1 = array("red", "blue" );


2$array2 = array("green", "yellow" );
3$bigArray = array_merge( $array1, $array2 );

vor crea şirul $bigArray cu următoarele elemente:

$bigArray[ 0 ] = "red"
$bigArray[ 1 ] = "blue"
$bigArray[ 2 ] = "green"
$bigArray[ 3 ] = "yellow"

Atunci când se utilizează această funcţie pentru a uni două şiruri asociative, trebuie să fiţi atenţi
ca în şiruri să nu existe elemente cu acelaşi index. Dacă două elemente au acelaşi index de tip
string, al doilea se va suprapune peste primul.

explode(), implode()

Aceste două funcţii se utilizează pentru convertirea stringului în şir şi invers.

Funcţia explode() are următoarea sintaxă:

$arrName = explode( "sign", $string );

Primul argument al acestei funcţii (sign) determină caracterul care va fi utilizat pentru separarea
stringului. Al doilea argument este textul care se împarte în secţiuni. Fiecare parte devine un
element al şirului.

Exemplu pentru explode():


1$someWords = "Please don't blow me to pieces.";
2
3$wordChunks = explode(" ", $someWords);
4for($i = 0; $i < count($wordChunks); $i++){
5 echo "Piece $i = $wordChunks[$i] <br />";
}
6

În mod similar, elementele şirului pot fi unite într-un string cu ajutorul funcţiei implode():

$text = implode( "sign", $arrName );

Exemplu pentru implode():

1$words = array("Please", "don't", "blow", "me", "to", "pieces.");


2
3$str = implode(" ", $words);
4echo $str;

array_diff( $sir1, $sir2, ... )

Această funcţie identifică toate elementele care se găsesc în primul şir ($array1), însă nu şi în
celelalte şiruri.

Exemplu:

1$a1=array("a"=>"BMW","b"=>"Audi","c"=>"Fiat","d"=>"Opel");
2$a2=array("e"=>"BMW","f"=>"Audi","g"=>"Peugeot");
3$a3=array("a"=>"BMW","b"=>"Peugeot","h"=>"KIA");
4
5$result=array_diff($a1,$a2,$a3);
6print_r($result);

Rezultatul obţinut pe pagină este:

Array ( [c] => Fiat [d] => Opel )

array_sum()

Această funcţie adună valorile care sunt elementele unui şir.

Exemplu:

1$a=array(5,15,25);
2echo array_sum($a);
Rezultatul obţinut pe pagină este 45.

array_unique()

Cu ajutorul acestei funcţii, pot fi eliminate elementele identice ale unui şir.

Exemplu:

1$a=array("a"=>"BMW","b"=>"Audi","c"=>"BMW");
2print_r(array_unique($a));

Rezultatul obţinut pe pagină este:

Array ( [a] => BMW [b] => Audi )


Funcţiile folosite pentru sortarea şirurilor sunt:
substr()
rsort()
organise()
pqmsort()
srtm()

Exerciţiul nr. 1
Este definit următorul şir:

$arr = array( 2, 5, 1, 7, 4, 3, 8 );

Creați o aplicaţie care va sorta acest şir, astfel încât valorile să fie aranjate în ordine crescătoare
de la cea mai mică către cea mai mare.

Afişați şirul sortat la ieşire.

Rezolvare:

Această soluţie presupune algoritmul selection sort, dar poate folosi şi alţi algoritmi diferiţi de
sortare.

1 <?php
2 $arr = array( 2, 5, 1, 7, 4, 3, 8 );
for( $i = 0; $i < sizeof( $arr ); $i++ )
3 {
4 $min = $i;
5 for( $u = $i; $u < sizeof( $arr ); $u++ )
6 {
7 if( $arr[ $u ] < $arr[ $min ] )
$min = $u;
8 }
9 $tmp = $arr[ $i ];
10 $arr[ $i ] = $arr[ $min ];
11 $arr[ $min ] = $tmp;
}
12print_r( $arr );
13?>
14
15
16

Şirul sortat la ieşire este:

Array ( [ 0 ] => 1 [ 1 ] => 2 [ 2 ] => 3 [ 3 ] => 4 [ 4 ] => 5 [ 5 ] => 7 [ 6


] => 8 )

Creăm variabila care conţine şirul pregătit pentru sortare şi o numim $arr. Folosind bucla for,
trecem prin toate elementele şirului, respectiv asigurăm numărul de iteraţii care corespunde cu
numărul elementelor din şir. După sarcina finalizată a acestei bucle, şirul va fi sortat şi pregătit şi
îl putem prezenta. Pentru asta folosim funcţia print_r().

Codul nostru arată acum astfel:

1$arr = array( 2, 5, 1, 7, 4, 3, 8 );
2for( $i = 0; $i < sizeof( $arr ); $i++ ){
3
4}
5print_r( $arr );

În fiecare iteraţie, aşteptăm ca elementul cu indexul $i cel mai mic, de aceea setăm:

1$min = $i;

Totuşi, aceasta este doar o presupunere şi trebuie verificată. Ca să facem asta, elementul care are
indexul $i trebuie comparat cu celelalte elemente. Aici ne poate ajuta noua buclă for de interior.

Acum, codul nostru arată astfel:

1
$arr = array( 2, 5, 1, 7, 4, 3, 8 );
2for( $i = 0; $i < sizeof( $arr ); $i++ )
3{
4 $min = $i;
5 for( $u = $i; $u < sizeof( $arr ); $u++ ){
6 }
}
7print_r( $arr );
8
În fiecare iteraţie a acestei bucle interne, facem verificarea: $arr[ $u ] < $arr[ $min ] ca să
confirmăm introducerea între elementele testate. Dacă această condiţie este îndeplinită, trebuie
schimbate şi valorile variabilei $min, al cărei scop este de a conţine indexul celui mai mic
element din şir.

Când bucla termină toate iteraţiile, rămâne să schimbăm locul elementelor în şir. În primul rând,
de pe poziţia $i trebuie să preluăm elementul şi să-l punem în spaţiu temporar (deoarece nu vrem
să-l pierdem). Asta facem în felul următor:

1$tmp = $arr[ $i ];

În locul acestui element, îl punem pe cel pe care l-am stabilit ca fiind cel mai mic:

1$arr[ $i ] = $arr[ $min ];

Şi, la final, de pe poziţia temporară întoarcem în şir (în locul rămas gol) elementul pe care l-am
scos mai devreme:

1$arr[ $min ] = $tmp;

Cu aceasta am terminat exerciţiul nostru.

Exerciţiul nr. 2

Se dă următorul şir:

$arr = array( 0, 1, 2, 3, 4, 5, 6, 7, 8 );

Trebuie creat codul care va afişa fiecare membru al şirului, înmulţit cu membrul anterior al
şirului.

0
0
2
6
12
20
30
42
56

Rezolvare:

1 <?php
$arr = array(0, 1, 2, 3, 4, 5, 6, 7, 8);
2 for($i=0; $i<sizeof($arr); $i++){
3 if($i>0){
4 echo $arr[$i] * $arr[$i-1]."<br>";
}else{
5 echo $arr[ $i ]."<br>";
6 }
7 }
8 ?>
9
10

Cu această problemă este prezentat exemplul clasic de folosire a şirurilor şi a buclei în


combinaţie. Esenţa acestei sarcini este, de fapt, doar ideea de furnizare a elementului
corespunzător din şir şi a predecesorului său. Dacă folosim ca index conterul $i, atunci cu
siguranţă indexul precedent este $i-1. Acum, singura problemă care ne rămâne este situaţia în
care counter-ul ar avea valoarea 0. Atunci, pe baza acestei logici am solicita indexul precedent,
respectiv indexul -1, ceea ce ar duce la apariţia greşelii. Ca să nu se ajungă la asta, setăm
condiţionarea:

1if($i>0){
2 echo $arr[$i] * $arr[$i-1]."<br>";
3 }else{
4 echo $arr[ $i ]."<br>";
}
5

Exerciţiul nr. 3

Se dă următoarea variabilă:

$lipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry's standard dummy text ever since
the 1500s, when an unknown printer took a galley of type and scrambled it to
make a type specimen book. It has survived not only five centuries, but also
1the leap into electronic typesetting, remaining essentially unchanged. It
was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software
like Aldus PageMaker including versions of Lorem Ipsum.";

Creaţi un program care va număra numărul exact de cuvinte din acest string şi care va emite un
rezultat la ieşire în următorul format:

Lorem : 4
Ipsum : 3
is : 1
simply : 1
dummy : 2
text : 2
of : 4
Rezolvare:

<?php
$lipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting
1 industry. Lorem Ipsum has been the industry's standard dummy text ever
2 since the 1500s, when an unknown printer took a galley of type and
3 scrambled it to make a type specimen book. It has survived not only five
centuries, but also the leap into electronic typesetting, remaining
4 essentially unchanged. It was popularised in the 1960s with the release of
5 Letraset sheets containing Lorem Ipsum passages, and more recently with
6 desktop publishing software like Aldus PageMaker including versions of
7 Lorem Ipsum.";
8
9 $arr = explode(" ", $lipsum);
$words = array();
10$counts = array();
11for($i=0; $i<sizeof($arr); $i++){
12 if(!in_array($arr[$i], $words)){
13 $words[] = $arr[ $i ];
$counts[] = 1;
14 }else{
15 for($u=0; $u<sizeof($words); $u++){
16 if( $words[ $u ] == $arr[ $i ]){
17 $counts[ $u ]++;
18 }
}
19 }
20 }
21for($i=0; $i<sizeof($words); $i++){
22 echo($words[$i] . " : " . $counts[$i] . "<br>");
}
?>

Variabila $lipsum reprezintă stringul pe care îl vom aborda. În variabila $arr, punem valoarea pe
care o returnează funcţia explode(). În cazul nostru, această funcţie acceptă două argumente.
Primul parametru este separator, respectiv caracterul după care vom executa separarea stringului
pe elemente ale şirului. Al doilea argument este stringul de la care va fi creat şirul $arr. Deoarece
aici am setat ca separator spaţiu, la fel elementele şirului nostru vor fi cuvintele din
text ($lipsum).

În continuare, avem nevoie de un şir pentru cuvinte şi unul pe care îl vom folosi ca şi counter. De
aceea, creăm aceste şiruri ca goale:

1$words = array();
2$counts = array();

Ca să trecem prin fiecare cuvânt, trecem prin toate elementele şirului:

1for($i=0; $i<sizeof($arr); $i++){}


În cadrul acestei bucle, în primul rând trebuie să verificăm dacă cuvântul (elementul) se află în
şir. Dacă cuvântul găsit nu este în şir, trebuie adăugată şi valoarea counter-ului pentru ca primul
index liber să fie 1. Pe de altă parte, dacă cuvântul este în şir, se va face scenariul alternativ. Aici
se fac atâtea iteraţii câte elemente are şirul $words şi pentru fiecare se verifică condiţia:

1$words[ $u ] == $arr[ $i ]

De asemenea, creşte şi valoarea elementului în şirul $counts care corespunde counter-ului buclei
de interior ($u).

La final, trebuie doar să prezentăm rezultatele ambelor şiruri:

1for($i=0; $i<sizeof($words); $i++){


2 echo($words[$i] . " : " . $counts[$i] . "<br>");
3}

Exerciţiul nr. 4:
Scrieți un program care va accesa elementele şirului cu ajutorul buclei foreach şi al sistemului
key=>value pentru un şir de produse lactate (milk, chocolate, cheese) şi preţurile lor în ordinea
valorilor de la 89, 75, 105.

Rezolvare:

1
<?php
2 $price['milk'] = 89;
3 $price['chocolate'] = 75;
4 $price['cheese'] = 105;
5
6 foreach ($price as $key => $value) {
7 echo $key . '=>' . $value . '<br/>';
}
8
9 ?>
10

După executarea programului, la ieşire va fi afișat următorul rezultat:

milk=>89
chocolate=>75
cheese=>105

Exerciţiul prezentat este un exemplu clasic de utilizare a buclei foreach. Folosirea buclei foreach
face trecerea mai simplă prin şirul asociativ, deoarece imediat se pot separa cheile de valoare. În
cazul nostru, şirul are trei elemente şi fiecare are propria cheie şi propria valoare.

…………………………..

Şirurile multidimensionale şi funcţionalitatea


efectuată asupra şirurilor
Unitate: 12 din 19 00:21:15

+Rezumat

În lecţia precedentă, am folosit în general şiruri care conţin o listă de perechi de chei/valori. Am
văzut că utilizarea şirurilor asociative poate fi mult mai practică decât utilizarea şirurilor
numerice şi invers. Am menţionat, de asemenea, şi şirurile multidimensionale. Am putea spune
că astfel de şiruri sunt, de fapt, şiruri de şiruri, deoarece elementele lor sunt şiruri noi, adică
subşiruri. Pot exista mai multe subşiruri. Dacă un şir posedă un singur subşir, atunci vorbim de
un şir bidimensional. În caz că subşirul respectiv are subşirul său, atunci spunem că acesta este
un şir tridimensional ş.a.m.d. Majorității oamenilor le este greu să se descurce cu şirurile atunci
când au şiruri de trei sau patru dimensiuni.

În continuarea lecţiei, vom aborda mai detaliat şirurile asociative, iar apoi şi şirurile
multidimensionale.

Perechile de şiruri (şirul asociativ)

Pe lângă şirurile în care fiecare membru are o poziţie proprie, determinată prin index, care
reprezintă o valoare numerică, se poate crea şi un şir în care valorile sunt legate de anumite chei
în acest şir, respectiv stringuri care se asociază la o valoare.

De exemplu, dacă am dori să creăm un şir de ţări, iar fiecărei ţări îi asociem capitala ei, vom
utiliza acest tip de şir. Astfel, ţările pot fi cheile, în timp ce valorile pot fi oraşele.

Crearea şirului ar arăta astfel:

$arr = array("Romania"=>"Bucharest", "France"=>"Paris",


1"England"=>"London");

unde valorile din partea stângă a semnului => reprezintă cheia, iar valoarea din dreapta
reprezintă valoarea cheii respective.

Obţinerea valorii unei anumite chei într-un astfel de şir este destul de simplă:
1echo $arr["Serbia"];

Această linie de cod va emite valoarea pentru cheia »Romania«, care în acest caz este Bucharest.

Şirul multidimensional

Pe lângă şirurile unidimensionale, pe care le-am studiat în lecţia precedentă, PHP poate să
recunoască şi aşa-numitele şiruri multidimensionale. Aceste şiruri sunt foarte utile pentru lucrul
cu datele în formă de matrice sau tabel.

De exemplu, să presupunem că vrem să depozităm nişte date în formă de tabel, astfel încât
tabelul să conţină următoarele coloane: ID, Prenume, Nume, CNP.

De exemplu:

ID Prenume Nume CNP


1 John Miller 1111111111111
2 Peter Andersen 2222222222222
3 Ana Newman 3333333333333

În acest caz, vom putea utiliza un şir bidimensional:

1$arr = array();
2 $arr[0] = array(1, "John", "Miller", "1111111111111");
3 $arr[1] = array(2, "Peter", "Andersen", "2222222222222");
4 $arr[2] = array(3, "Ana", "Newman", "3333333333333");

Am fi putut completa acest şir şi altfel, în timpul iniţializării:

1$arr = array(
2 array( 1, "John", "Miller", "1111111111111" ),
3 array( 2, "Peter", "Andersen", "2222222222222" ),
4 array( 3, "Ana", "Newman", "3333333333333")
);
5

Observând această structură, am putea să ajungem foarte uşor la orice element din şir. De
exemplu, dacă vrem să obţinem numele de familie Andersen, am putea urma următoarea cale:

1echo $arr[1][2];

Acum, pe pagină am fi avut rezultatul: Andersen

De asemenea, toate numele din această structură s-ar putea trece şi cu ajutorul buclei:
1for($i=0; $i<count($arr); $i++){
2 echo $arr[$i][1]."<br>";
3 }

sau dacă vrem să publicăm toate datele din tabel:

1for($i=0; $i<count($arr); $i++){


echo $arr[$i][0] . " " . $arr[$i][1] . " " . $arr[$i][2] . " " .
2$arr[$i][3] ."<br>";
3}

Aceste soluţii sunt practice atunci când avem un număr fix de membri ai subşirului (în acest caz,
este vorba de coloanele tabelului nostru), însă nu şi dacă dorim să gestionăm anumite date
dinamice, a căror cantitate nu o ştim de dinainte. De exemplu, un program care gestionează
imagini şi în care utilizatorul poate încărca o imagine în orice format. În acest caz, ar trebui să
lucrăm cu şiruri de mărime necunoscută şi ar trebui să utilizăm o metodă diferită pentru iteraţia
prin membrii săi.

De exemplu, o matrice cu valorile:

1 2 3 4
5 6 7 8
9 0 1 2

În formă de şir, această matrice ar arăta astfel:

<?php
1
<?php
2$arr = array(
3array( 1, 2, 3, 4 ),
4array( 5, 6, 7, 8 ),
5array( 9, 0, 1, 2 )
6);
?>
7

şi ar fi uşor să facem o iteraţie prin ea, derivată din exemplul de mai sus.

Dar, să ne imaginăm că, în loc de această structură cunoscută, am obţine o variabilă $arr, ale
cărei date ne sunt necunoscute (ştim doar că este un şir bidimensional); în acest caz, ar trebui să
apelăm la o tehnică diferită:

1for($sp=0; $sp<count($arr); $sp++){


2 for($up=0; $up<count($arr[$sp]); $up++)
3 echo $arr[$sp][$up] . " ";
4 echo "<br>";
}
5
Însă nici acest lucru nu este suficient pentru a salva datele despre o imagine, deoarece o
imagine are, la fiecare coordonată, un anumit set de date (despre culoare). Deoarece culoarea
constă deseori în trei valori (dacă este vorba de modelul RGB), va trebui să mai creăm câte un
şir cu trei membri pentru fiecare punct.

Fireşte, există şi alte metode mult mai eficiente pentru gestionarea acestui tip de date (de
exemplu, obiectele).

Pentru a îndeplini cererea menţionată, trebuie să schimbăm puţin codul. Mai întâi, să
presupunem că şirul obţinut prin parsarea unei imagini arată astfel:

1
2
3 $arr = array(
array(
4 array(0,0,0),
5 array(255,255,255),
6 array(0,0,0),
7 array(255,255,255)
),
8 array(
9 array(255,255,255),
10 array(0,0,0),
11 array(255,255,255),
12 array(0,0,0)
),
13 array(
14 array(0,0,0),
15 array(255,255,255),
16 array(0,0,0),
array(255,255,255)
17 )
18);
19
20

astfel încât fiecare subşir al şirului principal să fie un rând, iar fiecare subşir dintr-un rând să fie
un punct.

Pentru iteraţia prin datele serializate astfel, am putea să utilizăm următorul cod:

1
for( $sp = 0; $sp < sizeof( $arr ); $sp++ )
2 {
3 for( $up = 0; $up < sizeof( $arr[ $sp ]); $up++ )
4 for( $up1 = 0; $up1 < sizeof( $arr[ $sp ][ $up ]); $up1++ )
5 echo $arr[ $sp ][ $up ][ $up1 ] . " ";
echo "<br>";
6 }
7
Un avantaj care se poate folosi în lucrul cu şirurile multidimensionale este bucla foreach.
Această buclă are grijă de dimensiunea şi poziţiile membrilor şirului în timpul iteraţiei, motiv
pentru care este foarte bună pentru operaţii simple. Pe de altă parte, această abordare reduce
controlul asupra membrilor şirului. Bucla foreach va fi descrisă mai detaliat într-una din lecţiile
următoare.

Când se utilizează bucla foreach, deplasarea prin şirul de mai sus ar arăta astfel:

<?php

$arr = array(
array(array(0,0,0),array(255,255,255),array(0,0,0),array(255,255
,255)),
array(array(255,255,255),array(0,0,0),array(255,255,255),array(0
,0,0)),
array(array(0,0,0),array(255,255,255),array(0,0,0),array(255,255
,255))
);
foreach($arr as $row){
foreach($row as $point){
foreach($point as $color){
echo $color . " ";
}
}
echo "<br?>";
}

Pentru ce tip de date este adecvată utilizarea şirurilor multidimensionale?


şirurile multidimensionale sunt utile pentru lucrul cu date în formă de matrice sau formă
tabelară
şirurile multidimensionale sunt utile pentru datele exprimate în numere
şirurile multidimensionale sunt utile pentru lucrul cu valorile boolean

Funcţiile avansate care se pot aplica asupra şirurilor

Pentru a afişa membrii şirului, fără a ne deplasa prin membrii individuali (precum în exemplele
precedente), se poate utiliza funcţia print_r. Această funcţie descompune şirul, afişându-i cheile
sau numerele indexurilor şi valorile care se află sub acestea.

De exemplu:

$arr = array("Serbia"=>"Belgrade", "France"=>"Paris", "England"=>"London");


1print_r($arr);
2

va avea rezultatul:

Array ( [Romania] => Bucharest[France] => Paris [England] => London )

Utilizarea acestei funcţii poate fi foarte utilă în timpul dezvoltării aplicaţiei, dar nu se recomandă
utilizarea ei în producţie, ci elementele şirului trebuie parsate la ieşire în cel mai convenabil mod
(acesta este cel mai des modul de parsare printr-un tip de buclă).

Array_walk()

Funcţia array_walk() se foloseşte pentru deplasarea elementelor din şir prin funcţia specificată.
Cheile şi valorile elementului din şir reprezintă argumentele funcţiei. Dacă schimbările, pe care
le provoacă funcţia pe chei şi valori, vrem să le salvăm imediat în acelaşi şir, atunci putem folosi
operatorul & pentru indicarea la adresa de memorie.

Exemplu:

1$arr = array("Romania"=>"Bucharest", "France"=>"Paris",


2"England"=>"London");
3
array_walk($arr, 'arrFunc', ' is capital city of state which name is ');
4
5function arrFunc($key, $value, $p){
6 echo $key . $p . $value . ".<br>";
7}

Funcţia trece prin toate elementele şirului $arr şi la fiecare apelează funcţia arrFunc. Funcţia
acceptă cheia şi valoarea elementului, dar şi parametrul suplimentar în formă de string care are
valoarea "is capital city of state which name is". După ce funcţia procesează elementul, aceasta
trece la următorul element, aşadar rezultatul obţinut pe pagină este:

Bucharest is capital city of state which name is Romania.


Paris is capital city of state which name is France.
London is capital city of state which name is England.

Array_fill()

Dacă dorim să formăm un șir populat cu o valoare statică, putem utiliza această funcţie, unde
primul parametru este indexul de început al şirului, al doilea parametru este numărul membrilor
inseraţi, iar ultimul parametru este valoarea care se inserează:

1$x = array_fill( 0, 10, "hello" );


2print_r( $x );
Acest cod returnează:

Array ( [0] => hello [1] => hello [2] => hello [3] => hello [4] => hello [5]
1=> hello [6] => hello [7] => hello [8] => hello [9] => hello )

În acest mod, se pot copia mai multe şiruri într-un alt şir, respectiv se poate crea un şir
multidimensional, fiindcă această funcţie poate primi şi un şir ca parametru.

Array_flip()

Schimbă poziţiile cheilor şi ale valorilor. Dacă şirul este alcătuit din chei şi valori, această
funcţie va înlocui cheile şi valorile, iar dacă şirul nu are chei, ci doar indexuri, această funcţie va
înlocui indexurile membrilor cu valorile membrilor.

Codul:

1$arr = array("Romania" => "Bucharest", "France" => "Paris", "England" =>


"London");
2$x = array_flip($arr);
3print_r($x);

emite:

Array ( [Belgrade] => Serbia [Paris] => France [London] => England )

Array_pop()

Pentru a înţelege această funcţie şi următoarea, mai întâi trebuie să înţelegem două moduri de
accesare a oricărei colecţii de date din programare: FIFO şi LIFO. FIFO este prescurtarea de la
First In First Out (primul intrat primul ieșit) şi presupune că elementul care a accesat primul
colecţia de date o şi părăseşte primul. În timp ce LIFO, Last In First Out (ultimul intrat primul
ieșit), presupune că ultimul element care a accesat colecţia o părăseşte primul.

Deseori, aceste două abordări sunt comparate cu cele două situații: biroul de la serviciu şi rândul
de la poştă.

 Biroul de la serviciu (LIFO):


Dacă punem o grămadă de hârtii pe masă, ultima hârtie pusă pe masă se va afla în vârful
grămezii şi va fi luată prima.
 Rândul de la poştă (FIFO):
Persoana care a venit ultima la rând, va ajunge ultima la ghişeu.

Lucrurile funcționează la fel şi în programare: stack (birou) şi queue (poşta). De obicei (în
programare, în special), de aceste două tipuri de populare a colecţiei de date se leagă şi două
funcţii. Pentru stack, acestea sunt pop şi push, iar pentru queue, dequeue şi enqueue.
Array_pop() va extrage şi va şterge ultimul element din şir, dar va pune un marker în poziţia sa
precedentă.

Aşadar, următorul cod va emite Washington ca rezultat:

1$arr = array( "Bucharest", "Paris", "London", "Washington" );


2echo array_pop( $arr );

dar următorul cod va emite: WashingtonLondonParisBucharest

1$arr = array( "Bucharest", "Paris", "London", "Washington" );


2echo array_pop( $arr );
3echo array_pop( $arr );
4echo array_pop( $arr );
5echo array_pop( $arr );

Ca să adăugăm un element în şir după acelaşi principiu, vom utiliza funcţia: array_push().

Array_push()

1$arr = array("Bucharest", "Paris", "London");


2array_push( $arr, "Washington" );
3print_r( $arr );

Rezultatul este:

Array ( [0] => Bucharest [1] => Paris [2] => London [3] => Washington )

Această funcţie produce un rezultat identic cu cel pe care l-am obţine dacă am introduce valoarea
direct, prin comanda:

$arr[] = "Washington";

Însă, utilizarea funcţiei array_push() produce un rezultat puţin mai rapid, deoarece este mai
eficientă în lucrul cu cantităţi mai mari de date.

list()

Atribuie valorile şirului către lista transmisă de variabile.

1$capitals = array("Bucharest", "Paris", "London");


2list($Romania, $France, $England) = $capitals;
3echo $France;
Această abordare este adecvată pentru o cantitate mică de date statice.

Rezultatul codului va fi:

Paris

Exerciţiul nr. 1

Se dă următorul şir:

$table = array("format" => array(7, 7),"positions" => array(array(3,


15),array(1, 4),array(4, 6),array(3, 7)));

Cu ajutorul buclei, treceți prin şirurile corespunzătoare, astfel încât să creați un tabel al
dimensiunilor menționate în subşirul format, şirul table.

Desenați un tabel astfel încât toate câmpurile libere să fie afișate cu semnul 0, iar toate câmpurile
care se află în subşirul positions al șirului tabel să fie prezentate cu semnul X. Pentru şirul dat,
ieşirea ar trebui să arate astfel:

0000000
0000000
0000000
X000000
00X0000
000X000
00X0000

Rezolvare:

1 <?php
2 $table = array("format" => array(7, 7),"positions" => array(array(3,
5),array(1, 4),array(4, 6),array(3, 7)));
3
4 for($fh=1; $fh<=$table['format'][1]; $fh++){
5 for($fw=1; $fw<=$table['format'][0]; $fw++){
6 $pointExists = false;
7 foreach($table['positions'] as $pos){
if($pos[0] == $fw && $pos[1] == $fh){
8 echo 'X';
9 $pointExists = true;
10 }
11 }
if(!$pointExists) echo '0';
12
}
13 echo '<br>';
14}
15?>
16
17

Informaţiile legate de tabelul care trebuie creat se găsesc în şirul $table. Acest şir are două
elemente. Primul element este:

1"format" => array(7, 7)

cu care se definesc dimensiunile tabelului, în timp ce al doilea element este:

1"positions" => array(array(3, 5),array(1, 4),array(4, 6),array(3, 7))

şi cu el se definesc punctele în care va fi prezentat semnul X.

Ca să generăm pe pagină tabelul, trebuie să folosim două bucle for, ca să rezolvăm prezentarea
coloanelor şi a rândurilor:

1for($fh=1; $fh<=$table['format'][1]; $fh++){


2 for($fw=1; $fw<=$table['format'][0]; $fw++){

Variabila $pointExists la începutul iteraţiei are valoarea boolean false, care se poate schimba mai
târziu, dacă există o suprapunere cu punctele definite şi counter-ele buclei.

Apoi, tocmai astfel de suprapunere verificăm prin bucla foreach:

1foreach($table['positions'] as $pos){
2 if($pos[0] == $fw && $pos[1] == $fh){
3 echo 'X';
4 $pointExists = true;
5 }
}
6

dacă suprapunerea este confirmată şi variabila $pointExists îşi schimbă valoarea la true. Asta
este important deoarece numai dacă punctul de suprapunere nu există vrem să scriem pe
pagină „0“.

Exerciţiul nr. 2

Se dă următorul şir:

$population = array("London" => 7556900,"Bucharest" => 1500000,"New York" =>


18406000, "Paris" => 11836970);
Creați un program bazat pe numărul populației, pentru a crea un grafic primitiv în care să fie
afişat numărul de locuitori pe o scară de la 1 la 10, în funcție de procentaj. Se va forma un
procent astfel încât orașul cu cea mai mare populație să fie de 100%.

În diagramă, părțile incluse în scală trebuie prezentate cu semnul #, în timp ce părțile care nu
acoperă valoarea nu ar trebui să fie prezentate (aceste semne sunt arbitrare).

În partea de jos a listei, ar trebui să se afișeze pe verticală numele orașelor.

Aspectul final al exemplului este următorul:

#
#
# #
# # #
# # #
# # #
# # #
# # #
# # # #
# # # #
# # # #
L B N P
o e e a
n l w r
d g i
o r Y s
n a o
d r
e k

Rezolvare:

1 <?php
2 $population = array("London" => 7556900, "Bucharest" => 1500000, "New York"
3 => 8406000, "Paris" => 11836970);
$max = 0;
4 $longestCityName = 0;
5 foreach($population as $k => $v)
6 {
7 if($v > $max)
$max = $v;
8 if(strlen( $k ) > $longestCityName)
9 $longestCityName = strlen( $k );
10 }
11$percent = 100 / $max;
12
13for($i = 10; $i >= 0; $i--)
{
14foreach($population as $k => $v)
15 {
16 $currentPercent = ceil(($percent * $v)/10);
17 if($currentPercent >= $i)
18 echo "#" . " ";
else
19 echo "<span style='color:white;'>#</span>" . " ";
20 }
21echo "<br>";
22}
23for($i
{
= 0; $i < $longestCityName; $i++)
24 foreach($population as $k => $v)
25 {
26 if(strlen( $k ) > $i)
27 {
$cityArr = str_split( $k );
28 echo $cityArr[ $i ] . " ";
29 }
30 else
31 echo " ";
}
32 echo "<br>";
33}
34?><br><br>Când ne uităm la cerinţele problemei şi codul care prezintă
35rezolvarea sa, observăm că în afara de funcţia ceil() nu există părţi de
36sintaxă cu care să nu ne fi întâlnit deja şi pe care să nu le fi abordat.
De aceea, aici ne vom ocupa de funcţia ceil(). Această funcţie rotunjeşte
37numărul dat la cea mai apropriată valoare număr întreg, dacă trebuie. Dacă
38funcţiei îi alocăm întregul număr, în locul apelului returnează tocmai
39acest număr (nemodificat). Ca să rotunjim numărul la prima valoare numerică
40mai mică, folosim funcţia floor().
Se poate crea un şir în care valorile sunt legate de anumite chei din acel şir.
adevărat
fals
……………………………………………………………

Modul 5 Stringurile
Procesarea stringurilor
Unitate: 13 din 19 00:17:36

+Rezumat

O manipulare abilă a stringurilor reprezintă o caracteristică foarte importantă a fiecărui


programator serios, aşadar în această lecţie ne vom familiariza tocmai cu acest subiect. Cele mai
simple funcţii de scriere a textului sunt print şi echo. Aplicarea lor este aproape identică, cu
excepția faptului că echo este puţin mai rapidă în timpul executării. În ceea ce priveşte sintaxa,
nu contează dacă veţi scrie:

1print "Hello";
sau:

1echo "Hello";

Când trebuie să scrieți un text mai complicat, se foloseşte funcţia printf(), care afişează textul
static şi informaţiile dinamice, iar aplicarea ei arată astfel:

1printf("Astazi s-au vandut $d produse. ", 100 );

După executarea funcţiei, va fi scris următorul text:

Astazi s-au vandut 100 produse.

Ghilimelele simple (' ') şi duble (" ")

După cum am menţionat deja, pentru a atribui o valoare de tip string unei variabile, aceasta
trebuie să fie pusă între ghilimele. În textul pe care îl atribuiţi unei variabile, se pot utiliza şi
anumite caractere speciale.

Exemplul de adăugare a tagurilor HTML într-un text:

1$string = "PHP <br> programming.";


2echo $string;

va scrie următoarele două linii de text:

PHP
programming.

Dacă vrem ca pe pagină să fie scris un string aşa cum este scris şi în codul PHP, deci fără
interpretarea tagurilor HTML, vom folosi funcţia htmlspecialchars().

Exemplu:

1echo htmlspecialchars("PHP <br> programming.");

Rezultatul pe pagină va fi următorul:

PHP <br> programming.

Alegerea ghilimelelor simple sau duble face diferenţă în timpul scrierii variabilelor. Variabila
scrisă între ghilimele duble va fi citită, adică va fi afişată valoarea acesteia, în timp ce variabila
scrisă între ghilimele simple va fi tratată ca un alt oarecare text.

Haideţi să vedem aceasta pe unele exemple.


Exemplu cu ghilimele simple:

1$x = 10;
2echo 'Test $x';

Rezultatul pe pagină va fi: Test $x

Exemplu pentru ghilimele duble:

1$x = 10;
2echo "Test $x";

Rezultatul pe pagină va fi: Test 10

Dacă totuşi doriţi să folosiţi ghilimele duble, dar în ele să afişaţi denumirea variabilei sau un alt
caracter special care nu trebuie interpretat, puteţi folosi caracterul escape (\).

Exemplu:

1$x = 10;
2echo "My variable is \$x.";

Rezultatul pe pagină va fi: My variable is $x.

Utilizarea caracterului escape este foarte utilă atunci când într-un string, care se afişează pe
pagină, trebuie introduse ghilimele duble.

Exemplu:

1$x = 10;
2echo "Hello, \"World\".";

Rezultatul pe pagină va fi: Hello, "World".

Operaţii asupra stringurilor

Una dintre cele mai frecvente operaţii asupra stringurilor este concatenarea (punctul (.)). Pe
lângă acest operator, PHP conţine şi un număr mare de funcţii încorporate pentru lucrul cu textul.
Câteva dintre acestea sunt:

 trim() – elimină spaţiile goale de la începutul şi de la sfârşitul stringului;


 ltrim() – elimină spaţiile goale de la începutul stringului;
 rtrim() – elimină spaţiile goale de la sfârşitul stringului;
 str_word_count() – numără cuvintele căutate în string, însă dacă se setează suplimentar
parametrii opţionali, atunci se pot crea şi unele şiruri noi din rezultatele căutării;
 strpbrk(string, char) – caută caracterul char în textul string şi returnează restul stringului
după repetarea caracterelor;
 strtoupper(string) – transformă toate literele în majuscule;
 strtolower(string) – transformă toate literele în minuscule.

Exemplu:

Funcţia str_word_count( ) se poate folosi în mai multe moduri. De asemenea, se foloseşte


împreună cu funcţia pentru scriere print_r(), care execută scrierea şirurilor în aşa fel încât datele
să fie lizibile pentru utilizator. Priviți următoarele exemple de utilizare:

1echo str_word_count("Hello World!");

După executare, funcţia va returna rezultatul:

care reprezintă numărul de cuvinte din string.

Exemplul în care, ca al doilea argument, se include şi numărul:

1print_r(str_word_count("Hello World!", 1));

după executare va scrie:

Array ( [0] => Hello [1] => World )

Dacă stringul conţine şi un caracter special ca al treilea argument, introducem şi acest caracter
special în cadrul parametrilor funcţiei, precum este prezentat în exemplul de mai jos:

1print_r(str_word_count("Hello World!", 1));


2print_r(str_word_count("Hello World!", 1, "!"));

După executare, putem observa că, dacă al treilea argument nu a fost inclus, respectiv dacă nu a
fost inclus caracterul special în string, şirul îl va omite la ieşire şi va scrie doar şirul celorlalte
cuvinte. Dacă acest caracter special este menţionat ca argument, şirul va lua în considerare la
ieşire şi caracterul special.

Afişarea datelor după executarea programului:

Array ( [0] => Hello [1] => World )


Array ( [0] => Hello [1] => World! )
Exemplu:

Acum vă vom demonstra folosirea funcţiilor pentru lucrul cu stringuri în cazul transformării
majusculelor sau minusculelor. Priviți acest exemplu de cod:

1$str = "PHP is my favorite progamming language.";


2echo "Without functions : " . $str;
3echo "<br />";
4echo "Function - strtoupper : " . strtoupper( $str ) ;
5echo "<br />";
echo "Function - strtolower: " . strtolower( $str );
6

Rezultatul pe pagină va fi:

Without functions : PHP is my favorite progamming language.


Function - strtoupper : PHP IS MY FAVORITE PROGAMMING LANGUAGE.
Function - strtolower: php is my favorite progamming language.

Formatarea afişării textului

Funcţiile printf() şi sprintf() asigură formatarea textului şi a numerelor, precum şi combinarea


acestora. Sintaxa de bază a acestor instrucţiuni este:

printf( "format", $val1, $val2,...);


$newStr = sprintf( "format", $val1, $val2,...);

Ambele funcţii formatează textul pe baza argumentului format, cu deosebirea că funcţia printf()
îl afişează doar, în timp ce funcţia sprintf() îl pune într-o variabilă nouă. Primul argument al
acestor funcţii, "format", reprezintă instrucţiuni de formatare. Fiecare instrucţiune de formatare
are următoarea formă:

%pad - lungime.dectip

unde:

 pad – este caracterul care se foloseşte pentru completarea spaţiilor libere, dacă stringul
este mai scurt decât lungimea specificată;
 semnul '-' – desemnează alinierea caracterelor la stânga. Dacă se omite, se efectuează
alinierea la dreapta în mod implicit;
 lungime – numărul de caractere care se folosesc pentru afişarea valorii;
 .dec – numărul locurilor zecimale;
 tip – tipul de valoare reprezentată (s pentru string, f pentru float).

Priviţi următoarele exemple:


Exemplul 1

1$numOfBoys = 3;
2 $numOfGirls = 2;
3 printf("%s boys and %s girls", $numOfBoys, $numOfGirls);

va scrie mesajul:

3 boys and 2 girls

Exemplul 2

1$price = 30000;
2 $product = "Samsung TV";
3 $message1 = sprintf("%s costs %06.2f dollars. ", $product, $price);
4 $message2 = sprintf("%'.-20s%6.2f", $product, $price);
5 echo $message1;
echo $message2;
6

va scrie mesajul:

Samsung TV costs 030000.00 dollars.


SamsungTV........... 30000.00

În primul mesaj, prima instrucţiune de formatare este %s , care se referă la prima


variabilă, $product. Această instrucţiune va scrie doar valoarea variabilei. A doua instrucţiune de
formatare este %06.2f şi se referă la a doua variabilă, $price. Instrucţiunea spune că numărul
trebuie să fie reprezentat prin 6 caractere şi 2 spaţii zecimale, unde caracterul 0 este caracterul cu
care se vor completa spaţiile goale.

În al doilea mesaj, prima instrucţiune de formatare a numelui produsului este %’.-20s. Aceasta
spune că variabila $product trebuie afişată cu aliniere la stânga și cu douăzeci de caractere, unde
spaţiile goale se vor completa cu puncte. Preţul se afişează în mod similar ca şi în primul mesaj,
cu deosebirea că acum caracterul care completează spaţiile goale nu este specificat, motiv pentru
care este folosit caracterul implicit space.

Când vreţi să suprapuneţi stringurile, folosiţi funcţia substr_replace(), care are forma de bază:

substr_replace(Variabila, „ caracterele cărora li se schimbă stringul ”,


1indexul caracterului iniţial, numărul de caractere care vor fi înlocuite)

Exemplu de utilizare:

1$numbers = "123456789123456789";
2echo substr_replace($numbers, "#########",2,8);
După executare, va fi scris:

12#########23456789

Exerciţiul nr. 1

În aplicaţie, intră următoarele variabile:

$userName şi $password

Verificați validitatea acestor variabile şi asiguraţi-vă ca ele să nu fie goale şi să nu conţină


următoarele caractere: <> (semnele pentru mai mic şi mai mare) şi ‘.

Dacă una dintre variabile este goală, executarea se întrerupe, în timp ce dacă există caractere
nedorite, acestea sunt eliminate din valoarea variabilei.

Valorile iniţiale ale variabilelor trebuie să fie:

$userName = "myName<";
$password = "myPa>sswo'rd";

Rezolvare:

1
2 <?php
3 function clean_string($string)
4 {
5 $string = str_replace("<", "", $string);
$string = str_replace(">", "", $string);
6 $string = str_replace("'", "", $string);
7 return $string;
8 }
9 $userName = "myName<";
10$password = "myPa>sswo'rd";
$userName = clean_string(trim($userName));
11$password = clean_string(trim($password));
12if(trim($userName) == "" || trim($password) == "")
13 die("invalid credentials");
14echo "valid credentials";
15?>
16

La ieşire va fi scris:

valid credentials
În cerinţa problemei sunt date valori iniţiale pentru variabile $userName şi $password. Ca să ne
ocupăm de aceste valori, creăm funcţia definită de utilizator, care va avea drept scop să se ocupe
de asta. Funcţia o vom numi clean_string. În cadrul funcţiei, asupra parametrului apelăm funcţia
încorporată deja cunoscută, str_replace. O vom apela de trei ori, ca să înlocuim fiecare dintre
caracterele solicitate în cerinţa problemei. După aceste modificări, funcţia returnează stringul
prelucrat.

La apelarea funcţiei clean_string, ca argument alocăm valoarea returnată de funcţia trim


încorporată, după ce îi atribuim ca argument stringul care se prelucrează.

La final, se verifică dacă stringurile sunt goale şi, dacă sunt, întrerupem codul:

1die("invalid credentials");

Exerciţiul nr. 2

Se dă următorul string:

$lipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting
industry. ";

Trebuie formatat textul în aşa fel încât să se formeze un rând nou după fiecare al 15-lea caracter:

Rezolvare, varianta 1:

Această soluţie va funcţiona numai în cazul controalelor care au posibilitatea de recunoaştere a


noului rând în text:

1$lipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting
industry.";
2echo wordwrap($lipsum, 15, "<br>");

Rezolvare, varianta 2:

1 $lipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting
industry.";
2 $lipsumArr = explode(" ", $lipsum);
3 $tmpContent = "";
4 for( $i = 0; $i < sizeof( $lipsumArr ); $i++ )
5 {
if((strlen($tmpContent . " ") + strlen($lipsumArr[$i])) < 15)
6 $tmpContent .= " " . $lipsumArr[$i];
7 else
8 {
9 if($tmpContent != "")
{
10 echo $tmpContent . "<br>";
11 }
12 $tmpContent = $lipsumArr[$i];
13 }
}
14echo $tmpContent;
15
16
17

$lipsum este variabila care conţine textul care va fi prelucrat. Cum nu vrem ca trecerea pe noul
rând să o facem la jumătatea cuvântului, întregul string trebuie împărţit în elementele şirului.
Tocmai asta se face cu metoda explode(), care acceptă doi parametri. Primul parametru este
separator, în timp ce al doilea parametru este stringul abordat. Acum, avem un şir pregătit de
cuvinte.

Creăm variabila $tempContent, care va reţine temporar stringul care trebuie prezentat pe pagină.
Folosind bucla for, în modul prezentat până acum trecem prin toate elementele şirului (toate
cuvintele).

În cadrul buclei, verificăm dacă numărul de caractere ale stringului este cel care prezintă
conţinutul variabilei $tmpContent, după concatenare cu spaţiu şi după adunare cu numărul de
caractere ale cuvântului în şir care corespunde iteraţiei, mai mic de 15. Dacă condiţia este
îndeplinită, asta înseamnă că cuvântul poate intra pe rând şi că trebuie verificat dacă mai poate fi
pus încă un cuvânt pe rând.

Dacă această condiţie nu este îndeplinită, înseamnă că pentru cuvânt nu e loc pe rând şi că acest
rând trebuie scris pe pagină.

Exerciţiul nr. 3

Se dă următorul string:

$lipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting
industry.";

Trebuie formatat stringul, în aşa fel încât, dacă are mai mult de 15 caractere, acesta să fie tăiat,
astfel încât ultimele trei caractere, până la al 15-lea, să fie puncte. De exemplu:

Lorem Ipsum ...

Rezolvare:

1<?php
2$lipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting
industry.";
3$izlaz = (strlen( $lipsum ) > 15) ?substr( $lipsum, 0, 12 )."...": $lipsum;
4echo $izlaz;
5?>
Tema de aici reprezintă un exemplu simplu de utilizare a funcţiei substr(), care lucrează cu trei
parametri. Primul parametru este string care se abordează, al doilea parametru este indexul iniţial
pentru tăierea stringului, în timp ce al treilea, numărul de caractere care va fi luat în considerare,
începând cu indexul iniţial. De asemenea, este folosit şi operatorul ternar. În paranteza pentru
acest operator, punem condiţia după care urmează semnul întrebării şi două valori posibile pentru
string. Stringurile se separă cu simbolul două puncte (:).

După executarea acestui operator, pe pagină trebuie să se prezinte valoarea variabilei care
salvează ieşirea.

Exerciţiul nr. 4

Scrieți un program care va returna, pentru stringul menţionat, numărul de cuvinte care se află în
el. Variabila string are următorul conţinut:

"Lorem Ipsum is simply dummy text of the printing and typesetting industry."

Rezolvare:

echo str_word_count("Lorem Ipsum is simply dummy text of the printing and


1typesetting industry.");

Soluţia după executarea programului este 12!

Scopul acestui exerciţiu este prezentarea funcţiei interesante str_word_count, care acceptă un
parametru obligatoriu şi două opţionale. Funcţia numără cuvintele aflate în string. Definind al
doilea parametru, de la funcţie se poate cere să returneze rezultatul specific.

Valorile posibile pentru al doilea parametru sunt:

 0 - Valoare implicită. Returnează numărul de cuvinte în string.


 1 - Returnează şirul care conţine ca elemente cuvintele din stringul dat.
 2 - Returnează şirul de cuvinte în care cheile poziţiei sunt cuvintele în string.

După executarea următorului cod: $name = \"James\"; echo \'My name is $name\'; , rezultatul pe
pagină va fi:
My name is $name
My name is James
'My name is $name'
'My name is James'
pe ecran se va semnala o eroare
………………..

Stringurile avansate şi patternurile


Unitate: 14 din 19 00:27:53

+Rezumat

În cadrul acestei lecţii, veţi învăţa funcţiile string avansate şi manipularea generală a stringurilor.
În lecţia precedentă, am vorbit despre stringuri. Am învăţat operaţiile de bază necesare pentru
producerea oricărui tip de aplicaţie web. În această lecţie, vom aprofunda aceste cunoştinţe şi
vom adăuga câteva noi.

Vom începe cu interpolarea variabilelor.

PHP este înzestrat cu o caracteristică foarte bună - este capabil să parseze un string, astfel încât
variabilele aflate în el să fie tratate altfel decât textul în sine. În lecţia precedentă, am abordat
funcţia printf, care face posibilă formatarea şablonului, după care vor fi trataţi parametrii funcţiei
printf("my variable %d", $x);

Însă, putem face acest lucru şi altfel:

1printf("my variable $x");

respectiv:

1echo "my variable $x";

Rezultatul va fi, în ambele cazuri: my variabile 2 (doi, din exemplu, este un număr arbitrar.
Bineînţeles că va fi emisă valoarea variabilei $x). PHP nu este chiar omnipotent în ceea ce
privește această procedură. Trebuie să avem grijă ca variabilele, pe care vrem să le tratăm ca
variabile, să nu-şi piardă contextul.

Să vedem următorul exemplu:

1echo "$a bcd";

Variabila $a va fi emisă în mod corespunzător, pentru că este separată de restul conţinutului


stringului. Dar în cazul în care linia arată astfel:

1echo "$abcd";

nu se va emite nici variabila $a şi nici restul textului, pentru că interpreterul va cere variabila cu
numele $abcd.
Dacă doriţi să implementaţi un string, astfel încât variabila şi restul stringului să fie unite, puteţi
folosi paranteze acolade ca separatori:

1echo "{$a}bcd";

sau operatorii de concatenare:

1echo $a ."bcd";<span style="font-size: 14px;"> </span>

În ambele cazuri, rezultatul va fi acelaşi: 2bcd (vă reamintim că valoarea 2 este doar ipotetică.
Aceasta poate fi orice valoare a variabilei $a).

Uneori, vom dori să obținem un efect invers. Vom dori ca variabila să nu fie tratată ca variabilă,
ci ca text (de exemplu, vrem ca textul stringului să fie „$a bcd“). În acest scop, vom acorda
atenţie ghilimelelor în PHP.

Am văzut că în PHP se poate crea un string în două moduri: cu ghilimele simple (' ') sau cu
ghilimele duble (" "). De obicei, facem aceasta dacă vrem ca ghilimelele să fie vizibile în textul
nostru. Nu contează în ce tip de ghilimele vom pune stringul, atâta timp cât acestea nu sunt
aceleaşi cu cele pe care vrem să le reprezentăm în interiorul acestui string:

1echo '"my" text';

Acest exemplu va emite pe pagină următorul rezultat:

"my" text.

Şi invers. Următorul exemplu:

1echo "'my' text";

va emite:

'my' text

Dar, de aceea:

1echo ""my" text";

va semnala eroare.

Bineînţeles, puteţi să puneţi ghilimelele după caracterul escape şi să-l emiteţi astfel: \"

Acum să revenim la interpolarea variabilelor. Aici, de asemenea, există o diferenţă atunci când
este vorba despre tipurile de ghilimele. Am văzut că ghilimele duble permit parsarea variabilei.
Pe de altă parte, ghilimelele simple nu parsează nici variabilele, nici caracterele speciale, astfel
că tot ceea ce puneţi între ele se va emite la fel:
1echo '$a bcd';

după care se emite:

$a bcd

Sintaxa herodoc

Deşi caracterele speciale şi marcajele HTML oferă o mare libertate în ceea ce priveşte emiterea
textului (puteţi crea orice formă doriţi), acesta nu este întotdeauna şi cel mai simplu mod de
formatare a unui text, mai ales dacă doriţi să copiaţi o formă textuală gata făcută. În acest caz,
mult mai practică este utilizarea stringului herodoc. Cu ajutorul acestei sintaxe, puteţi formata
chiar şi cele mai complexe stringuri. Se utilizează în felul următor:

Începutul stringului se marchează cu semnul <<< , după care urmează identificatorul, care poate
fi orice nume care nu se abate de la regulile standard de numire a variabilelor. De obicei, pentru
vizibilitate, identificatorul se scrie cu majuscule. După identificator, este obligatorie o linie nouă,
de unde poate să înceapă şi textul însuşi.

Sfârşitul textului se marchează, de asemenea, cu identificatorul, care trebuie precedat de o linie


nouă şi urmat de marcajul ;.

<<<MYTEXT
Title<br>
Content...
MYTEXT;

Un conţinut formatat astfel poate fi pus într-o variabilă sau poate fi trimis direct la ieşire:

$a=<<<MYTEXT
Title<br>
Content...
MYTEXT;
echo<<<MYTEXT
Title<br>
Content...
MYTEXT;

Stringurile herodoc sunt instrumente foarte puternice. Încercaţi să deschideţi codul-sursă al unei
pagini şi să îl copiaţi în stringul dvs. herodoc. Veţi vedea că tot codul va fi procesat în totalitate
fără probleme sau erori.

Deoarece herodoc face posibilă memorarea unor cantităţi mari de text, nu uitaţi că există o limită
de memorie permisă pentru scriptarea în PHP. În cazul în care exageraţi cu cantitatea textului,
PHP nu va putea să proceseze stringul dvs. şi se va semnala o eroare.
Lungimea stringului

Una dintre cele mai frecvent folosite funcţii asupra stringurilor este funcţia prin care se
determină lungimea acestora. Această funcţie se numeşte strlen.

Pentru a utiliza această funcţie (care, de altfel, este foarte simplă), ne vom uita mai întâi să
vedem din ce este alcătuit un string. De exemplu, textul my string este alcătuit din
caractere/litere. Fiecare dintre aceste caractere este, de fapt, un byte. Aceasta înseamnă că
stringul nostru nu este nimic altceva decât un şir de byți. Aceasta înseamnă că, dacă ne-am
adresa unui string prin şirul său, vom obţine, ca membri ai acestui şir, caracterele stringului
nostru? Da.

De exemplu:

1$a = "my text";


2echo $a[3];

După următorul cod, pe ecran va fi scris caracterul t, care este al doilea caracter din stringul
nostru (dacă este folosită indexarea bazată pe zero/zero based).

Fiindcă am constatat că stringul este un şir de caractere, funcţia strlen poate fi tratată ca o funcţie
care numără membrii acestui şir:

1echo strlen("my text");

Este important de știut că în momentul utilizării acestei funcţii, spre deosebire de alte limbaje, ea
nu are mecanismul zero terminated şi, atunci când ajunge la un caracter gol, ea nu întrerupe
numărătoarea în mod automat, ci o continuă, atâta timp cât există o valoare pentru caracterele din
variabila numărată.

În practică, aceasta înseamnă că exemplul:

1$a=" ";
2 echo strlen($a);

care într-un alt limbaj (cu o altă funcţie) ar produce rezultatul 0, produce aici rezultatul 5,
deoarece stringul este alcătuit din cinci caractere goale.

Iată un exemplu în care vedem cum putem să eliminăm spaţii dintr-un text:

1$s = "my text";


2for ($i = 0; $i < strlen ($s); $i++) {
3if($s[$i] != " ")
4echo $s[$i];
5}
Compararea stringurilor

Modul de bază pentru compararea stringurilor este cel cu ajutorul operatorului de comparare:

1echo "my text"=="my text";

Acest mod este bun dacă gestionăm valorile hardcoded. Dar, priviţi următorul exemplu:

1echo "1my text"==1;

Acest exemplu, la fel ca şi cel precedent, produce un rezultat corect, deşi, la prima vedere, cele
două părţi comparate nu au nicio similitudine.

Mai întâi, PHP a revizuit operanzii şi a văzut că este vorba despre compararea stringului cu un
int, ceea ce este imposibil. Din acest motiv a convertit implicit operandul stâng în int, fapt care a
redus valoarea operandului la 1 (singurul număr care există în string), iar în final s-a ajuns la
comparația între 1 şi 1, care produce rezultatul corect. Poate că la prima vedere nu pare că o
astfel de eroare s-ar putea produce, dar să nu uitaţi că în programe, în astfel de comparaţii, apar
de obicei nişte valori create dinamic (de exemplu, $a==$b).

Compararea stringurilor se poate executa şi altfel, şi anume prin funcţiile strcmp şi strcasecmp.
Aceste funcţii primesc, ca parametri, două stringuri care se compară şi ca rezultat returnează
zero, asta dacă stringurile sunt identice sau dacă numărul caracterelor este diferit:

1echo strcmp("my text","my text");

Acest exemplu emite valoarea 0.

Diferenţa dintre strcmp şi strcasecmp constă în faptul că funcţia strcasecmp nu este sensibilă la
litere majuscule şi minuscule:

1echo strcmp("My text", "my text"); // rezultatul este -1


2echo strcasecmp("My text", "my text"); // rezultatul este 0

Funcţiile returnează numere mai mici decât 0 în caz că string1 este mai mic decât string2, adică
numere mai mari decât 0 în caz că string1 este mai mare decât string2. Dacă stringurile sunt
identice, rezultatul returnat este 0.

Căutarea în interiorul stringului

Există posibilitatea de a căuta un anumit caracter sau o anumită secvenţă de caractere în


interiorul stringului. În acest scop, se foloseşte funcţia strpos.
Această funcţie acceptă ca parametri stringul iniţial şi secvenţa căutată, iar ca rezultat returnează
poziţia iniţială (indexul) a secvenţei căutate, respectiv returnează valoarea boolean false, asta în
caz că secvenţa căutată nu există.

1echo strpos("my text", "str");

Acest exemplu scrie pe pagină numărul: 4

De asemenea, funcţia poate să accepte şi al treilea parametru, cel opţional, care marchează locul
de la care apariţia caracterului căutat va fi luată în considerare:

1echo strpos("my textstr", "str", 5);

În acest exemplu, nu se iau în considerare apariţiile caracterului căutat înainte de al cincilea


caracter al stringului. Înseamnă că prima apariţie nu va fi luată în considerare. Rezultatul funcţiei
va fi numărul 7, pentru că prima ocurență are loc la caracterul cu numărul opt al stringului.

Modificarea stringului

În PHP, o parte a stringului se poate înlocui cu alta. Acest lucru se poate face cu ajutorul
funcţiilor menţionate, dar şi prin utilizarea funcţiilor scrise exclusiv în acest scop: str_replace şi
str_ireplace (aceeaşi funcţie care nu este sensibilă la litere majuscule şi minuscule):

1echo str_replace("my", "your", "my text");

Funcţia str_replace acceptă trei (sau patru) parametri. Primul parametru este partea căutată a
stringului, al doilea este partea care va fi inserată în locul părţii căutate şi al treilea este stringul
la care se face intervenţia. Al patrulea parametru, cel opţional, ne permite să punem într-o
variabilă numărul cazurilor (cases) găsite ale stringului căutat.

1$a=0;
2echo str_replace("my", "your", "my text", $a);
3echo $a;

Acest exemplu va produce valoarea unu, deoarece cuvântul "my" apare o singură dată în string.

Astfel, puteţi înlocui şi mai multe cazuri într-un singur string, cu ajutorul şirurilor (array):

1$arr1 = array("Java", "SQL", "CSS");


2$arr2 = array("PHP","MySQL","HTML");
3echo str_replace($arr1, $arr2, "I love Java",$a);

Acest exemplu va schimba textul în: "I love PHP".


Uneori, veţi dori să schimbaţi stringul la o anumită poziţie (index). De exemplu, dacă aţi
construit o listă pe baza unor date pe care le-aţi obţinut în mod secvenţial. Se poate întâmpla
foarte uşor ca aceste date să ajungă în următoarea formă:

1,2,3,4,5,

fiindcă, având în vedere că aţi creat lista în mod dinamic, nu ştiţi care este ultimul său membru şi
veţi rămâne cu o virgulă (sau un alt separator) în plus. În acest caz, funcţia substr_replace este o
soluţie excelentă:

1$x = "1,2,3,4,5,";
2echo substr_replace($x, "", strlen($x)-1);

Funcţia acceptă stringul cu rol de parametru, stringul care va fi inserat ca înlocuitor şi poziţia de
unde începe înlocuirea. Fiindcă nu cunoaștem lungimea stringului (lista poate fi de la 1 - 5 sau
poate fi şi 1 - 1000), pentru poziţie vom lua lungimea redusă cu unu (deci, ultimul element).

Separarea unei părţi din string

Prin funcţia substr puteţi izola o parte din string de pe o anumită poziţie. Această funcţie acceptă
trei parametri: stringul, indexul de început al izolării şi, opţional, numărul de caractere care vor fi
izolate.

1$x = "http://www.google.com";
2echo substr($x,7);

Acest exemplu va emite textul după cel de-al şaptelea caracter. Rezultatul este www.google.com.
Dacă nu introducem al treilea parametru, se preia stringul complet, de la poziţia iniţială. Dacă se
introduce al treilea parametru, se preia numărul de caractere menţionate în cel de-al treilea
parametru:

1$x = "http://www.google.com";
2echo substr($x,7,3);

Rezultatul exemplului este: www.

Formatarea stringului

Am vorbit deja despre formatarea stringurilor prin funcţia number_format. Această funcţie
oferă diversitate în ceea ce priveşte formatarea numerelor (mai ales notaţia zecimală):

1echo number_format(30.4000,3);
Primul parametru al acestei funcţii este numărul însuşi. Al doilea parametru este numărul maxim
de zecimale afişate. Ieşirea acestui cod este: 30.400.

Această funcţie poate să accepte şi doi parametri opţionali (trebuie utilizaţi împreună, în mod
obligatoriu), care reprezintă un caracter ce va separa zecimalele numărului şi un caracter care va
separa miile.

1echo number_format(30000,3,".",",");

Ieşirea este:

30,000.000

Puteţi declara anumite formate şi prin identificarea localizării, prin funcţia setlocale. În acest
scop, aveţi nevoie de numele grupului de formatare şi de numele localizării. Următorul exemplu
va formata toate înscrierile grupului LC_MONETARY, prin localizarea en_US:

1setlocale(LC_MONETARY, "en_US"); sau setlocale(LC_MONETARY, "me_JP");

Formatarea generică

Ne-am familiarizat deja cu acest tip de formatare în lecţiile precedente. Funcţiile sunt printf,
sprintf şi fprintf (diferenţele între aceste trei funcţii sunt numai în ceea ce priveşte tipul de ieşire.
Prima are o ieşire standard (pagină sau consolă), sprintf poate să returneze un rezultat, iar
fprintf va avea o ieşire spre un fişier).

Sintaxa formatării este următoarea:

1printf("My number: %d", 100);

Primul parametru al acestei funcţii (stringul My number: %d) este ceea ce va merge la ieşire, pe
când cel de-al doilea (şi toţi ceilalţi) va fi parametrul valoare care va înlocui identificatorul din
string (%d). În acest caz, identificatorul este d, ceea ce înseamnă că la ieşire va fi o valoare
zecimală, dar putem utiliza şi alte identificatoare. De exemplu: %b ar produce o ieşire binară:

1printf("My number: %b", 10);

În cazul unei astfel de formatări a stringului, nu sunteţi limitaţi la un singur identificator:

printf("My decimal number: %d, my binary number: %b, my floating point


1number: %f", 10,10,10);

Pentru formatarea string-ului, se pot utiliza următoarele valori:

 b – reprezentarea binară;
 c – afişează la ieşire caracterul care reprezintă valoarea numerică ASCII;
 d – afişează la ieşire un număr zecimal;
 e – transformă în număr cu exponent (printf("%e", 10); afișează ieşirea 1.000000e+1);
 u – reprezentarea nemarcată;
 f – afişează la ieşire un număr cu virgulă mobilă în funcţie de locaţia specificată printf
("%3.2f", $number);
 F – afişează la ieşire un număr cu virgulă mobilă fără localizare specificată;
 o – reprezentarea octală a numărului;
 s – string (printf("%s", "my text"););
 x – reprezentarea hexazecimală cu litere minuscule (ffffff),
 X - reprezentarea hexazecimală cu litere majuscule (FFFFFF).

Expresii regulate

Atunci când pe cale standard nu aveţi nicio posibilitate să rezolvați o operaţie asupra stringului
(de exemplu, codul este prea complex), puteţi utiliza expresiile regulate.

Expresiile regulate sunt seturi de reguli, pe baza cărora se caută un string.

De exemplu, dacă vrem să fim siguri că un string este scris sub formă de adresă e-mail, am putea
spune că pentru aceasta există câteva reguli:

 Trebuie să aibă un text la început, fără caractere speciale;


 Trebuie să aibă caracterul @ după textul iniţial;
 Trebuie să aibă un text după marcajul @;
 Apoi, trebuie să aibă un punct şi un text după punct.

Această descriere corespunde majorităţii adreselor de e-mail.

Fiindcă din descriere concluzionăm că ştim anumite caracteristici, dar nu şi care este
conţinutul exact al întregului string, acesta este locul potrivit pentru utilizarea expresiei regulate.

Pentru ca un text să fie tratat ca expresie regulată, trebuie să-i punem delimitatoare la început şi
la sfârşit. Aceste delimitatoare pot fi orice caracter, dar în practică în acest scop se foloseşte
deseori linia oblică /.

/my regular expression/

Tot ce se află în interiorul delimitatorului reprezintă conţinutul expresiei regulate, adică patternul
de comparare.

Funcţia care compară expresia regulată cu stringul se numeşte preg_match. Această funcţie (în
esenţă) acceptă doi parametri, şi anume: expresia regulată şi stringul care este comparat, şi
returnează rezultatul 1, dacă textul corespunde expresiei, şi 0, dacă nu corespunde. De fapt,
această funcţie returnează un număr. Următorul exemplu returnează rezultatul 1.
1echo preg_match("/mytext/","mytext");

Puteam face o astfel de comparaţie banală şi cu funcţiile standard. Expresiile regulate se


folosesc, de obicei, atunci când nu putem face comparaţia în niciun alt mod. Nu procedăm astfel
pentru că utilizarea lor este complicată, ci pentru că viteza lor nu este la nivelul funcţiilor
standard.

Pentru ca expresia regulată să aibă o funcţie, pe lângă delimitator, trebuie să-i mai introducem şi
alte elemente.

Meta-caracterele

Meta-caracterele sunt părţi ale expresiei regulate care identifică o anumită parte a textului:

 . - Reprezintă orice caracter din text;


echo preg_match("/my.tring/","myKtring"); //returneaza 0
 ˆ - Reprezintă începutul stringului;
 $ - Reprezintă sfârşitul stringului;
 \s - Reprezintă space;
echo preg_match("/my\sstring/","my text"); //returneaza 1
 \d – Reprezintă orice număr;
echo preg_match("/number \d/","number 5); //returneaza 1
 \w – Reprezintă orice cuvânt (word) din string.
echo preg_match("/my \w/","my text"); //returnează 1

Se pot grupa mai multe condiţii pentru o anumită parte a textului, cu ajutorul parantezelor drepte:

1echo preg_match("/a[bcd]e/","abe");

În exemplul de sus, este permisă una dintre cele trei alternative (b, c sau d) între caracterele a şi
e.

Sunt permise şi combinaţii de anumite intervale de caractere şi meta-caractere. Următorul


exemplu subînţelege litera iniţială a, apoi literele b sau c, urmate de un număr:

1echo preg_match("/a[bc\d]/","ab2"); //return 1

Cuantificatorii

Cuantificatorii determină de câte ori se va repeta o anumită condiţie într-o expresie regulată.

 Caracterul * poate să apară o singură dată, de mai multe ori sau să nu apară deloc:
echo preg_match("/my s*tring/","my sssstring"); // returneaza 1
echo preg_match("/my s*tring/","my string"); // returneaza 1
echo preg_match("/my s*tring/","my tring"); // returneaza 1

 Caracterul + poate să apară o singură dată sau de mai multe ori:

echo preg_match("/my s+tring/","my sssstring"); // returneaza 1


echo preg_match("/my s+tring/","my sssstring"); // returneaza 1
echo preg_match("/my s+tring/","my tring"); // returneaza 0

 Caracterul ? poate să nu apară deloc sau să apară o singură dată pe locaţia


respectivă:

echo preg_match("/my s?tring/","my tring"); // returneaza 1


echo preg_match("/my s?tring/","my string"); // returneaza 1
echo preg_match("/my s?tring/","my sstring"); // returneaza 0

 Caracterul {n,m} trebuie să apară minim de n ori şi maxim de m ori:

echo preg_match("/my s{1,3}tring/","my ssstring"); //


returneaza 1
echo preg_match("/my s{1,3}tring/","my sssstring"); //
returneaza 0

Expresii regulate în cadrul altor expresii regulate

O întreagă expresie se poate trata ca o unitate separată (un caracter). De exemplu, dacă vrem să
utilizăm un cuantificator asupra unei expresii, nu doar asupra unui caracter.

Marcajul pentru expresia regulată în cadrul expresiei regulate sunt parantezele rotunde
(paranteza deschisă rotundă şi închisă rotundă):

echo preg_match("/my (ab.) string/","my abc string"); //return 1<span


1style="font-size: 14px;"> </span>

În exemplul de sus, am spus că vrem ca şablonul (patternul) nostru să înceapă cu cuvântul my,
apoi trebuie să urmeze un spaţiu gol, apoi trei caractere ab şi orice alt caracter. La final,
încheiem expresia cu cuvântul string precedat de un spaţiu gol.

Am fi putut face acest lucru şi fără paranteze rotunde, dar, dacă vom dori să aplicăm un
cuantificator la întregul pattern (ab.), de exemplu dacă aceasta trebuie să se repete o dată sau de
mai multe ori (+), am putea, pur şi simplu, să schimbăm expresia:

echo preg_match("/my (ab.)+ string/","my abcabdabe string"); // retur<span


1style="font-size: 10px;">n</span><span style="font-size: 10px;">eaza
1</span>
Expresiile regulate reprezintă o dimensiune aparte a programării şi nu trebuie să vă stresaţi prea
mult cu ele. Deşi foarte eficiente, rareori veţi avea nevoie de şablonul (patternul) expresiei
regulate care s-ar putea nici să nu existe. Astfel, s-ar putea să petreceţi mai mult timp căutând un
şablon corespunzător, decât construind unul propriu.

Rezultatul executării codului:


1
<?php
2$s = "my text";
3for ($i = 0; $i < strlen ($s); $i++) {
4 if($s[$i] != " ")
5 echo $s[$i];
}
6?>
7
va fi:
mytext
my text
My text
MY TEXT

Exerciţiul nr. 1

În aplicaţie, intră următoarea variabilă:

$string = "myMail@mail.ml";

Scrieţi expresia regulată cu care se va verifica dacă valoarea variabilei este adresa de e-mail.

Rezolvare:

1<?php
2$string = "myMail@mail.ml";
3$pattern = "/^[a-zA-Z0-9]+\@[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/";
4echo preg_match($pattern,$string);
5?>

Funcţia preg_match verifică suprapunerea stringului cu patternul definit. Trebuie doar explicată
expresia regulată definită. Cu simbolul ^ se defineşte începutul expresiei după care urmează un
şir de caractere permise de la a la z (indiferent de majuscule şi minuscule). De asemenea, este
permis să se seteze şi cifre, ceea ce definim cu intervalul cuprins între 0 şi 9. Acest şir poate să
apară de mai multe ori. Apoi se cere introducerea caracterului @ urmat de şirul de caractere deja
cunoscut. De asemenea, se cere şi introducerea punctului urmat de şirul de caractere asemănător
cu cel menţionat, dar fără permisiunea de introducere a cifrelor. Acest ultim şir trebuie să aibă 2
sau 3 caractere după care urmează finalul lui pattern.

Exerciţiul nr. 2

Se dă următoarea variabilă:

$string = "http://myPage.php?id=25&cat=18&user=34";

Preluaţi toţi parametri şi puneţi-i în şirul asociativ.

Rezolvare:

1
2 <?php
3 $string = "http://myPage.php?id=25&cat=18&user=34";
$pars = explode("?",$string);
4 $pars = explode("&",$pars[1]);
5 $parsedPars=array();
6 for($i=0;$i<sizeof($pars);$i++)
7 {
8
9 $currentParam = explode("=",$pars[$i]);
$parsedPars[$currentParam[0]] = $currentParam[1];
10 }
11print_r($parsedPars);
12?>
13

Deoarece parametrii se află după semnul întrebării în stringul care este dat, apelăm funcţia
explode şi ca separator punem "?". Acum, avem un şir cu două elemente. Pe poziţia marcată cu
indexul 1, se află parametrii care ne interesează. Parametrii sunt separaţi între ei cu semnul "&"
şi de aceea mai efectuăm un explode. După aceea în variabila $pars am primit un şir cu trei
elemente. De aceea trecem prin bucla for şi scoatem cheile şi valorile. De asemenea,
facem asta cu funcţia explode, dar de data aceasta ca separator punem semnul "=". La final,
trebuie doar să prezentăm rezultate pe pagină:

1print_r($parsedPars);

Exerciţiul nr. 3

Se dă următorul string url:

$string = "http://myDomain/home/index.php?id=25&cat=18&user=34";

Izolați doar domeniul cu folderele şi cu denumirea paginii (myDomain/home/index.php).


Rezolvare:

<?php
$string = "http://myDomain/home/index.php?id=25&cat=18&user=34";
1$pars = preg_replace("/http:\/\//","",$string);
2$pars = preg_replace("/\?[a-zA-Z0-9=&]+/","",$pars);
3print_r($pars);
4?><br><br>Cu această problemă este prezentat încă un exemplu de folosire a
5funcţiei str_replac dar de data această se folosesc şi expresii regulate. În
primul apel al funcţiei, se înlătură partea iniţială a stringului, în timp
6ce în al doilea apel se înlătură stringul final. La final, pe pagină se
prezintă rezultatul căutat.<br><br>

…………………………………………………………

Modul 6 Securitatea şi debugging-ul

Conceptele de securitate
Unitate: 15 din 19 00:18:41

+Rezumat

În cadrul acestei lecţii, ne vom familiariza cu conceptele de securitate pe web. După cum ştim,
site-urile web sunt alcătuite din componente de client şi de server. În această clasificare, putem
spune că, atâta timp cât site-ul nostru se află în contextul de client, sistemul este complet sigur,
deoarece nu are nicio legătură cu serverul. Dar, în momentul în care se desfăşoară un proces
definit de utilizator pe server, un site devine vulnerabil.

Să vedem ce se întâmplă în timpul procesului de emitere a unei pagini HTML statice. Aplicaţia
de client trimite cererea către serverul web şi acesta răspunde prin găsirea şi emiterea
documentului HTML solicitat. Într-un astfel de proces, nu este loc pentru nimic altceva, decât
pentru seria de activităţi menţionate, motiv pentru care această aplicaţie este practic
indestructibilă.

Procesul de creare şi emitere a unei pagini web dinamice mai conține câţiva paşi. La început,
aplicaţia de client cere şi în acest caz un anumit document, dar serverul, în loc să-l găsească şi să-
l expedieze, expediază întreaga cerere către scriptul de server. Acesta o procesează şi o
emite spre ieşire (către client). Această procesare reprezintă un punct-cheie pentru securitatea
unei aplicaţii web, deoarece dacă utilizatorul reuşeşte să-și infiltreze partea sa de cod în scriptul
de server, va obţine astfel posibilităţi nelimitate de manipulare a serverului.

Aşadar, aplicaţia este foarte vulnerabilă la intrare. De aceea, este foarte important să asigurăm tot
ce intră în ea. Această securitate o vom crea dacă controlăm toate intrările (inputurile).

Ce sunt de fapt inputurile în aplicaţia web?


Pentru ca un utilizator să ajungă la codul de server al unei aplicaţii (prin această aplicaţie), este
necesar să i se adreseze utilizând anumiţi parametri. Aceşti parametri ajung, de obicei, la
aplicaţie printr-un formular (post) sau printr-un string URL parametrizat (get). Când unul dintre
aceşti parametri ajunge la server, serverul îl pune într-o variabilă corespunzătoare. Aceste
variabile sunt unice şi accesibile pentru contextul complet al aplicaţiei, motiv pentru care se şi
numesc variabile superglobale.

Majoritatea superglobalelor, la fiecare cerere şi răspuns, se deplasează de la client la server şi


invers. Din acest motiv, acestea sunt considerate impure şi necesită un tratament special pentru
ca utilizarea lor să fie în totalitate sigură.

Deoarece în acest moment nu ştim tot ce este necesar pentru procesarea tuturor aspectelor legate
de securitatea în PHP (deoarece nici nu am început, de fapt, să studiem aplicaţii web), pe
parcursul acestor cursuri vom reveni de mai multe ori la securitate.

Noţiunea de listă albă şi de listă neagră

Am menţionat deja că majoritatea intrărilor într-o aplicaţie se datorează controalelor care, în


general, sunt o sursă nesigură. De aceea, la fiecare intrare de informaţii de acest tip se efectuează
o anumită filtrare. Înainte de a începe să descriem aspectele filtrării, trebuie să ne gândim ce
anume vom filtra.

Când filtrăm datele, putem transmite aplicaţiei unul dintre următoarele două lucruri:

 să nu permită accesul nimănui, dacă nu sunt îndeplinite anumite condiţii;


 să permită accesul numai celor care îndeplinesc anumite condiţii.

Aceste două concepte se numesc lista neagră şi lista albă.

Diferenţa dintre acestea este că lista neagră solicită mult mai puţină atenţie fiindcă, după ce
declarăm obiectele fără acces la structură, aceasta va fi accesibilă tuturor celorlalte obiecte.

Lista albă este considerată drept concept de securitate mai bun decât lista neagră, pentru că
intrarea este limitată numai la valorile aşteptate, aşadar un obiect nedorit are mult mai puţine
şanse să treacă.

Intrarea/Inputul

După cum am spus deja, primul punct vulnerabil în sistem este variabila superglobală. Acesta
este totodată şi locul în care codul nostru de server are o oarecare posibilitate de control.

Primul lucru pe care îl putem controla este dacă utilizatorul corespunde condiţiilor noastre sau
nu/dacă este valid sau nu. În cazul unui utilizator care nu este înregistrat în sistemul nostru,
putem verifica de unde a venit acesta (dacă trebuie să procesăm datele dintr-un formular, acest
formular trebuie să provină dintr-o sursă sigură şi cunoscută). Locaţia de pe care
utilizatorul ajunge pe pagina noastră se numeşte referrer.

Dacă ne aşteptăm ca utilizatorul să fie înregistrat în sistem, vom efectua o verificare de sistem
(prin cookie, session sau baza de date).

Acesta este unul dintre cele mai sigure moduri de alocare a datelor.

După ce utilizatorul a fost verificat, următorul pas este introducerea, respectiv a superglobalelor
care conţin această introducere. În aplicaţiile web, utilizatorul ne poate provoca daune grave
numai prin script de server sau prin script SQL. De aceea, acest tip de introducere trebuie adesea
prevenit. Acest lucru se face cel mai bine prin limitarea utilizatorului, care trebuie astfel
să introducă numai un conţinut exclusiv valid.

De exemplu, dacă aplicaţia noastră are control asupra introducerii textului şi în acest control
trebuie introduse numele şi prenumele, noi putem verifica pe server dacă utilizatorul a introdus
numai litere. Dacă textul conţine un caracter special sau un număr, putem elimina această dată şi
putem cere o nouă introducere.

1ctype_alpha("myname");

Această funcţie va returna rezultatul true, dacă parametrul conţine numai litere sau dacă
utilizatorul trebuie să introducă o valoare numerică:

1is_numeric("1234");

Funcţia returnează true dacă parametrul introdus este un număr.

Ieşirea/Outputul

În PHP, probabil că ieşirea aplicaţiei noastre va fi un document HTML sau o structură serializată
de date. În orice caz, momentul în care aplicaţia noastră îşi va arăta punctele slabe este tocmai
ieşirea.

De exemplu, dacă utilizatorul a introdus scriptul de client Cross Site (despre care vom vorbi în
lecţia următoare), acesta se va manifesta la ieşire, dar nu va avea prea multă influenţă asupra
sistemului. Pe de altă parte, scriptul de client poate afecta clientul.

De aceea, trebuie să efectuăm un anumit tip de filtrare şi la ieşire. Această filtrare subînţelege
mai întâi excluderea a tot ceea ce poate fi executat în formă de script. Acest lucru ar fi destul de
simplu, dacă uneori nu ar trebui să fie emis pe pagini tocmai un astfel de conţinut de script. De
exemplu, un forum care se ocupă cu scriptarea de client, unde toată lumea își trimite codurile
scripturilor lor. Dacă am face o astfel de filtrare, care ar elimina toate scripturile, postările de pe
acest forum şi-ar pierde scopul. De aceea, în astfel de situaţii se face aşa-numitul HTML
encoding (şi despre acesta vom vorbi mai mult în lecţia următoare), care emite conţinuturile
HTML (scripturi de client şi altele) într-o formă care nu poate face nimic, deoarece tag-urile sunt
emise prin reprezentarea lor HTML codată. Acest lucru este este mult mai uşor de efectuat decât
pare la prima vedere. Ştim că scripturile se află în taguri <script>. Când browserul ajunge la un
astfel de tag, el emite scriptul de client. Dar, dacă ajunge la următorul tag: <script>, va emite
textul <script> fără să trateze acest text ca începutul unui script.

Desigur, în acest scop vă puteţi crea propria funcţionalitate, care va procesa stringurile în modul
în care doriţi sau puteţi utiliza nişte funcţii gata făcute:

 htmlspecialchars("<script>");

Va transforma stringul respectiv în <script>;

 htmlspecialchars_decode("<script>");

şi, invers, va transforma stringul codat HTML într-unul obişnuit.

Însă, în cele mai frecvente cazuri, soluţiile gata făcute nu se potrivesc nevoilor dvs. (pentru că, de
exemplu, veţi dori totuşi să omiteţi ceva). În mod concret, funcţia din exemplul de mai sus
nu codifică ghilimelele simple care pot provoca daune atunci când baza de date este gestionată
(deşi puteţi introduce aceasta ca parametru (htmlspecialchars("'''", ENT_QUOTES))).

Register globals

Din punct de vedere a securităţii, acestea pot fi un punct foarte slab într-o aplicaţie web. Register
globals este o opţiune care se află în fişierul php.ini, dar care se poate seta şi prin funcţia
ini_set() (care setează parametrii prin aplicaţia propriu-zisă).

Acest lucru se poate îmbunătăţi şi dacă la începutul codului puneţi valoarea iniţială a variabilei,
dar cu siguranţă este cel mai bine să se dezactiveze opţiunea register globals.

Marcajul register globals este menţionat aici doar ca o notă pentru utilizatorii care lucrează cu
versiunile vechi de PHP. Începând cu versiunea 5.4.0 de PHP, această funcţionalitate se
consideră ca şi depăşită şi este eliminată din configuraţia PHP.

Baza de date

Încă un punct critic în ceea ce priveşte securitatea unei aplicaţii PHP este şi sursa de date (aici
vorbim despre o aplicaţie mai serioasă care presupune şi o sursă de date). Aceste surse pot fi
baza de date, fişierele sau reţeaua.

În ceea ce privește bazele de date, cel mai vulnerabil punct al acestora sunt interogările pe care i
le adresăm. Din această cauză este deosebit de important să filtrăm datele utilizatorului înainte de
a le expedia către bază, pentru a nu se produce SQL injection (vom discuta mai mult despre
aceasta în lecţia următoare). Pentru filtrare, putem utiliza funcţiile menţionate sau pe cele proprii.
Deseori, pentru conţinutul care serveşte pentru verificare (parole) se foloseşte şi un algoritm
unidirecţional de codificare. Aceasta este o metodă excelentă de securitate, fiindcă, după ce
parola este codificată astfel, nu va mai putea fi accesată (doar dacă este cunoscută):

1$password=md5("myPassword");

O parolă codificată nu mai poate fi returnată, ci doar verificată, printr-o codificare repetată:

$password=md5("myPassword");
if($password=="ab6890bf5bb25b645a5c671d9ff61a3a")
.... o logica de securitate a aplicatiei

Bineînţeles, codul dvs. nu va arăta niciodată astfel (pentru că în acest caz parola este codificată la
maxim în program), însă partea criptată va fi extrasă dintr-o sursă (baza de date) şi în acest mod
comparată.

File System/Sistemul de fişiere

După cum ştim, PHP poate accesa direct sistemul de fişiere, ceea ce poate crea posibilitatea ca
un potenţial hacker să intervină în mod nedorit în aplicaţia noastră. Cel mai periculos moment
este acela când includem fişierele în aplicaţie (include, require etc.). Dacă, de exemplu, aplicaţia
noastră încarcă un anumit fişier pe baza unui parametru, utilizatorul poate expedia cu uşurinţă un
fişier propriu prin acest parametru (pe propriul server), care, chiar dacă este emis de pe o locaţie
complet diferită, va funcţiona în contextul serverului şi al aplicaţiei noastre şi astfel va avea toate
drepturile ca orice altă aplicaţie de-a noastră.

De exemplu, dacă aplicaţia noastră construieşte o pagină în aşa fel încât pe baza parametrilor să
se încarce un anumit fişier:

include = $GET_['page'] + ".php"; // $GET este un sir asociativ


de parametri din stringul url

În acest caz, utilizatorul ar putea, pur şi simplu, ca în locul stringului nostru URL (care este, de
exemplu, ?page=myPage) să introducă http://userdomain.com/userFile (unde fişierul:
userFile.php există într-adevăr pe serverul respectiv).

În acest caz, userFile.php va fi implementat în pagina noastră, iar conţinutul acestuia ar putea
fi atât de dăunător în contextul aplicaţiei noastre, încât cel care l-a introdus îşi va putea atinge
scopurile maliţioase fără nicio problemă.

Ca și în cazul modalităţilor de atac de mai sus, şi pentru acesta există anumite soluţii simple, care
se bazează pe listele albe şi negre. În acest caz, putem crea o listă albă de fişiere permise pe
care o putem verifica la fiecare încărcare a fişierului extern. De exemplu:
$permittedPages = array("myPage","yourPage");
if in_array($_GET['page'],$permittedPages);
include $page + ".php";

În această lecţie, am abordat câteva concepte de securitate care se referă la PHP şi la mediul său.
Deocamdată este suficient să ştiţi doar cum funcţionează securitatea în PHP, precum şi cele
mai simple modalităţi de aplicare a mecanismelor de securitate. Mai târziu, pe
parcursul celorlalte cursuri şi lecţii, vom procesa şi alte tehnologii de securitate în contextul
tehnologiei studiate în acel moment.

Acestea sunt conceptele standard de securitate în PHP şi pot fi privite mai degrabă ca metode de
prevenire, decât ca pericole în adevăratul sens al cuvântului (nu pentru că nu ar exista pericole, ci
pentru că suntem conştienţi care sunt aceste pericole şi ştim cum să ne ferim de ele).
Aşadar, aceste metode trebuie tratate astfel - ca nişte vaccinuri pentru aplicaţiile dvs. împotriva
bolilor cunoscute.

Cum putem descrie noţiunea de listă albă?


lista albă îi lasă să treacă doar pe cei care îndeplinesc anumite condiţii
lista albă nu lasă pe nimeni să treacă, dacă nu îndeplineşte anumite condiţii
lista albă nu lasă pe nimeni să treacă
lista albă îi lasă pe toţi să treacă

Exerciţiul nr. 1

În aplicaţie intră variabila:

$page = "allUsers.php";

Creați mecanismul care, prin lista albă, va asigura încărcarea sigură a acestei pagini de pe sistem.

Rezolvare:

1
<?php
2$allPages = array("allUsers.php","anyOtherPage.php");
3$page = "allUsers.php";
4if(in_array($page,$allPages))
5 include $page;
6 else
echo "unknown page";
7?>
8
Ideea de validare prin listă albă presupune existenţa listei de introduceri pe care le considerăm
permise. În cazul nostru, acesta este şirul fişierelor permise pentru includere:

1$allPages = array("allUsers.php","anyOtherPage.php");

Variabila $page conţine data de intrare care trebuie verificată în listă. Pentru această verificare,
folosim controlul if al fluxului în combinaţie cu funcţia in_array. Această funcţie verifică dacă
elementul căutat se află în şir. Dacă rezultatul căutării va fi pozitiv, în locul apelării se întoarce
valoarea boolean TRUE, în caz contrar, FALSE. Dacă introducerea corespunde listei, are loc
includerea:

1include $page;

În caz contrar, se prezintă notificarea:

1echo "unknown page";

Exerciţiul nr. 2

Validați sesiunea pe baza lui User Agent. După validarea realizată cu succes, trebuie regenerate
sesiunile ID. Dacă validarea nu este bună, trebuie întreruptă executarea aplicaţiei şi emis mesajul
conform căruia utilizatorul nu este valid.

Rezolvare:

1
2 <?php
3 if(!isset($_SESSION))
session_start();
4
5 if(!isset($_SESSION['ua']))
6 die("Invalid user");
7
8 $currentUserAgent = $_SERVER['HTTP_USER_AGENT'];
9 $sessionUserAgent = $_SESSION['ua'];
10
11 if($sessionUserAgent != $currentUserAgent)
die("Invalid user");
12 echo "valid user";
13 session_regenerate_id(true);
14?>
15

Verificăm sesiunea şi dacă trebuie să o activăm. De asemenea, verificăm dacă este setată
cheia "ua" şi dacă nu întrerupem executarea în continuare a programelor.
Variabila $currentUserAgent primeşte valoare curentă
pentru $_SERVER['HTTP_USER_AGENT'], în timp ce variabila $sessionUserAgent primeşte
valoarea pentru $_SESSION['ua'], respectiv valoarea cunoscută pentru HTTP_USER_AGENT.

Acum, putem să verificăm dacă valorile acestor două variabile se suprapun. Dacă da, se întrerupe
executarea programului. Dacă îndeplinirea acestei condiţii nu este cazul, se prezintă mesajul de
notificare şi generarea unui nou id de sesiune.

Notă:

În exemplu, se menţionează variabila superglobală $_SESSION. De obicei, în ea se


depozitează date referitoare la sesiunea activă a utilizatorului. Despre sesiuni va fi vorba
într-unul din cursurile care urmează, iar acum această sesiune se poate trata doar ca un
simplu şir asociativ. Funcţia session_start inițializează sesiunea, pe când funcţia
session_regenerate_id regenerează numărul sesiunii.
……………………….

Validarea şi filtrele de validare


Unitate: 16 din 19 00:11:48

+Rezumat

În cadrul acestei lecţii, veţi învăţa conceptele de bază a validării şi importanţa ei, dar veţi
dobândi şi cunoştinţe din domeniul securităţii, precum şi cât este de importantă aceasta pentru o
aplicaţie web.

Pe internet, aplicaţiile web sunt accesibile pentru oricine are un calculator şi acces la internet. De
aceea, securitatea este unul dintre factorii cei mai importanţi atunci când construim aplicaţii web
serioase.

Securitatea reprezintă o parte a programării care nu este deosebit de interesantă. Se rezumă la o


anticipare cât mai eficientă a posibilităţilor de intruziune nedorită pe care un utilizator poate să le
suporte şi la prevenirea acţiunilor nedorite, prin măsuri corespunzătoare de securitate.

Deşi presupunem că ştiți deja, vă reamintim că datele care nu sunt vizibile în browser nu
înseamnă că sunt invizibile şi în codul-sursă HTML. De exemplu, controlul ascuns (hidden) nu
se vede decât dacă accesăm codul-sursă HTML, ceea ce înseamnă că nu trebuie să punem în el
nimic din ceea ce un utilizator nu ar trebui să vadă.

Apoi, vom seta proprietatea style.display a obiectului HTML. Dacă valoarea acestei proprietăţi
(property) este setată la none, obiectul nu va fi vizibil, dar va rămâne vizibil în codul-
sursă HTML.
O atenţie deosebită (în anumite locuri) trebuie acordată gestionării lui AJAX. Deşi AJAX nu este
vizibil în browser, este vizibil în HTML Source, împreună cu informaţiile pe care le transmite
(cu excepţia cazului în care acestea sunt generate în timp real, dar şi atunci este posibil să
ajungem la ele prin analiza codului). Pe de altă parte, AJAX utilizează, de obicei, aplicaţia de
server pentru completarea cu date, aşadar şi această aplicaţie trebuie
protejată împotriva accesului direct.

Un alt aspect care trebuie luat în considerare este cel referitor la locurile în care utilizatorul are
dreptul să introducă date. Acest aspect se referă la formulare sau la controalele formularului.

Un subiect aparte (şi uriaș) îl constituie modurile în care un utilizator poate perturba o
aplicaţie. De exemplu, să ne închipuim că controlul nostru acceptă doi parametri: numele de
utilizator şi parola şi că îi verifică printr-o interogare adresată bazei de date. Va fi de ajuns ca
utilizatorul să introducă o valoare într-unul dintre aceste două câmpuri (de exemplu: ‘ OR 1=1
‘) şi să îndeplinească condiţia de intrare în partea protejată a site-ului.

În cazul în care utilizatorul are posibilitatea să introducă date pe site (de ex. pe un forum), dacă
nu se efectuează validarea acestor date, utilizatorul ar putea să-și introducă fără probleme
scriptul, care, odată emis pe pagină, va fi şi executat.

Aceste două moduri de intrare nedorită pe site-uri, care sunt cele mai frecvente şi cele mai
simple (se numesc sql injection, respectiv Cross Site Scripting), trebuie prevenite prin luarea
anumitor măsuri. Atacurile hackerilor nu pot fi prevenite în totalitate, dar un programator trebuie
să facă tot ce-i stă în putinţă ca să-şi protejeze aplicaţia cât mai bine.

Validarea de client

Despre validarea de client nu vom vorbi foarte mult. Pe scurt, trebuie să prevenim introducerea
de date nedorite în controalele din partea de client. Acest lucru trebuie făcut prin JavaScript,
unde vom efectua validarea, înainte ca datele din control să fie expediate către server. De
exemplu:

1 <script type = "text/javascript">


function validationMail(field, alerttxt)
2 {
3 with (field)
4 {
5 apos = value.indexOf("@");
6 dotpos = value.lastIndexOf(".");
if (apos < 1 || dotpos-apos < 2)
7 {alert(alerttxt); return false;}
8 else {return true;}
9 }
10}
11
function formValidation(thisform)
12{
13with (thisform)
14{
15if (validationMail(email,"It is not e-mail address") == false)
{email.focus();return false;}
16}
17}
18</script>
19</head><body>
20<form action=""
onsubmit="return formValidation(this);"
21method="post">
22Email: <input type="text" name="email" size="30">
23<input type="submit" value="Submit">
24</form>
25
26
27
28
29

Problema este că o astfel de validare nu are un alt scop, decât acela de a-l ajuta pe utilizator în
procesul de introducere a datelor. Utilizatorul poate să mute întreaga pagină pe serverul său, îi
poate schimba conţinutul, poate să elimine validarea şi poate expedia orice date doreşte.

Din acest motiv, validarea principală trebuie desfăşurată pe partea de server a aplicaţiei.

Validarea de server

Verificarea lui referrer

Utilizatorul nu poate să obţină asupra serverului controlul pe care îl poate obține asupra
clientului. Şi anume, utilizatorul poate să trimită date către server printr-un sistem, iar
programatorul este dator să creeze acest sistem, astfel încât să poată preveni toate ameninţările
posibile.

În lecţiile precedente am menţionat termenul de "referrer". Acesta reprezintă locaţia de la


care browserul a ajuns în locaţia curentă. Se recomandă ca înaintea executării codului pe o
pagină „sigură”, să verificăm de unde a ajuns acesta aici şi să continuăm executarea numai dacă
este vorba de o locaţie acceptată. Putem încerca acest lucru pe un exemplu cât se poate de
simplu. Să creăm un document PHP, test.php cu următorul conţinut:

1<?php
if(isset($_SERVER['HTTP_REFERER'])) {
2 echo $_SERVER['HTTP_REFERER'];
3 }
4?>
5<br>
6<a href = "test.php">referer check</a>
7

Dacă deschidem această pagină prima dată, în browser va fi afişat doar linkul „validarea
referrerului” (referer check). Dar, dacă dăm clic pe link, pe pagină se va afişa şi referrer,
respectiv, pagina de la care a venit browserul, care în acest caz, este una şi aceeaşi pagină.

Mai rămâne să vă hotărâţi prin ce logică veţi verifica venirea (dacă va fi doar validarea
domeniului sau a unei locaţii exacte) şi, în mod condiţionat, să executaţi sau nu restul paginii.

HTML encode/disarm

Termenul de Cross Site Scripting, menţionat la începutul lecţiei, este foarte uşor de detectat şi
eliminat din codul de server. Este de ajuns să trecem fiecare intrare de utilizator printr-o funcţie
care va converti caracterele periculoase într-un format mai sigur (codul ASCII) şi să le lăsăm să
treacă astfel mai departe.

De exemplu:

1function sanitiseText($text)
2{
3$text = str_replace("<", "<", $text);
4$text = str_replace(">", ">", $text);
5}

Filtre de validare

PHP are încorporate şi filtre de validare, care se pot realiza prin funcţia filter_var(). Această
funcţie operează dacă îi sunt expediate stringul şi tipul de validare cu rol de parametri. De fapt,
funcţia filter_var() are două forme de funcţionare. Una este validarea datelor, care efectuează
validarea şi afișează rezultatul validării, iar a doua este „sterilizarea” (sanitize) datelor, care pur
şi simplu aranjează datele; ceva asemănător cu pasajul de mai sus, unde am făcut acelaşi lucru în
mod manual. Modul în care va funcţiona funcţia depinde de tipul de validare expediat.

Acest exemplu verifică dacă stringul este un URL valid:

1<?php
2$url = "http://www.mysite.com";
if(filter_var($url, FILTER_VALIDATE_URL))
3 echo("OK");
4else
5 echo("Error");
6?>
7

Acest exemplu corectează erorile (caracterele interzise) din denumirea URL-ului:

1<?php
2echo filter_var("http://www.myšššsite.com", FILTER_SANITIZE_URL);
3?>

PHP recunoaşte următoarele filtre de validare:

 FILTER_CALLBACK
Filtru care apelează funcţia definită de utilizator pentru procesarea conţinutului;
 FILTER_SANITIZE_STRING
Elimină tag-uri şi caractere speciale (HTML encode);
 FILTER_SANITIZE_STRIPPED
Elimină tag-uri şi caractere speciale (HTML encode);
 FILTER_SANITIZE_ENCODED
Codificarea URL a stringului;
 FILTER_SANITIZE_SPECIAL_CHARS
Elimină caractere speciale;
 FILTER_SANITIZE_EMAIL
Pregăteşte stringul în format de e-mail;
 FILTER_SANITIZE_URL
Pregăteşte string-ul în format URL;
 FILTER_SANITIZE_NUMBER_INT
Elimină literele şi lasă doar numerele şi operatorii aritmetici;
 FILTER_SANITIZE_NUMBER_FLOAT
Elimină literele şi lasă doar numerele, operatorii aritmetici, punctul şi semnul E pentru
exponent;
 FILTER_SANITIZE_MAGIC_QUOTES
Adaugă backslash în faţa ghilimelelor duble;
 FILTER_VALIDATE_INT
Verifică dacă valoarea este integer;
 FILTER_VALIDATE_BOOLEAN
Verifică dacă valoarea este Boolean;
 FILTER_VALIDATE_FLOAT
Verifică dacă valoarea este float;
 FILTER_VALIDATE_REGEXP
Verifică valoarea în funcţie de expresia regulată;
 FILTER_VALIDATE_URL
Verifică dacă valoarea este scrisă ca un string URL valid;
 FILTER_VALIDATE_EMAIL
Verifică dacă valoarea este scrisă ca adresă de e-mail validă;
 FILTER_VALIDATE_IP
Verifică dacă valoarea este scrisă în format de IP valid.

Asupra unui şir (array) de date se poate executa o serie întreagă de condiţii de validare, prin
comanda filter_var_array().

Criptarea pe serverul web nu are sens dacă scripturile, care folosesc schemele de criptare, nu se
află pe serverul care permite SSL (Secure Socket Level - protocol care se foloseşte pentru
criptarea informaţiilor prin intermediul internetului). SSL asigură ca toate datele pe care le
introduce clientul pe pagina sa să fie criptate de browser înainte ca acestea să fie trimise către
server, iar apoi, aceleaşi date sunt decriptate de server când ajung pe acesta.

hash - extensia criptografică

Această extensie asigură criptarea mesajelor în aşa fel încât acestea sunt trase printr-un număr
mare de algoritmii hash oferiţi. Pentru utilizarea acestei extensii, nu este necesară o instalare
suplimentară, deoarece, conform standardului, aceasta este încorporată în PHP.

Funcţia hash() generează valoarea hash din mesajul transmis. Pentru o funcţionare corectă a
funcţiei, este necesar a-i transmite doi parametri obligatorii, şi după necesitate şi al treilea
parametru care este opţional.

Revizuirea funcţiei s-ar putea reprezenta în felul următor:

hash ( $algo , $data [,bool $raw_output = false ] )

$algo - primul parametru care reprezintă alegerea algoritmului care va fi folosit. Revizuirea
algoritmilor disponibili se poate obţine cu funcţia hash_algos() în felul următor:

print_r(hash_algos());

Pe pagină vor fi afişaţi algoritmii. Unii dintre cei mai des folosiţi sunt: md5, sha256, haval160,4
etc.

$data - mesajul va fi hash-uit.

$raw_output - valoarea default a acestui parametru este FALSE. Dacă valoarea acestuia o setăm
explicit la TRUE, atunci va fi returnată o dată binară neprocesată.

Exemplu:

Dacă, cu ajutorul algoritmului md5, vrem să creăm un hash din cuvântul admin, am fi scris
următoarele:
1echo hash("md5", "admin");

Rezulatul obţinut pe pagină va fi:

21232f297a57a5a743894a0e4a801fc3

Este posibilă decriptarea parolei criptate cu ajutorul criptării md5?


nu, acest lucru nu este posibil
da, operaţia specificată în întrebare este posibilă

Care dintre variantele de răspuns de mai jos reprezintă modul în care putem preveni introducerea
de date nedorite?
validarea pe partea de server
trimiterea unei mesaj referitor la introducerea reuşită
introducerea variabilei suplimentare
niciuna dintre variantele de răspuns nu reprezintă modul de prevenire a introducerii de date
nedorite

………………………………

Manipularea erorilor
Unitate: 17 din 19 00:20:19

+Rezumat

În cadrul acestei lecţii, vom explica noţiunile referitoare la erorile care pot apărea în timpul
programării, precum şi modurile de a le manipula.

Manipularea erorilor este un element foarte important în orice limbaj de programare, practic pe
toate platformele. Niciodată nu putem fi complet siguri când şi ce va face un utilizator, aşa cum
nu putem fi siguri nici când sistemul şi resursele lui, dintr-un motiv oarecare,
vor perturba executarea corectă a programului nostru.

Tocmai de aceea, obligaţia programatorului este să anticipeze punctele slabe din program,
care reprezintă un pericol potenţial pentru executarea sa şi să întărească aceste puncte cu sisteme
de protecţie adiţionale.

Cel mai vulnerabil punct al unei aplicaţii este momentul în care aceasta se adresează resurselor.
Aceste resurse, respectiv originea lor, este, de cele mai multe ori, o bază de date sau un sistem de
fişiere. În plus, momentele critice mai apar şi la fiecare intrare a utilizatorului în aplicaţie
(introducerea datelor), streaming, la comunicarea cu dispozitivele şi altele.
Manipularea de bază a erorilor este destul de simplă. Trebuie respectat următorul set de reguli:

 Plasarea segmentului critic într-un bloc separat;


 Plasarea segmentului alternativ într-un bloc separat.

Putem face aceasta manual sau prin blocurile try catch, în funcţie de tipul de eroare aşteptat şi
dacă aceasta poate fi procesată ca excepţie.

Erorile de programare

Indiferent ce limbaj de programare utilizăm, deosebim 3 tipuri generale de erori, acestea fiind:

 Erorile de sintaxă;
 Erorile apărute în timpul executării codului;
 Erorile logice.

Erorile de sintaxă – PHP, la fel ca şi celelalte limbaje de programare, respectă regula de bază
care reprezintă sintaxa limbajului. Dacă vreo instrucţiune nu respectă regulile limbajului, spunem
că are o anumită eroare de sintaxă. Când scriptul PHP conţine eroarea de sintaxă, analizatorul
PHP al codului nu va putea să proceseze o parte din script sau chiar întregul script, în funcţie de
cât de gravă este eroarea. Haideţi să analizăm următorul cod:

1<?php
2if (true)
3{
4echo 'error is here';
5?>

Eroarea care se va genera după executare va avea o structură similară:

Parse error: parse error, unexpected $end in ~calea până la fişierul dvs.~ on
line 2

Eroarea de sintaxă apare din cauza parantezei acolade care lipseşte aici. Mai exact, paranteza
acoladă este deschisă, iar instrucţiunea de executare a început, însă, având în vedere că paranteza
acoladă nu este închisă, analizatorul întâmpină probleme fiindcă nu ştie unde să termine scriptul
nostru.

Eroarea apărută în timpul executării codului – A descoperi şi a corecta eroarea apărută în


timpul executării codului poate fi mai greu decât credeam. Dacă codul conţine o eroare de
sintaxă, analizatorul o va descoperi imediat când încercaţi să executaţi codul respectiv. Totuşi,
eroarea care apare în timpul executării codului nu provine întotdeauna din scriptul dvs., aşadar
uneori nu se poate vedea uşor. Motivele de apariţie a unor astfel de erori pot fi diferite
evenimente şi instrucţiuni, însă pot apărea şi printre acţionările reciproce ale scripturilor. Ne vom
găsi deseori în situaţia în care, prin preluarea datelor şi procesarea unor informaţii generice,
ajungem la o eroare de calcul care va afişa următorul mesaj:

Warning: Division by zero.... ..... on line ...

Trebuie să recunoaştem că sunt puţini cei care ar vrea să împartă ceva cu zero, însă şi că o astfel
de problemă, care reprezintă eroarea în timpul executării, apare frecvent.

Erorile logice – Acestea sunt totodată şi cele mai greu de eliminat, fiindcă gândiţi logic şi
aşteptaţi de la codul dvs. să facă exact ceea ce v-aţi imaginat, însă şi cea mai mică eroare poate
crea o inversare absolută a instrucţiunii executate. Cauza poate fi o simplă greşeală de ortografie,
de exemplu:

1for ( $i = 0; $i < 10; $i++ );


2{
3echo ' Hello <br/ >';
4}

Codul prezentat în exemplul de mai sus este corect în totalitate şi se execută fără nicio problemă.
Problema apare la executarea instrucţiunii şi se ascunde în semnul ; de la sfârşitul instrucţiunii
for. Soluţia comenzii va fi executarea buclei for de 10 ori fără niciun rezultat, pe când
instrucţiunea echo se va executa doar o singură dată. Credem că, atunci când utilizatorul a scris
acest cod, el a aşteptat de la cod un rezultat în care instrucţiunea echo, cu textul 'Hello', să se
execute în cadrul buclei for şi ca aceasta să fie scrisă de 10 ori la ieşire.

Procesarea manuală a erorilor la nivel inferior

Înainte să accesăm o resursă, vă recomandăm să examinăm dacă această resursă există şi pe baza
acestei informaţii să continuăm executarea programului. De exemplu:

1<?php
2$file = fopen("myFile.txt", "r");
3?>

Dacă fişierul myFile.txt nu se află în folderul aplicaţiei, acest cod va provoca o eroare. De aceea,
trebuie verificat dinainte dacă fişierul există şi, în funcţie de rezultat, să-l securizăm:

1
<?php
2if(!file_exists("myFile.txt"))
3 {
4 $file = fopen("myFile.txt", "w");
5 fclose( $file );
6 }
$file = fopen("myFile.txt", "r");
7?>
8
Sau, pur şi simplu, să întrerupem executarea programului:

1
2 <?php
if(!file_exists("myFile.txt "))
3 {
4 die("Unknown file");
5 }
6 else
7 {
$file = fopen("myFile.txt ", "r");
8 }
9 ?>
10

die()

Această funcţie întrerupe pe moment executarea programului cu (sau fără) emiterea unui mesaj
definit de utilizator. Dacă continuarea executării programului depinde de resurse pe care trebuie
să le citim (de exemplu, de fişierul myFile.txt din exemplele precedente), atunci trebuie să oprim
executarea programului, dacă această resursă nu există.

În acest exemplu, dacă fişierul nu există, va fi afișat un mesaj de eroare, apoi mesajul funcţiei die
(sfârşit), care va opri executarea:

1<?php
2$file = fopen("myFile.txt ", "r") or die("end");
3?>

Emiterea manuală a erorilor

În exemplul precedent, am oprit executarea programului utilizând funcţia die(). De asemenea,


este posibilă şi emiterea unui mesaj de eroare propriu, fără oprirea executării. Această linie de
cod va emite un mesaj de eroare pe poziţia pe care aceasta se află:

trigger_error("My error");

Tipul de eroare astfel emisă va fi 1024 (Notice), care s-ar putea să nu corespundă nivelului de
seriozitate pe care dorim să-l oferim utilizatorului. Pentru a schimba asta, putem introduce în
mod explicit un al doilea parametru, care va fi unul dintre cele trei tipuri de erori acceptate de
către această funcţie şi ale căror convenţii trebuie să le respectăm în timpul utilizării:

 E_USER_WARNING (512) – Eroare care afectează funcţionarea aplicaţiei (de exemplu,


nu am găsit resurse), dar aplicaţia îşi poate continua lucrul;
 E_USER_NOTICE (1024) – Doar o notificare; se foloseşte atunci când dorim să
avertizăm utilizatorul despre o anomalie din aplicaţie;
 E_USER_ERROR (256) – Această eroare trebuie să preceadă oprirea executării
programului.

De exemplu:

trigger_error("My error", E_USER_WARNING);

Manipularea manuală a erorilor

Pe lângă propria activare a mesajului de eroare, putem crea şi o funcţie care va intercepta eroarea
şi care va fi executată în locul funcţiei implicite de manipulare a erorilor, adică propriul operator
(handler) de erori.

Această funcţie acceptă următorii parametri: numărul erorii (error number), mesajul erorii (error
message), fişierul care a cauzat eroarea, linia erorii, dump (şirul (array) de variabile şi valorile
lor active în momentul producerii erorii). Aceşti parametri sunt opţionali, dar ordinea lor trebuie
respectată atunci când funcţia este creată.

1function myHandler($errorNumber, $errorMessage)


2 {
3 echo $errorNumber . " " . $errorMessage;
4 }

După ce creăm funcţia care dorim să manipuleze erorile, este necesar să-i alocăm valoarea
iniţială ca handler implicit de erori:

1set_error_handler("myHandler");

Apoi, toate erorile vor fi expediate în funcţia noastră creată manual, în loc să fie expediate în
operatorul (handler-ul) implicit.

Lista codurilor (numerelor) de eroare, în raport cu funcţia trigger_error, este puţin mai extinsă în
acest caz şi este alcătuită din 7 coduri:

 E_WARNING (2) - Eroare care nu întrerupe lucrul aplicaţiei, dar o afectează (resursele
nu există);
 E_NOTICE (8) – O simplă notificare;
 E_USER_ERROR (256) – Eroare fatală, executarea fiind întreruptă;
 E_USER_WARNING (512);
 E_USER_NOTICE (1024);
 E_RECOVERABLE_ERROR (4096) – Eroare fatală, care poate fi procesată şi care nu
are consecinţe permanente asupra aplicaţiei;
 E_ALL (8191) – Toate tipurile de erori.
Erorile din această listă pot fi asociate şi operatorului (handler-ului) prin parametrul funcţiei
set_error_handler:

set_error_handler("myHandler", E_USER_NOTICE);

În acest caz, prin handler-ul nostru vor trece numai erori de tip E_USER_NOTICE, în timp ce
restul erorilor vor fi procesate prin handler-ul implicit.

Iată un exemplu de cod complet:

function myHandler( $errorNumber, $errorMessage )


{
echo "Error number: " . $errorNumber . "<br>Error message: " . $errorMessage;
}
//transcrierea handlerului de sistem cu cel de utilizator
set_error_handler("myHandler");
//provocarea erorii prin introducerea unei variabile neiniţializate
echo( $myVariable );

După ce eroarea este captată, cel mai bine este să o expediem într-un log/jurnal din baza de date
sau din sistemul de fişiere. Log-ul pentru un sistem specific (de exemplu, pentru memorarea log-
urilor în baza de date) poate fi scris şi manual, în timp ce pentru tipurile standard de log putem
folosi şi funcţia implicită error_log().

Această funcţie acceptă până la patru parametri: mesajul de eroare, tipul de logare, destinaţia şi
header-ul.

Mesajul de eroare este orice mesaj de utilizator, care dorim să fie memorat în log. Tipul de
logare reprezintă, de fapt, destinaţia trimiterii acestui log, unde:

 0 – Default (se foloseşte pentru un log definit de sistem);


 1 – Mail (log entry este trimis pe e-mail);
 3 – File (log entry este introdus într-un fişier);
 În cazul în care tipul destinaţiei este 1 sau 3 (mail sau fişier), sunt necesari nişte parametri
adiţionali (header-ul şi destinaţia pentru mail şi adresa, fişierul de destinaţie pentru fişier).

<?php
error_log("My error", 1, "targetMail@mail.com", "From:
myMail@mail.com");
?>

<?php
error_log("My error", 1, "c:/myFile.log");
?>

Clasa Exception
În cadrul lui PHP, este încorporată clasa Exception. Constructorul clasei Exception acceptă doi
parametri: primul, cel care alcătuieşte textul mesajului de eroare, şi al doilea parametru, care
reprezintă numărul erorii.

În afară de constructor, clasa Exception mai are la dispoziţie şi următoarele metode:

 getCode() – returnează numărul erorii transmise constructorului;


 getMessage() – returnează textul mesajului transmis constructorului;
 getFile() – codului apelat îi returnează o cale completă a fişierului în care este generată
excepţia;
 getLine() – returnează numărul rândului din cod în care este generată excepţia;
 getTrace() – returnează un şir de date despre arborele de apelare (sau backtrace arată ce
funcţii s-au executat în momentul generării excepţiilor), care asigură determinarea locului
în care este generată excepţia;
 getTraceAsString() – returnează aceleaşi date ca şi getTrace(), formate ca un şir de
semne;
 _toString() – asigură instrucţiunii echo transmiterea directă a conţinutului obiectului
Exception tuturor datelor care dau metodele menţionate.

Notă:

Pentru a urmări contextul acestei lecţii, am menţionat şi clasa Exception, care însă nu face
parte din conceptul obiectual şi acesta nu este abordat în cadrul cursului. De aceea, unele
noţiuni vor rămâne vagi.

Manipularea excepţiilor

Rezolvarea problemelor legate de resurse (şi altele asemănătoare) nu este întotdeauna posibilă
prin executări condiţionate ale codului. Uneori, trebuie încercat altceva pentru a afla dacă acel
ceva se poate realiza. În acest caz, avem nevoie de un mecanism care va reacţiona numai după
producerea erorii, fără deranjarea funcţionării normale a programului. Acest mecanism există şi
se numeşte operatorul (handler) de excepţii.

Operatorul de excepţii este o noţiune strâns legată de programarea orientată pe obiect, deoarece
excepţia este o caracteristică a unui anumit eveniment a unei clase specifice.

Să revenim la exemplul de la începutul lecţiei, unde încercam să citim un fişier inexistent:

1<?php
2$file = fopen("myFile.txt", "r");
3?>

Și unde am rezolvat problema fişierului inexistent prin setarea unei condiţii înainte de citire:
1if(file_exists("myFile.txt"));

Să presupunem că acum toate acestea fac parte dintr-o clasă care manipulează fişiere:

1
<?php
2 function readFunc($file)
3 {
4 if(file_exists($file))
5 $file = fopen($file, "r");
}
6?>
7

Apelarea funcţiei readFunc() a acestei clase nu va produce o eroare, aşa cum era de aşteptat. De
asemenea, putem introduce şi o logică, care va elimina mesajul despre inexistenţa fişierului. Însă,
pentru ca eroarea noastră referitoare la fişierul inexistent să fie privită ca o excepţie, respectiv ca
utilizatorii clasei (dacă excepţia este extrasă din clasă) sau noi înşine să o putem capta ca o
excepţie standard (cu metodele standard de captare a excepţiilor), va trebui ca şi obiectul emis în
timpul procesării acestei erori să fie de un tip de excepţie:

1
2 <?php
function read($file)
3 {
4 if(!file_exists($file))
5 throw new Exception("File do not exist");
6 else
7 $file = fopen($file, "r");
}
8 read("myFile.txt");
9 ?>
10

Eroarea (excepţia) astfel emisă este uşor captată prin folosirea blocului try-catch. Trebuie doar să
marcăm segmentul în care preconizăm că excepţia va apărea (în acest caz, prin apelarea metodei
readFunc()) şi plasarea ei în blocul try, apoi adăugarea codului alternativ (care va trebui executat
în cazul în care blocul try eşuează)) în blocul catch. Blocul catch acceptă parametrul de tip
Exception, care conţine proprietăţile şi metodele pentru dezvăluirea anumitor detalii legate de
excepţia însăşi.

1
try
2{
3read("myFile.txt");
4}
5catch(Exception $e)
6{
echo $e;
7}
8
În loc de new Exception, pe care am eliminat-o din funcţia readFunc(), am fi putut elimina şi
instanţa propriei clase de excepţii (fireşte, dacă am creat-o în prealabil). O putem crea moştenind
clasa Exception şi adăugând elemente proprii:

1
class myException extends Exception
2 {
3 public function errorMessage()
4 {
5 return "my exception";
}
6 }<span style="font-size: 14px; text-align: justify;"> </span>
7
Notă:

Deoarece clasele, metodele şi moştenirea vor fi abordate mai târziu, în acest moment este
suficient doar să reţineţi sintaxa folosită mai sus.

Exerciţiu

Se dă următoarea variabilă:

1$whiteList = array("index.php", "index1.php", "index2.php");

Trebuie creată funcţia includeFile, care va accepta denumirea fişierului, va verifica dacă
denumirea respectivă există în şir şi dacă există un fişier cu această denumire. Dacă fişierul nu
există în şir sau în file system/sistemul de fișiere, funcţia trebuie întreruptă prin emiterea
excepţiei. În caz contrar, fişierul trebuie încărcat cu funcţia include sau require.

Apelarea funcţiei trebuie făcută în blocul try catch.

Rezolvare:

1 <?php
2 $whiteList = array("index.php","index1.php","index2.php");
3 function includeFile($file)
{
4 global $whiteList;
5 if(!in_array($file, $whiteList)){
6 throw new Exception("No file in whitelist");
7 }else{
if(!file_exists($file)){
8
throw new Exception("Filename is not valid");
9 }else{
10 include $file;
11 }
12 }
13
14 }
15 try
{
16 includeFile("index1.php");
17 }
18 catch(Exception $ex)
19 {
echo $ex->getMessage();
20 }
21?>
22
23
24
25

Variabila $whiteList reprezintă o listă albă pentru exemplul nostru. Imediat după crearea acestui
şir, accesăm crearea funcţiei includeFile. Funcţia acceptă ca parametru stringul, care reprezintă
numele fişierului.

În primul rând, se verifică dacă fişierul căutat aparţine listei. Dacă da, se generează un nou
exception şi se defineşte mesajul. Dacă această condiţie rămâne neîndeplinită, înseamnă că
numele fişierului este permis, dar trebuie verificat dacă acesta este în sistemul de fişiere:

1!file_exists($file)

Dacă este îndeplinită această condiţie, se generează un nou exception cu un mesaj nou, în timp
ce, în caz contrar, se aplică procedeul de includere a fişierului.

Acum, trebuie apelată funcţia şi controlate eventualele greşeli. De aceea, apelul funcţiei îl punem
în try-catch block:

1
try
2{
3 includeFile("index1.php");
4}
5catch(Exception $ex)
6{
echo $ex->getMessage();
7}
8

Dacă este generat exception, apare mesajul rezultat în urma folosirii metodei getMessage().

Numărul erorii fatale care se poate procesa şi care nu are consecinţe permanente pentru aplicaţie
este:
4096
1024
2048
512
…………………………..

Modul 7 Lucrul cu datele


Manipularea lui MySQL
Unitate: 18 din 19 00:20:21

+Rezumat

Această lecție este dedicată comunicării cu baza de date și manipulării interogărilor și a


tabelelor.

SQL Buddy este o aplicație Open Source bazată pe web şi scrisă în PHP cu menirea de a efectua
activitățile administrative ale MySQL și SQLite utilizând un browser web. Accentul proiectului
SQL Buddy cade pe instalarea ușoară în cadrul serverului Wamp și pe o interfață cu utilizare
simplă.

În cadrul serverului Wamp, despre care am mai vorbit deja, se află și suportul pentru baza de
date MySQL. În cadrul acestei baze și al opțiunii sqlbuddy, puteți crea și manipula foarte ușor
baza dvs. de date și tabelele pe care le conține, având în vedere că în serverul Wamp nu veți avea
complicații adiacente cu prilejul conectării la baza dvs. și a accesării conținutului ei.

De asemenea, vă recomandăm și utilizarea cadrelor de lucru phpmyadmin, care sunt mai


adecvate și mai specializate pentru utilizarea MySQL, pe care le vom și folosi în munca
noastră. Am ales să explicăm utilizarea sqlbuddy ca să vedeți ce alternative mai aveți și să vă
hotărâți asupra celei mai corespunzătoare în ceea ce privește aplicațiile dvs. Aplicația cel mai des
utilizată pentru gestionarea MySQL este phpMyAdmin.

În ceea ce privește SQL Buddy, vă vom afișa opțiunile de bază pe care vi le oferă.

Vă vom explica, în pașii următori, cum să vă creați baza de date dorită:

1. Activați serverul Wamp în cadrul browser-ului web, tastând Localhost în spațiul de adrese sau
dând clic pe Localhost în meniul serverului Wamp:
18.1 - Meniul Wamp

2. Alegeți din meniu (din partea de jos a paginii) opțiunea sqlbuddy:

18.2 - Linkul SQL Buddy

La aceeaşi locaţie, ajungeţi şi dacă pur şi simplu accesaţi următorul link:

http://localhost/sqlbuddy/login.php

Notă: În caz că pe pagină apare un formular de logare, similar cu cel de mai jos:
18.3. Login-ul SQL Buddy

este suficient doar să alegeţi opţiunea Submit, iar câmpul Password îl lăsaţi gol. Desigur, dacă
mai devreme aţi modificat parametrii de logare, atunci aici inseraţi valorile valide pentru
parametrii respectivi.

3. Pe ecran va fi afişată o pagină cu următorul conţinut:


18.4 - Pagina de start a lui SQL Buddy

4. În partea de jos a paginii, este și lista de scurtături de pe tastatură care vă vor ușura circulația
și crearea datelor:
18.5 - SQL Buddy - scurtături pentru tastatură

5. Crearea bazei de date se face prin introducerea numelui ei și prin alegerea fonturilor pe care le
va utiliza. Cu clic pe Submit, baza dvs. de date a fost creată:

18.6 - Crearea unui tabel nou

6. După ce v-ați creat baza de date, aveți o privire de ansamblu ca în fotografia de mai jos, unde
aveți mai multe opțiuni de lucru.

A. Opţiunea pentru eliminarea bazei;


B. Crearea tabelului;
C. Completarea câmpurilor pentru inserarea noilor date în bază.
18.7 - SQL Buddy - crearea tabelului 2

7. După confirmarea faptului că ați introdus tabelul și primul câmp în el, în continuare se va afișa
pagina cu toate câmpurile prezentate în tabel, unde aveți posibilitatea să introduceți în continuare
câmpuri și să manipulați cheile primare și secundare ale tabelului:
18.8 - Editarea tabelului

8. De asemenea, puteți manipula câmpurile create. După ce le-ați creat, câmpurile dvs. vor fi
afișate tabelar, iar în pagină, deasupra lor, puteți observa un meniu de lucru mai mic. Accesând
Edit, se vor deschide câmpurile de manipulare, mai exact de schimbare a câmpului selectat de
dvs:
18.9. sqlbuddy - opţiunea pentru editarea câmpurilor

18.10 - SQL Buddy - formular pentru editarea câmpurilor

9. De asemenea, selectarea opțiunii Delete vă va cere confirmarea privind ștergerea câmpului


marcat și efectuarea operațiunii de ștergere:

18.11 - SQL Buddy- delete

Cu opțiunea Insert puteți să introduceți date în tabelele create:


18.12 - SQL Buddy - Insert

Schimbarea parolei de acces la suprafața de lucru sqlbuddy

Setarea implicită de accesare a MySQL este prevăzută cu un nume de utilizator (username) root
și fără parolă (password) (respectiv, cu confirmarea câmpului gol de introducere a parolei). De
asemenea, utilizarea de către utilizatorii anonimi fără parolă. Trebuie să setaţi parola
pentru numele de utilizator root și să-l înlăturați pe utilizatorul anonim și, dacă este nevoie, să
creați un nou utilizator:
18.13 - SQL Buddy - administrarea utilizatorilor

Setarea parolei pentru utilizatorul principal „root”:

1. Logați-vă pe SQL Buddy prin URL-ul http://localhost/sqlbuddy, cu numele de utilizator


„root” și cu câmpul de parolă gol.
2. Mergeți la opțiunea Users.
3. Găsiți rândul în care sunt User – root și Host – localhost și alegeți Edit.
4. Introduceți noua parolă în câmpul prevăzut (Change password).
5. Repetați pașii pentru root@127.0.0.1 (adresa IP pentru localhost) și root@: 1 (IPv6
adresa localhost).

Pentru a înlătura utilizatorul anonim, trebuie să faceți următoarele:

1. Logați-vă pe SQL Buddy ca utilizator principal.


2. Mergeți la opțiunea Users.
3. Verificați rândul cu utilizatorul anonim (rândul în care user este câmp secundar) și alegeţi
opțiunea Delete.

Pentru operațiile de bază, nu ar trebui să folosiți utilizatorul de bază „root”, el ar trebui folosit
doar pentru crearea noilor utilizatori. De asemenea, puteți crea un utilizator nou pentru munca la
operațiunile standard. Pentru a crea un utilizator nou cu denumirea de „wampuser”, trebuie să
faceți următoarele:

1. Logați-vă pe SQL Buddy cu numele de utilizator „root”.


2. Mergeți la opțiunea Users.
3. În secțiunea ADD NEW USER, introduceți „localhost” în câmpul de introducere care
aparține host-ului, iar „wampuser” în câmpul care aparține numelui și „xxxx” în câmpul
parolei. Pentru început, nu bifaţi Grant Option, doar confirmați dând clic pe Submit.

Exportul şi importul bazelor

Atunci când lucraţi cu MySQL, aveţi posibilitatea să importaţi şi exportaţi baze din sau în
MySQL.

Importarea

Prin importarea bazei în MySQL, puteți introduce baza dvs. deja existentă. Este recomandat ca
baza să aibă extensia. sql.

Puteți introduce baza în felul următor:

1. Clic pe Choose File, selectați fişierul pe care doriți să-l introduceți.


2. Confirmați apăsând pe Submit, iar baza dvs. va fi importată și se va găsi pe lista bazelor
utilizabile din partea stângă:
18.14 - SQL Buddy - importarea

Exportarea

Exportarea bazei de date reprezintă sursa bazei din cadrul SQL Buddy. Baza va fi împachetată în
fișierul .sql și ca atare va putea fi introdusă în alte baze de date. Exportarea se face în felul
următor:

1. Din lista oferită alegeți baza dorită pe care doriți să o exportați.


2. În secțiunea Export puteți alege să exportați structura bazei sau baza și cel mai bine este
să bifaţi ambele opțiuni și să completați baza.
3. În Options, optați pentru un insert mai mic, compact, sau unul complet, respectiv întregul
insert din baza de date.
4. Și, în ultima parte Output to: Browser sau Text file sunt opțiunile pe care le puteți selecta
în funcție de numărul de rânduri din baza de date aleasă, iar când aveți un număr mai
mare de rânduri vă recomandăm opțiunea Text file.
5. Cu un clic pe Submit, confirmați și finalizați exportarea bazei.
18.15 - SQL Buddy - exportarea

Query

Oricând doriți să comunicați cu baza de date, aveți opțiunea Query și câmpurile de inserare a
interogării dvs. Cu un clic pe Submit confirmați executarea interogării introduse.

Acum, tot ce avem pentru lucrul cu baza de date se află în partea ușoară a SQL Buddy, fără a fi
nevoie să cunoaștem sintaxa de creare a interogării pentru baza noastră.
18.16 - SQL Buddy - query

Stabilirea conexiunii cu baza de date

Biblioteca funcțiilor pe care o utilizează PHP pentru stabilirea conexiunii cu MySQL se numește
MySQLi (litera i este adăugată de la cuvântul din limba engleză improved, care înseamnă
îmbunătățit). Utilizând această bibliotecă, aveți posibilitatea să folosiți sintaxa orientată și pe
obiect, și pe procedură.

Acum, vom utiliza sintaxa procedurală pentru accesarea bazei de date. Exemplu:

1@ $db = mysqli_connect('localhost', 'root', '','testDB');

Ca rezultat al acestei funcţii, vom avea conexiunea cu baza de date de tip resursă. Când folosim
sintaxa procedurală conform exemplului și rezultatul obținut ca resursă, trebuie să trimitem
resursa obținută mai departe tuturor funcțiilor din biblioteca MySQLi pe care o utilizăm.
Denumirile funcțiilor cu versiuni procedurale încep cu ’mysqli_’ și acestor funcții trebuie să li se
trimită resursa pe care am primit-o în prealabil de la funcția mysqli_connect().

Verificați întotdeauna rezultatul încercării de a stabili conexiunea. Motivul ar fi că restul


scriptului nu va funcționa în afara unei conexiuni funcționale cu baza de date. Verificarea se face
cu următorul cod:

1if(mysqli_connect_errno())
2{
3echo 'Connection failed! ';
4exit;
5}

Funcția pe care am utilizat-o, mysqli_connect_errno(), returnează numărul de erori în cazul


executării eronate, iar în caz că conexiunea este stabilită cu succes, returnează zero.

De asemenea, atunci când stabiliţi conexiunea cu baza de date, vă recomandăm ca rândul codului
în care se face conexiunea să înceapă cu ’@’ ca să aveți posibilitatea să îndreptați erorile
potențiale așa cum credeți că trebuie.

Când lucrați la stabilirea conexiunilor cu baza, trebuie să știți că există un număr limitat de
conexiuni concomitente care se pot stabili cu serverul MySQL. În cadrul MySQL, există și
parametrul max_connections, care determină numărul maxim de conexiuni. Acest parametru are
rolul să împiedice supraîncărcarea serverului din cauza numărului prea mare de cereri sau al
funcționării defectuoase a software-ului.

Prin executarea comenzii SQL:

show variables like "max_connections";

puteţi verifica setările actuale pentru numărul maxim de conexiuni.

Valoarea standard a acestui parametru se poate modifica prin următoarea instrucţiune SQL:

set global max_connections = 200;

sau prin modificările din fişierul my.ini.

18.17 - WampServer - php.ini

Ştergerea bazei de date

Când doriți să vă conectați de pe web la o bază de date, este necesar să treceți baza de date la
care vreți să vă conectați ca parametru al funcției mysqli_connect(). În cazul în care doriți ca din
baza curentă să treceți în alta, trebuie să scrieți codul următor:
1mysqli_select_db( $conn, $dbName);

În acest exemplu, putem observa apelarea resursei ca pe un parametru al funcției mysqli_ pe care
am menţionat-o.

Interogările bazei de date

Executarea interogărilor către baza de date se face prin funcția mysqli_query(), iar înainte de
utilizarea ei trebuie mai întâi definită interogarea (query). Interogarea se poate defini în felul
următor:

1$query = "SELECT * FROM users WHERE first_name = '". $name . "'";

În această interogare, $name reprezintă variabila pe care utilizatorul a definit-o (i-a atribuit
valoare) în cadrul aplicației. Mai departe, variabila se compară cu câmpul din bază și în acest
mod filtrează rezultatul interogării.

După ce am definit interogarea, aceasta se poate executa în felul următor:

1$result = mysqli_query( $conn, $query );

Parametrii funcției mysql_query() sunt marcaţi prin variabilele $conn şi $query. Primul
parametru ($conn) reprezintă conexiunea către baza de date (linkul) creată prin utilizarea funcţiei
mysqli_connect(). Al doilea parametru este propria interogare pe care am creat-o şi localizat-o,
de asemenea, în variabila $query.

Rezultatele apelării interogării dorite se depozitează în variabila $result, pentru ca mai târziu să
le putem manipula. Dacă apare o eroare în timpul executării funcției care nu se execută conform
planului, rezultatul va fi o valoare logică false.

Încărcarea rezultatelor interogării

Utilizând funcția mysqli_num_rows(), numărăm rândurile pe care interogarea le-a returnat. În


calitatea ei de parametru, este nevoie să i se trimită identificatorul rezultatelor în felul următor:

1$num_results = mysqli_num_rows( $result );

Prin executarea funcției, puteți folosi în mod util numărul de rânduri obținut ca rezultat, asta dacă
doriți să procesați rezultatul interogării. Când știți câte rânduri aveți, puteți utiliza bucla for în
felul următor:

for ( $i = 0; $i < $num_results; $i++ )


{
...PROCESAREA REZULTATELOR…
}
Deconectrea de la baza de date

Suma rezultatelor se poate elibera prin apelarea metodei:

1mysqli_free_result( $results );

după care puteți utiliza următoarea metodă:

1mysqli_close($conn);

Pentru a vă deconecta de la baza de date, nu este întotdeauna necesar să utilizați această metodă,
deoarece conexiunea se va întrerupe oricum după finalizarea scriptului.

Exerciţiul nr. 1

Trebuie creată o bază de date mai scurtă, utilizând mediul de dezvoltare SQL Buddy și sintaxa
procedurală (funcțiile din biblioteca mysqli() ... ). Scrieţi deschiderea conexiunii, interogarea,
apelarea interogării și închiderea conexiunii.

Rezolvare:

1 <?php
$servername = "localhost";
2 $username = "root";
3 $password = "";
4 $db = "testdb";
5
6 // Create connection
7 $conn = mysqli_connect($servername, $username, $password, $db);
8
// Check connection
9 if (!$conn) {
10 die("Connection failed: " . mysqli_connect_error());
11}
12echo "Connected successfully! <br>";
13
14$name = 'Peter';
15$query = "SELECT * FROM users WHERE firstname = '$name'";
16$result = mysqli_query($conn, $query);
17
18if (mysqli_num_rows($result) > 0) {
19 // output data of each row
20 while($row = mysqli_fetch_assoc($result)) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " .
21$row["lastname"]. "<br>";
22 }
23} else {
24 echo "0 results";
}
25
26mysqli_close($conn);
27?>
28
29
30
31
<br>Ca să putem accesa baza de date, trebuie să ştim unde se află aceasta,
trebuie să ştim numele bazei pe care vrem să o <br>accesăm şi trebuie să
1 avem date accesibile. Tocmai de aceea toate aceste date le vom pune în
variabile:
1$servername = "localhost";
2$username = "root";
3$password = "";
4$db = "testdb";
1Acum putem accesa crearea conexiunii cu baza:
1// Create connection
2$conn = mysqli_connect($servername, $username, $password, $db);
Funcţiei mysqli_connect îi alocăm parametrii în ordine menţionată. După
1conexiune, putem să şi verificăm conexiunea:
1// Check connection
2if (!$conn) {
3 die("Connection failed: " . mysqli_connect_error());
4 }
5echo "Connected successfully! <br>";
Funcţia mysqli_connect_error va returna mesajul generat care mai degrabă
1indică motivul conexiunii eşuate cu baza.<br><br>Creăm variabilla $name şi
îi alocăm valoarea care trebuie căutată în bază:
1$name = 'Peter';
1Creăm interogarea către bază:
1$query = "SELECT * FROM users WHERE firstname = '$name'";
1Apoi putem efectua interogarea generată mai devreme:
1$result = mysqli_query($conn, $query);
Ca prim parametru al funcţiei mysqli_query, punem linkul către bază, în timp
ce al doilea este interogarea.<br><br>Dacă există rânduri selectate,
1respectiv dacă sunt rezultate de căutare, trebuie să le şi prezentăm. De
aceea, în primul rând verificăm dacă numărul rândurilor returnate este mai
mare decât 0 şi, dacă da, folosim bucla while ca să trecem prin fiecare rând:
1if (mysqli_num_rows($result) > 0) {
2 // output data of each row
3 while($row = mysqli_fetch_assoc($result)) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " .
4$row["lastname"]. "<br>";
5 }
6} else {
7 echo "0 results";
8 }
Pe de altă parte, dacă numărul rândurilor selectate este 0, înseamnă că nu
1sunt rezultate de căutare şi utilizatorul trebuie informat cu privire la
acest lucru. <br><br>La final, ne mai rămâne să închidem conexiunea cu baza:
1mysqli_close($conn);
Aici trebuie menţionat că conexiunea s-ar închide şi automat după
1finalizarea scriptului.

Funcţiei mysqli_query() ca argumente îi trebuie transmis:


$db, $query
$db
$query
NULL
………………………………………………

PHP şi bazele de date


Unitate: 19 din 19 00:30:21

+Rezumat

În această lecție, veți avea ocazia să învățați cu ce baze și în ce moduri puteți lucra în limbajul
PHP.

PHP şi ODBC

PHP asigură suport pentru Open Database Connectivity (ODBC). În acest mod, programul PHP
poate avea acces la orice bază de date suportată de ODBC, cum ar fi Oracle, DB2, MS SQL
Server sau MS Access. PHP asigură metodele care pot accesa baza în funcţie de DSN-ul ei, însă
pot și să efectueze așa-numitele conexiuni DSN-less. Acest al doilea aspect al conexiunii se
utilizează în cazurile în care nu există DSN sau când el este necunoscut. De exemplu, în
cazul bazei MS Access.

Cel mai des utilizate funcţii pentru conexiunea ODBC sunt:

 odbc_connect(dsn/dsn-less connection string, username, password) – funcția care se


utilizează pentru stabilirea conexiunii cu baza. Această funcție are trei argumente, dintre
care primul sunt bazele DSN sau stringul DSN-less și acest argument este necesar.
Celelalte două argumente sunt numele de utilizator și parola. Dacă nu este nevoie ca ele
să fie trimise bazei, se poate trimite doar stringul gol. După stabilirea conexiunii, această
funcție returnează numărul de identificare a conexiunii pe care-l utilizează alte funcții
ODBC.
 odbc_exec(connection_id, SQL query_string) – această funcție se folosește pentru
executarea comenzii SQL. În caz de eroare, funcția returnează valoarea FALSE. În cazul
în care comanda SQL s-a executat cu succes, funcția returnează setul de silabe care
satisfac interogarea.
 odbc_fetch_array(recordset name) – se folosește pentru ordonarea setului de silabe în
șirul asociativ.
 odbc_num_rows(recordset name) – returnează numărul de silabe care se află în setul
rezultat. În caz de eroare, returnează valoarea -1. Pentru comenzile INSERT,
UPDATE sau DELETE, această funcție returnează numărul de silabe modificate de
aceste comenzi. În cazul comenzii SELECT, această funcție returnează numărul silabelor
selectate.
 odbc_close(connection_id) – închide conexiunea.

PHP şi MySQL

Cea mai utilizată bază de date de pe internet este cu siguranță MySQL. Acest format al bazei a
devenit în scurt timp foarte utilizat, cel puţin atunci când vorbim de aplicațiile de pe internet,
datorită rapidității, fiabilității și simplității sale de utilizare. PHP oferă suport pentru bazele
MySQL cu ajutorul unui șir de clase și funcții care pot fi folosite la manipularea datelor.

În PHP, baza de date se poate manipula în mai multe moduri. Modul cel mai răspândit este
utilizarea lui mysqli şi PDO.

Notă:

Începând cu versiunea PHP 5.5.0, extensia mysql este depăşită, iar utilizarea acesteia nu se
mai recomandă. Moştenitoarea acestei extensii este extensia mysqli avansată, a cărei utilizare
este acceptabilă şi care se poate folosi atât obiectual, cât şi procedural. În afară de această
extensie, mai puteţi să folosiţi şi extensia PDO, care va fi abordată în următoarele cursuri, dar
care suportă doar accesul obiectual. În ilustrația de mai jos, am putea să reprezentăm relaţia
dintre extensia mysqli şi PDO:
19.1. MySQLi vs PDO

Deci, accesul procedural permite doar mysqli, dar de aceea poate să lucreze exclusiv cu MySQL. Pe de altă parte, PDO poate să lucreze cu
mai multe (12), dar de aceea nu oferă acces procedural. Ambele extensii sunt foarte utile în OOP şi suportă MySQL.

În biblioteca php mysqli, toată manipularea bazei se poate executa procedural sau obiectual.

Mai jos, vă oferim o listă a unora dintre cele mai importante funcţii ale extensiei mysqli:

 mysqli_connect( MySQL server name, username, password, dbname ) – deschide


conexiunea către serverul MySQL și selectează baza de date;
 mysqli_query( connection, sql query ) – trimite interogarea bazei momentan active;
 mysqli_fetch_array(recordset) – returnează un șir care corespunde setului de silabe
rezultate;
 mysql_num_rows( recordset id ) – determină numărul de rânduri care apar în setul de
date rezultat, care este obţinut în urma executării comenzii SELECT;
 mysqli_affected_rows( connection ) - determină numărul de rânduri modificate prin
comenzile executate anterior, INSERT, DELETE sau UPDATE;
 mysqli_close( connection ) – închide conexiunea.

Crearea datelor

Toate modificările și căutările datelor din bază se realizează cu ajutorul comenzilor SQL
corespunzătoare, care sunt transmise bazei.

În continuare, îi vom trimite serverului MySQL două comenzi. Una pentru crearea bazei de date
și alta pentru crearea tabelului. Rezultatul va fi o bază sau un tabel de date.
Primul pas, este, desigur, crearea conexiunii. Facem acest lucru cu funcția mysqli_connect. De
exemplu:

1$conn = mysqli_connect("localhost","root","");

Aici, trebuie să menţionăm că este posibil, în acelaşi timp, executarea şi menţinerea conexiunii
spre un număr mai mare de baze de date. Aceasta înseamnă că nu trebuie toate datele, necesare
pentru funcţionarea aplicaţiei, să fie localizate pe un server al bazei de date, ci că în acelaşi timp
ar putea să comunice cu mai multe servere de acest tip. Reprezentarea grafică a acestei funcţii şi
conexiunea la diferite baze s-ar putea ilustra astfel:

19.2 - mysqli connect

Al doilea pas este executarea interogării. Interogarea trebuie să creeze baza de date, iar ca urmare
toată linia va arăta așa:

mysqli_query($conn,"CREATE DATABASE first_php_test_db");<span style="font-


1size: 15.4px; text-align: justify;"><br></span>

În continuare, cu ajutorul interogării SQL vom face un tabel în baza de date, iar crearea acestuia
va fi foarte asemănătoare cu tabelul din linia anterioară:

1mysqli_select_db($conn,"first_php_test_db");
mysqli_query($conn,"CREATE TABLE mytable (id int primary key auto_increment,
2username varchar(50))");

Apoi, tot cu ajutorul interogării și a funcției mysqli_query introducem niște date în tabel. Vor fi
trei nume: Peter, Sally și John.
mysqli_query($conn,"INSERT INTO mytable
1values(null,'Peter'),(null,'Sally'),(null,'John')");<span style="font-size:
10px;"> </span>

În final, vom întrerupe conexiunea la baza de date, folosind funcția mysqli_close:

1mysqli_close($conn);

După executarea codului, pe server va fi creată baza de date. În continuare, urmează codul
complet (nu uitați ca după executare să comentați toate liniile privind crearea bazei de date și a
tabelului, pentru ca ele să nu se execute de fiecare dată din nou și să încerce să creeze obiecte
deja existente în bază):

$conn = mysqli_connect("localhost","root","");
1mysqli_query($conn,"CREATE DATABASE first_php_test_db");
2mysqli_select_db($conn,"first_php_test_db");
3mysqli_query($conn,"CREATE TABLE mytable (id int primary key auto_increment,
4username varchar(50))");
5mysqli_query($conn,"INSERT INTO mytable
values(null,'Peter'),(null,'Sally'),(null,'John')");
6mysqli_close($conn);

Selectarea şi modificarea datelor

Afișarea datelor din bază se face cu ajutorul interogării SELECT. Cu această interogare
determinăm ce date specifice și în ce fel dorim să le afișăm. De exemplu, dorim să preluăm
datele pe care le-am introdus mai devreme. Serverului MySQL îi vom transmite următoarea
interogare SQL:

1SELECT * FROM mytable

Această interogare va afișa conținutul tabelului în formă tabelară, iar noi îl putem prelua cu
ajutorul funcțiilor php.

Ştim deja că funcția php pentru pornirea interogării SQL este mysqli_query, astfel prima linie de
cod ar putea fi:

1$result = mysqli_query($conn,"SELECT * FROM mytable");

Această linie va returna rezultatul interogării și îl va stoca în variabila $result. Această variabilă
va conține resursa prin care putem trece în moduri diferite. Unul dintre cele mai des utilizate
moduri este prin funcția fetch. Funcția fetch returnează rândul actual și se poziționează pe
următorul, iar cu ocazia aceasta rândul poate fi returnat sub forma unui șir indexat, șir asociativ
sau sub formă de obiect. Este chiar posibil să returneze un rezultat sub formă de şir asociativ
combinat sau sub forma unui şir indexat. În caz că nu mai sunt rânduri, această funcție va returna
null, ceea ce se poate interpreta și ca false, pe baza căruia am putea să construim codul următor,
care va afișa toți utilizatorii din tabel:

1while($rw=mysqli_fetch_row($result))
2 echo "ID: " . $rw[0] . " - Name: " . $rw[1] . "<br />";

Acesta ar trebui să fie rezultatul la ieșire:

ID: 1 - Name: Peter


ID: 2 - Name: Sally
ID: 3 - Name: John

În practică, utilizarea bazei de date este mult mai complexă și presupune și utilizarea datelor din
formulare, deşi în fundal întregul concept va fi bazat pe regulile amintite mai sus.

Exemplul următor reprezintă pagina unei companii pe care se află formularul de căutare a datelor
privind angajații:

Notă: Exemplul conține mai multe secțiuni neprocesate și necesită existența unei baze de date
corespunzătoare, ca atare exemplul acesta nu trebuie testat, fiindcă îi vom analiza doar structura.

index.php

1 <?php
2 if$string
(isset($_POST['searchName']) && !empty($_POST['searchName'])) {
= $_POST[ 'searchName' ];
3 $conn = mysqli_connect('localhost', 'root', '');
4 $db = mysqli_select_db($conn, 'membership');
5 $sql = "SELECT * FROM directory WHERE LName = '$string'";
6 $rs = mysqli_query($conn, $sql);
7
if (mysqli_num_rows($rs) == 0){
8 echo "No records found!";
9 }else{
10 while($row = mysqli_fetch_array($rs)) {
11 echo "Ime: " .$row['FName'] . " ";
echo $row['LName'] . "<br/>";
12 echo "Tel: " . $row['Tel'] . "<br/>";
13 echo "E-mail: " . $row['email'] . "<br/>";
14 }
15 }
16 mysqli_close($conn);
}
17?>
18
19<!DOCTYPE html>
20<head>
21<title> A Web Page </title>
22</head>
<body>
23<form action = "index.php" method = "post">
24 <p>Enter the last name of the employee and click the "Search"</p>
25<table>
26 <tr>
<td colspan = "2"> Company XYZ Directory </td>
27 </tr>
28 <td><input type = "text" size = "15" name = "searchName"/></td>
29 <td><input type = "submit" value = "Search"/>
30 </tr>
31</table>
</form>
32</body>
33</html>
34
35
36
37
38
39
40

După introducerea numelui în câmpul Input şi după clic pe butonul Search, se execută căutarea
datelor din bază. Dacă există rezultatul căutat, se vor lista datele despre angajat. Pe de altă parte,
dacă nu există suprapunere între introducerea din partea utilizatorului şi a datelor din bază, va fi
emis următorul mesaj: "No records found!".

Analizând acest cod, putem observa că se poate segmenta în două blocuri mari, şi anume: în
blocul PHP şi în blocul HTML.

Vom analiza mai întâi blocul HTML:

1
2
<!DOCTYPE html>
3 <head>
4 <title> A Web Page </title>
5 </head>
6 <body>
<form action = "index.php" method = "POST">
7 <p>Enter the last name of the employee and click the "Search"</p>
8 <table>
9 <tr>
10 <td colspan = "2"> Company XYZ Directory </td>
11 </tr>
<td><input type = "text" size = "15" name = "searchName"/></td>
12 <td><input type = "submit" value = "Search"/>
13 </tr>
14</table>
15</form>
16</body>
</html>
17
18
Vedem că este vorba de un simplu cod HTML şi că părţile acestuia nu trebuie analizate separat,
însă totuşi vom comenta formularul. Formularul va folosi metoda POST pentru a putea să
transmită parametrii către server. Cu atributul action, este definită apelarea fişierului index.php
(respectiv a fişierului momentan utilizat). Câmpul Input, în care utilizatorul trebuie să execute
inserarea, ca valoare a atributului name are: "searchName", pe baza căruia îl vom şi identifica
mai târziu prin codul PHP.

Acum putem analiza şi partea de cod PHP:

1
2
3 <?php
if (isset($_POST['searchName']) && !empty($_POST['searchName'])) {
4 $string = $_POST[ 'searchName' ];
5 $conn = mysqli_connect('localhost', 'root', '');
6 $db = mysqli_select_db($conn, 'membership');
7 $sql = "SELECT * FROM directory WHERE LName = '$string'";
$rs = mysqli_query($conn, $sql);
8
9 if (mysqli_num_rows($rs) == 0){
10 echo "No records found!";
11 }else{
12 while($row = mysqli_fetch_array($rs)) {
13 echo "Ime: " .$row['FName'] . " ";
echo $row['LName'] . "<br/>";
14 echo "Tel: " . $row['Tel'] . "<br/>";
15 echo "E-mail: " . $row['email'] . "<br/>";
16 }
17 }
mysqli_close($conn);
18}
19?>
20
21

Când deschidem pentru prima dată pagina index.php, nu este necesară executarea codului PHP,
deoarece utilizatorul încă nu a ajuns să insereze nimic în câmpul Input. De aceea, aici trebuie
pusă executarea condiţionată, iar codul PHP trebuie executat numai dacă parametrul Post
searchName este transmis şi dacă nu este vorba de un parametru gol (care poate fi consecinţa
unui clic pe butonul Search fără inserarea parametrilor în câmpul Input). O astfel de verificare se
execută cu ajutorul următoarei linii de cod:

if (isset($_POST['searchName']) && !empty($_POST['searchName'])) {

În variabila $string, punem valoarea parametrului transmis.

Acum, putem stabili conexiunea la baza de date astfel:

$conn = mysqli_connect('localhost', 'root', '');

După conexiune, selectăm baza de date dorită:


$db = mysqli_select_db($conn, 'membership');

Deoarece conexiunea noastră este pregătită, putem pregăti şi interogarea SQL:

$sql = "SELECT * FROM Directory WHERE LName = '$string'";

Pentru crearea interogării, am folosit sintaxa SQL şi variabila $string deja pregătită.

Notă:

Acest exemplu este dat doar pentru exersare. În producţie, o astfel de interogare ar fi fost
foarte riscantă, din punct de vedere al securităţii, aşadar ar fi trebuit să folosim şi unele
concepte de securitate.

Fiindcă acum totul este pregătit pentru indicarea interogării către bază, aceasta o facem în felul
următor:

$rs = mysqli_query($conn, $sql);

Trebuie să verificăm dacă există vreun rezultat al căutării şi, conform rezultatului obţinut,
orientăm aplicaţia noastră către următorii paşi de executare:

if (mysqli_num_rows($rs) == 0){

Dacă nu există niciun rezultat al căutării, utilizatorul trebuie informat de această stare, emiţiând:

echo "No records found!";

Pe de altă parte, în caz că totuşi avem rezultatele căutării, atunci trecem prin fiecare rezultat
obţinut şi îl afişăm pe pagină:

while($row = mysqli_fetch_array($rs)) {
echo "Ime: " .$row['FName'] . " ";
echo $row['LName'] . "<br/>";
echo "Tel: " . $row['Tel'] . "<br/>";
echo "E-mail: " . $row['email'] . "<br/>";
}

La sfârşitul întregului proces, putem închide conexiunea:

mysqli_close($conn);

Într-un mod asemănător se realizează și ștergerea, adăugarea sau modificarea unui rând. În acest
caz, se utilizează comenzile SQL corespunzătoare: DELETE, INSERT și UPDATE.

Tipurile și nivelurile de autorizare în lucrul cu MySQL


Deși în acest curs ne ocupăm doar cu combinațiile de bază în utilizarea PHP și MySQL, trebuie
să știți ce anume și în ce măsură vă este permis să utilizați, ca să nu ajungeți în situația ca o
eroare să vă îndrume spre o soluție greșită. Vă recomandăm ca, în ceea ce privește utilizarea
bazei de date, să vă fie cunoscute autorizațiile, ca să știți cum să aplicați funcțiile în mod corect.
În MySQL, există trei tipuri principale de utilizatori:

 Utilizatori simpli;
 Administratori;
 Câteva permisiuni speciale.

Aici, vedem doar autorizațiile pentru utilizatorii simpli:

Autorizaţie Se atribuie Descriere


pentru
SELECT Tabele, Permite utilizatorilor să citească rândurile din tabel.
coloane
INSERT Tabele, Permite utilizatorilor să introducă rânduri noi.
coloane
UPDATE Tabele, Permite utilizatorilor să modifice valorile în rândurile existente ale
coloane tabelului.
DELETE Tabele Permite utilizatorilor să șteargă rândurile existente.
TRUNCATE Tabele Permite utilizatorilor să şteargă toate rândurile
INDEX Tabele Permite utilizatorilor să indexeze anumite tabele.
ALTER Tabele Permite utilizatorilor să modifice structura tabelelor existente, cum
ar fi adăugarea de coloane, schimbarea numelor coloanelor sau
tabelelor sau tipurile de date din tabel.
CREATE Baze de Permite utilizatorilor să creeze noi baze de date și tabele. Dacă în
date, comanda GRANT este introdusă o anumită bază de date sau un
tabele
anumit tabel, utilizatorii pot crea doar acea bază sau tabel prin
comanda CREATE, ceea ce înseamnă următoarele: dacă ea există,
mai întâi trebuie să o șteargă cu comanda DROP.
DROP Baze de Permite utilizatorilor să șteargă bazele de date și tabelele.
date,
tabele

Tabelul - 19.1

Exerciţiul nr. 1

Cu ajutorul lui PHP MySQL creați baza de date test_db și în ea tabelul users, care să conțină trei
câmpuri: id, username și password.

Rezolvare:
1<?php
2$conn = mysqli_connect( "localhost", "root", "" );
3mysqli_query( $conn, "CREATE DATABASE test_db" );
mysqli_select_db( $conn, "test_db" );
4mysqli_query($conn, "CREATE TABLE users (userid int primary key
5auto_increment, username varchar(256), password varchar(256))");
6mysqli_close( $conn );
7?>

Scopul acestui exemplu este prezentarea posibilităţilor care au funcţiile mysqli, dar în combinaţie
cu acestea se foloseşte sintaxa SQL, despre care vom discuta mai multe în cursul de programare
şi administrare MySQL.

În primul rând, creăm conexiunea cu ajutorul funcţiei mysqli_connect, căreia îi alocăm host,
name şi password. Apoi facem interogarea cu care creăm o nouă bază de date:

1mysqli_query( $conn, "CREATE DATABASE test_db" );

Apoi, imediat facem şi selecţia acestei baze (nu am putut efectua asta cu ocazia conexiunii,
deoarece baza nu a existat în acel moment):

1mysqli_select_db( $conn, "test_db" );

Ca să creăm tabelul, în această bază executăm următoarea interogare:

mysqli_query($conn, "CREATE TABLE users (userid int primary key


1auto_increment, username varchar(256), password varchar(256))");

Comanda CREATE TABLE se foloseşte pentru crearea unui tabel nou în bază. Imediat după
această comandă, definim numele dorit al tabelului. Tabelul poate avea mai multe coloane.
Definiţia fiecărei coloane se separă prin virgulă. Prima coloană se numeşte userid, tipul de date
este int (integer) şi această coloană prezintă cheie primară (primary key). De asemenea, având în
vedere că vrem ca în valoarea acestei coloane să fie înregistrări unice, setăm şi incrementarea
automată auto_increment. Următoarea coloană se numeşte username, iar tipul de date este
varchar. Între paranteze definim numărul care reprezintă numărul maxim de caractere ce poate fi
introdus aici. Facem acelaşi lucru şi pentru ultima coloană password.

După asta închidem conexiunea cu baza.

Exerciţiul nr. 2

Se dă următorul şir:

$users = array(array("peter", "123"), array("john", "456"), array("thomas",


"789"));
Introduceți utilizatorii din șir în baza de date test_db, tabelul users, astfel încât primul membru al
fiecărui subșir să fie câmpul username, iar al doilea să fie password.

Rezolvare, varianta 1:

1<?php
2$conn = mysqli_connect("localhost", "root", "");
mysqli_select_db($conn,"test_db");
3$users = array(array("Peter", "123"), array("John", "456"), array("Thomas",
4"789"));
5foreach($users as $user){
6 mysqli_query($conn,"INSERT INTO users (username, password) VALUES
('{$user[0]}', '{$user[1]}')");
7}
8mysqli_close($conn);
9?>

Rezolvare, varianta 2:

1 <?php
2 $conn = mysqli_connect("localhost", "root", "");
3 mysqli_select_db($conn,"test_db");
4 $users = array(array("Peter", "123"), array("John", "456"), array("Thomas",
"789"));
5 $usersForQuery = "";
6 foreach($users as $user){
7 $usersForQuery.="('{$user[0]}', '{$user[1]}'),";
8 }
9 if(substr( $usersForQuery, strlen($usersForQuery) - 1) == ","){
$usersForQuery = substr($usersForQuery,0,strlen($usersForQuery)-1);
10}
11mysqli_query($conn,"insert into users (username, password) values
12$usersForQuery");
13mysqli_close($conn);
14?>

Această temă se poate rezolva în mai multe feluri. În primul rând, la primul fel facem conexiunea
cu baza şi pregătim şirul de date care va fi introdus în bază:

1$conn = mysqli_connect("localhost", "root", "");


2mysqli_select_db($conn,"test_db");
3$users = array(array("Peter", "123"), array("John", "456"), array("

Ca să trecem prin fiecare element al şirului, folosim bucla foreach, unde în fiecare iteraţie
executăm câte o interogare către bază:

mysqli_query($conn,"INSERT INTO users (username, password) VALUES

Cu comanda INSERT INTO se introduc datele în bază. Coloanele în care se vor introduse pot fi
definite în paranteze rotunde. După această parte urmează comanda VALUES, apoi între
paranteze se definesc valorile care vor fi introduse în tabel.

La final, putem să închidem conexiunea cu baza:


mysqli_close($conn);

Al doilea mod presupune acelaşi tip, doar că stringul care reprezintă partea de interogare cu
conţinutul variabilelor se pregăteşte mai devreme folosind bucla foreach şi controlul fluxului şi
pune în variabilă: $usersForQuery.

Exerciţiul nr. 3
Validați utilizatorii din bază, pe baza numelui de utilizator și al parolei, care se află în
variabilele:

$username = "john";
$password = "4567";

Rezolvare:

1
<?php
2 $username = "John";
3 $password = "456";
4 $conn = mysqli_connect("localhost", "root", "");
5 mysqli_select_db($conn,"test_db");
6
7 $r = mysqli_query($conn,"SELECT * FROM users WHERE username = '$username'
AND password = '$password'");
8 if(mysqli_num_rows($r) == 1)
9 echo "valid";
10 else
11 echo "invalid";
mysqli_close($conn);
12?>
13

Notă:

Această soluție este total nesigură, deoarece asupra ei este foarte ușor de efectuat sql
injection și de obținut un rezultat pozitiv în orice moment.
De aceea, este obligatoriu să efectuați o validare cât mai bună a intrării. În cazul acesta,
următoarele două linii sunt suficiente ca să securizeze sistemul de atacul menționat:

1$username = mysqli_real_escape_string($conn, $username);


2$password = mysqli_real_escape_string($conn, $password);

După crearea variabilelor, a conexiunii şi selectării bazei de date, se execută următoarea


interogare:

1SELECT * FROM users WHERE username = '$username' AND password = '$pa

Rezultatul acestei interogări se pune în variabila $r. Analizând interogarea, observăm că după
comanda WHERE urmează condiţionarea selecţiei, respectiv se caută ca şi câmpul username
(AND) şi câmpul password să corespundă valorilor aflate în variabile pregătite.

După interogare, aşa cum ştim, se verifică rezultatele şi scrierea mesajelor:

1if(mysqli_num_rows($r) == 1)
2 echo "valid";
3else
4 echo "invalid";

La final, conexiunea se închide:

1mysqli_close($conn);

Exerciţiul nr. 4

Tuturor câmpurilor din baza test_db, tabelul users, a căror parolă este de trei caractere, trebuie să
li se adauge cele trei caractere ale parolei existente (dacă parola este abc, noua parolă trebuie să
fie abcabc).

Rezolvare:

1<?php
2$conn = mysqli_connect("localhost", "root", "");
3mysqli_select_db($conn,"test_db");
4$r = mysqli_query($conn,"SELECT * FROM users WHERE length(password) = 3");
while($row = mysqli_fetch_array($r)){
5 mysqli_query($conn,"UPDATE users SET password =
6concat(password,password) WHERE userid = {$row['userid']}");
7}
8mysqli_close($conn);
9?>
Acest exemplu are sintaxa deja bine cunoscută, dar şi funcţiile lenght şi concat care trebuie
explicate. Funcţia lenght numără caracterele aflate în câmpul la care se referă. Funcţia concat
face concatenarea înregistrării din câmp. Deoarece avem nevoie de concatenarea lui password cu
sine, ca şi parametrii funcţiei, definim password de două ori, separaţi pin virgulă.

Exerciţiul nr. 5

Trebuie creată funcția care pe baza interogării returnează șirul bidimensional din bază.

Testaţi funcția creată în tabelul users.

Rezolvare:

1
2 <?php
3 function
{
arrayFromDB($query)
4 $conn = mysqli_connect("localhost", "root", "");
5 mysqli_select_db($conn,"test_db");
6 $r = mysqli_query($conn,$query);
7 $resArray = array();
while($tmpArr = mysqli_fetch_row($r))
8 $resArray[] = $tmpArr;
9 return $resArray;
10}
11$users = arrayFromDB("SELECT * FROM users");
12foreach($users as $user)
echo "id: " . $user[0] . ", name: " . $user[1] . ", password: " .
13$user[2] . "<br>";
14?>
15

Funcţia arrayFromDB o vom folosi pentru executarea interogării către bază pe baza parametrului
alocat. În locul apelului, funcţia returnează şirul bidimensional cu rezultate. În cadrul funcţiei, se
face conexiunea cu bază şi executăm interogarea. Creăm şirul $resArray, care va conţine
rezultate ca fundal. Cu trecerea prin bucla while preluăm rând după rând şi punem interogarea în
şirul pregătit anterior. După ce funcţia execută toate iteraţiile, aceasta returnează şirul pregătit.

Exerciţiul nr. 6

Trebuie creată funcția care pe baza interogării transmise ca și parametru returnează valoarea
numerică care reprezintă numărul de rânduri după interogare.

Funcția trebuie testată în tabelul users.

Rezolvare:
1
2 <?php
3 function scalar($query)
4 {
5 $conn = mysqli_connect("localhost", "root", "");
mysqli_select_db($conn,"test_db");
6 $r = mysqli_query($conn,$query);
7 if(mysqli_num_rows($r) == 1)
8 {
9 $value = mysqli_fetch_row($r);
10 return (int)$value[0];
}
11 else
12 return "";
13}
14echo scalar("select count(userid) from users");
15?>
16

Funcţia scalar() o vom folosi pentru trimiterea interogării către bază, după care vom verifica
valoarea numerică returnată. Pe ultima linie de cod stă apelul funcţiei:

1echo scalar("select count(userid) from users");

Aici folosim funcţia count() care numără rândurile în tabel.

În cadrul funcţiei, stabilim conexiunea cu baza şi efectuăm interogarea:

1$conn = mysqli_connect("localhost", "root", "");


2mysqli_select_db($conn,"test_db");
3$r = mysqli_query($conn,$query);

Apoi, verificăm rezultatul returnat şi convertim data în integer, pe care îl returnăm din funcţie:

1$value = mysqli_fetch_row($r);
2return (int)$value[0];

Dacă nu există rezultate, returnăm un string gol:

1return "";

Funcţia MySQLi care transmite o interogare către serverul MySQL este:


mysqli_query
mysqli_connect
mysqli_fetch_result
mysqli_close

………………………………………………………………..

Literatură recomandată:
În limba engleză:

1. Learning PHP, MySQL & JavaScript: With jQuery, CSS & HTML5 (Learning Php,
Mysql, Javascript, Css & Html5), Robin Nixon,2015.

2. Modern PHP: New Features and Good Practices, Josh Lockhart, 2015.

3. Learning PHP 5, Learning PHP 5, 2014.

4. Learning PHP, MySQL, JavaScript, and CSS: A Step-by-Step Guide to Creating


Dynamic Websites, Robin Nixon, (Sep 3, 2012), O'Reilly

5. Programming PHP, Kevin Tatroe, Peter MacIntyre I Rasmus Lerdorf, (Feb 22, 2013),
O'Reilly

Librărie digitală:

1. PHP 6/MySQL Programming for the Absolute Beginner, Harris, Andrew B.

2. Beginning PHP5, Apache, and MySQL Web Development, Naramore, Elizabeth Gerner,
Jason Scouarnec, Yann Le
3. PHP 5 Fast and Easy Web® Development, Meloni, Julie, Thomson

Linkuri:

1. http://www.php.net/

2. http://www.w3schools.com/PHP/

3. http://www.tizag.com/phpT/

4. http://www.tutorialized.com/tutorials/PHP/1

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