Programarea Core Php.docx

  • Uploaded by: Vasile Sentiment
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Programarea Core Php.docx as PDF for free.

More details

  • Words: 56,418
  • Pages: 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 propriuzisă 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 , 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”>), 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 , 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 (). 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 Skypeul, ceea ce înseamnă că acesta trebuie dezactivat (mai târziu, această problemă se va rezolva întrun 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 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: –prefix=/usr/local/php –with-mysql=/usr/local/mysql 1./configure ./configure –prefix=/usr/local/php<span style="font-size: 14px; text-align: 2justify;">

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 *> <<>> ………………………………………………….

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 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 A h H g G i s d D I F n Y y s

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

Tabelul 2.1 Codul care urmează afişează data și ora curentă în cadrul paginii web:

1'; 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 Seconds Minutes Hours Day of the month Day of the week, numeric (Sunday is 0, Saturday is 6) Month, numeric Year, numeric (4 digits) Day of the year, numeric (e.g., 299) Day of the week, textual, full (e.g., “Friday") Month, textual, full (e.g., “January") Seconds since epoch (what time( ) returns)

Key seconds minutes hours mday wday mon year yday weekday month 0

Tabelul 2.2

1 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 Însă, pentru stilul orientat pe obiect, codul este: 1format('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 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

Problema nr. 2 În cadrul aplicaţiei PHP, se află o linie care emite date despre data și ora curente: 1 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 Î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; //Printing variables on the screen 7 echo $x; 8 } 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 leam 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; //Variable my_variable increases by 1 8 $my_variable++; 9 } 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() {

$GLOBALS["my_variable"]++; 2 } 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"; 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"; 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) echo $var . ":" . $value . '
'; 2 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; text3align: justify;"> Î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 6

"localhost"; "root"; ""; "myDB";

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 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

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

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

6 Rezolvare: 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
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 $număr++; $număr--; $număr+=2; $număr-=2; $număr*=2; $număr/=2;

Semnificaţie $număr=$număr+1; $număr=$număr-1; $număr=$număr+2; $număr=$număr-2; $număr=$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;">

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) echo "User is younger than 25 and older than 13 years"; 3 Î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) echo "User is 13 or 25 years old"; 3 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")){ echo "Valid user"; 4 } 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 and or xor

Denumire And Or Xor

Exemplu $x and $y $x or $y $x xor $y

&& || !

And Or Not

$x && $y $x || $y !$x

Rezultat Este true dacă şi variabila $x, şi variabila $y sunt true. Este true dacă cel puţin o variabilă este true. Este true dacă una sau cealaltă variabilă este true, dar nu şi dacă ambele sunt true. Este true dacă şi variabila $x, şi variabila $y sunt true. Este true dacă cel puţin o variabilă este true. 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 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 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

6 Rezultatul curent al aplicaţiei este: 448.2526

Rezolvare: 1 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"; 4 ?> 5

)

Rezolvare: Se poate utiliza operatorul modulo: 1"; 4 ?> 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 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) echo "This line of code depends of condition
"; 2 echo "This line of code will be executed in any case"; 3 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{ $b = $a; 4 } 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; $month = 2; 3 $year = 2013; 4 5 $result = checkdate( $month, $day, $year); 6 7 if ($result == true) 8 { echo "Date is correct."; 9 } 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 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 $page = "login.html"; 3 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) $statusName = "stays"; 7 else if($status == 2) 8 $statusName = "moves"; 9 else if($status == 3) $statusName = "dissapear"; 10 11else if($status == 4) { 12 if($lastStatus == 2) 13 $statusName = "dissapear"; 14 else $statusName = "unknown"; 15 } 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 '

Congratulations!!!

'; 5 } 6 elseif( abs($_GET['number'] - $secretNumber) < 10 ) { 7 echo '

You are near to the result!!!

'; 8 } 9 else 10 { 11 echo '

Try again!!!

'; } 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 { echo '

Congratulations!!!

'; 3 } 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 { echo '

You are near to the result!!!

'; 3 } 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 } 4

echo '

Try again!!!

';

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) { case valoare1: 2 //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 case valoare2: 6 //Blocul de cod care se va executa dacă expresia şi valoarea 2 coincid 7 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; case 2: 6 echo "x is two"; 7 break; 8 default: 9 echo "x is not one either two"; 10}<span style="font-size: 14px;"> 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"; case 2: 5 echo "x is two"; 6 default: 7 echo "x is not one either two"; 8}<span style="font-size: 14px;"> 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; case 3: 7 case 4: 8 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 6 break; 7 case "Tue": 8 case 2: echo "Today 9 break; 10case "Wed": 11case 3: 12 echo "Today 13 break; case "Thu": 14case 4: 15 echo "Today 16 break; 17case "Fri": 18case 5: echo "Today 19 break; 20case "Sat": 21case 6: 22 echo "Today break; 23case "Sun":

is Monday";

is Tuesday";

is Wednesday";

is Thursday";

is Friday";

is Saturday";

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; case $x%3 == 0: 7 echo "x is not divisible by 2, but it is divisible by 3"; 8 break; 9 default: 10 echo "x is not divisible by 2, either 3"; 11}<span style="font-size: 14px;"> 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; case is_string($x): 6 echo "x is a string"; 7 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 switch ( $category) 4 { 5 case "news" : 6 echo '

News from the world ...

'; 7 break; 8 case "politics" : echo '

Politics...

'; 9 break; 10 case "sport" : 11 echo '

Last sport results ...

'; 12 break; 13 default : echo '

Welcome...

'; 14 } 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 lam ş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 switch ( $category ) 4 { 5 case "news" : 6 echo '

News from the world...

'; 7 case "politics" : echo '

Politics...

'; 8 case "sport" : 9 echo '

Last sport results ...

'; 10 default : 11 echo '

Welcome ...

'; 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 ) { case 0: 3 echo "i is equal 0"; 4 break; 5 case 1: 6 echo "i is equal 1"; break; 7 case 2: 8 echo "i is equal 2"; 9 break; 10 default: echo "i is not equal 0, 1 either 2"; 11 } 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 ) { default: 4 echo "i is not equal 0, 1 either 2"; 5 break; 6 case 1: 7 echo "i is equal 1"; break; 8 case 0: 9 echo "i is equal 0"; 10 break; 11 case 2: 12 echo "i is equal 2"; break; 13 } 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
echo 'Case 1';

echo 'Case 2';

11 12 13 14 15 16 17 18 19 20 21} 22 23 24 25

case 3: echo 'Case 3'; break; default: echo 'Default 1'; break; default: echo 'Default 2'; break;

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"; switch ($way){ 3 case "a": 4 echo '

Regular customer ...

'; 5 break; 6 case "b": 7 echo '

Customer has found us over the TV commercial....

'; break; 8 case "c": 9 echo '

Recommendation...

'; 10 break; 11 default : echo '

We don't know how customer found us...

'; 12 } 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 17 18 După executarea programului, la ieşire obţinem rezultatul: 1 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 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 23 24

= $operand1 + $operand2; = $operand1 - $operand2; = $operand1 * $operand2; = $operand1 / $operand2; = "Unknown result.";

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 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"; 3 } 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
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; echo "Value of element $br is $colors[$i]."; 7 } 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"; 3 ?> 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: "; 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; $i++; 3 } 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; echo $i; 4 $i++; 5 } 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++) echo $i; 2 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++){ for($u=0;$u<10;$u++){ 2 echo $u . "
"; 3 } 4 echo "---$i
"; 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){ $colors .= $value . " "; 7 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){ bloc de instructiuni 2 } 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; echo $i . "
"; 3 } 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 { if($i>5) break; 3 echo $i; 4 } 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) break 2; 4 } 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 "
";

Rezolvare: 1 2 0) 7 echo "
"; 8 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 "
". 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++) echo pow($selectedNumber,$i) . "
"; 3 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
{ 5 echo $i; 6 for($u = 1; $u <= $b; $u ++) 7 { 8 if($u == $b || $i == 0 || $i == $a-1) echo $u; 9 else 10 echo "0"; 11 } 12 echo "
"; 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; = 8; 2$b for($i = 0; $i < $a; $i++) 3{ 4 echo $i;

5 for($u = 1; $u <= $b; $u ++){} echo "
"; 6 } 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
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 = 2) 5{ echo $number . "
"; 6 $number -= 1; 7 } 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){ echo "first
"; 4 while (1){ 5 echo "second
"; 6 while (1){ echo "third
"; 7 continue 3; 8 } 9 echo "This line will never be executed.
"; 10 } 11echo "This line either.
"; 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 . "
"; $number -= 1; 4 } 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 = << #I#
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 2 3 4 5

#I#
HTML; $divNum = 10;

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 echo str_replace("#I#", $i, $html); 12 $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

<span style="font-size: 14px; text-align:

1 justify;"> 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 <<
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
8 9 10 11 12 13 14 15 16 17?> 18 19

echo $amount. " + ". $number. " este egal cu : "; $amount = $amount + $number; echo $amount. "
"; } while ( $number!= 10 ); echo "
"; echo "Amount all numbers: ". $amount;

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{ }while ( $number!= 10 ); 5 6 echo "
"; 7 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. "
"; 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: "; echo " Quantity "; echo "Price "; while ( $counter<= 100 ) { echo " "; echo $counter; echo " "; echo $price * $counter; echo " "; $counter = $counter + 10; } echo ""; ?>

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: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number: Number:

380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399

Rezolvare: 1 "; 4 $number++; 5 }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{ echo "Number: $number
"; 3 $number++; 4 }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 "; $price = $price + 1; 6 }while($price <= 1000); 7 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 "); 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
2

Welcome to our site!

3
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 Some text.....

"; 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 iar apoi mai creăm încă un fişier cu următorul conţinut: 1 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 ş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

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 2 3... content of page .... 4 5 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" ) echo "no file"; 2 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)){ require_once ( $file ); 3 }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 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: title
"; echo "**********************************************"; echo "
Some text
"; 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 "**********************************************
"; 4 } 5 6 //calling function stars 7 stars(); 8 echo "title
"; //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:
1echo "************************************ Belgrade 2**************************************"; 3echo "
Text about Belgrade
"; "************************************* Paris 4echo ****************************************"; 5echo "
Text about Paris
"; 6echo "************************************* London 7**************************************"; 8echo "
Text about London
"; ?>

Folosind funcţia, acest cod s-ar putea rezolva astfel: 1 2 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;"> 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){ return $num1 + $num2; 2 } 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 return $sum; 5 } 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){ $sum = 0; 3 if(is_array($numbers)){ 4 for( $i=0; $i < sizeof( $numbers ); $i++){ 5 $sum = $sum + $numbers[$i]; 6 } return $sum; 7 }else{ 8 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; return $total; 3 } 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){ $num1 = $num1 + 1; 2 } 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: add_1(&$num1){ 1function $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<span style="font-size: 14px; text-align: justify;"> 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 "; 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 func2(); 5 } 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:
1 function str_reverse($str){ 2 $rez = ""; for($i=strlen($str)-1; $i>=0; $i--){ 3 $rez.=$str[$i]; 4 }

return $rez; 5 } 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 = ""; return $rez; 3 } 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--){ $rez.=$str[$i]; 2 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( define( define( define(

"SQUARE", 0 ); "RECTANGLE", 1 ); "CIRCLE", 2 ); "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

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;"> 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 3 Arrays 4 5 6

7 "; "Second color in array " . $colors[1] . "
"; 10echo echo "Third color in array " . $colors[2] . "
"; 11?> 12

13 14 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".
"; 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 "
"; 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++){ echo "Piece $i = $wordChunks[$i]
"; 5 } 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 2 3 4 5


{ 6 if( $arr[ $u ] < $arr[ $min ] ) 7 $min = $u; 8 } 9 $tmp = $arr[ $i ]; $arr[ $i ] = $arr[ $min ]; 10 $arr[ $min ] = $tmp; 11 } 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; for( $u = $i; $u < sizeof( $arr ); $u++ ){ 5 } 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
3 4 5 6 7 8 ?> 9 10

if($i>0){ echo $arr[$i] * $arr[$i-1]."
"; }else{ echo $arr[ $i ]."
"; } }

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]."
"; }else{ 3 echo $arr[ $i ]."
"; 4 } 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:
1 2 3 4 5 6 7 8 9 $arr = explode(" ", $lipsum); $words = array(); 10$counts = array(); 11for($i=0; $i<sizeof($arr); $i++){ if(!in_array($arr[$i], $words)){ 12 $words[] = $arr[ $i ]; 13 $counts[] = 1; 14 }else{ 15 for($u=0; $u<sizeof($words); $u++){ 16 if( $words[ $u ] == $arr[ $i ]){ $counts[ $u ]++; 17 } 18 } 19 } 20 } 21for($i=0; $i<sizeof($words); $i++){ echo($words[$i] . " : " . $counts[$i] . "
"); 22 } ?>

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++){ echo($words[$i] . " : " . $counts[$i] . "
"); 2 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 $value) { echo $key . '=>' . $value . '
'; 7 } 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"); $arr[1] = array(2, "Peter", "Andersen", "2222222222222"); 3 $arr[2] = array(3, "Ana", "Newman", "3333333333333"); 4 Am fi putut completa acest şir şi altfel, în timpul iniţializării: 1$arr = array( 2 array( 1, "John", "Miller", "1111111111111" ), array( 2, "Peter", "Andersen", "2222222222222" ), 3 array( 3, "Ana", "Newman", "3333333333333") 4 ); 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"; 2 } 3 sau dacă vrem să publicăm toate datele din tabel: 1for($i=0; $i"; 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:
1 7

array( 1, 2, 3, 4 ), 5, 6, 7, 8 ), 9, 0, 1, 2 )

ş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"; 4 } 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), array(0,0,0), 6 array(255,255,255) 7 ), 8 array( 9 array(255,255,255), 10 array(0,0,0), array(255,255,255), 11 array(0,0,0) 12 ), 13 array( 14 array(0,0,0), array(255,255,255), 15 array(0,0,0), 16 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++ ) for( $up1 = 0; $up1 < sizeof( $arr[ $sp ][ $up ]); $up1++ ) 4 echo $arr[ $sp ][ $up ][ $up1 ] . " "; 5 echo "
"; 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: "; } 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 . ".
"; 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 2echo 3echo 4echo 5echo

= array( "Bucharest", "Paris", "London", "Washington" ); array_pop( $arr ); array_pop( $arr ); array_pop( $arr ); 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 array(7, 7),"positions" => array(array(3, 2 $table 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++){ $pointExists = false; 6 foreach($table['positions'] as $pos){ 7 if($pos[0] == $fw && $pos[1] == $fh){ 8 echo 'X'; 9 $pointExists = true; } 10 } 11 if(!$pointExists) echo '0'; 12 } 13 echo '
'; 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++){ for($fw=1; $fw<=$table['format'][0]; $fw++){ 2 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'; $pointExists = true; 4 } 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 o n d o n

# # # B e l g r a d e

# # # # # # # # # N e w Y o r k

# # # # # # # # # # # P a r i s

Rezolvare: 1 7556900, "Bucharest" => 1500000, "New York" 8406000, "Paris" => 11836970); 3 => $max = 0; 4 $longestCityName = 0; 5 foreach($population as $k => $v) { 6 if($v > $max) 7 $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 { $currentPercent = ceil(($percent * $v)/10); 16

if($currentPercent >= $i) 17 echo "#" . " "; 18 else 19 echo "<span style='color:white;'>#" . " "; 20 } 21echo "
"; 22} = 0; $i < $longestCityName; $i++) 23for($i { 24 foreach($population as $k => $v) 25 { if(strlen( $k ) > $i) 26 { 27 $cityArr = str_split( $k ); 28 echo $cityArr[ $i ] . " "; 29 } else 30 echo " "; 31 } 32 echo "
"; 33} 34?>

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
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
programming."); Rezultatul pe pagină va fi următorul: PHP
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: 2

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 2echo 3echo 4echo 5echo echo 6

= "PHP is my favorite progamming language."; "Without functions : " . $str; "
"; "Function - strtoupper : " . strtoupper( $str ) ; "
"; "Function - strtolower: " . strtolower( $str );

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; $numOfGirls = 2; 2 printf("%s boys and 3

%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); $message2 = sprintf("%'.-20s%6.2f", $product, $price); 4 echo $message1; 5 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 ", "", $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) == "") die("invalid credentials"); 13 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: = "Lorem Ipsum is simply dummy text of the printing and typesetting 1$lipsum industry."; 2echo wordwrap($lipsum, 15, "
");

Rezolvare, varianta 2: = "Lorem Ipsum is simply dummy text of the printing and typesetting 1 $lipsum 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 if($tmpContent != "") 9 { 10 echo $tmpContent . "
"; 11 }

12 } 13 } 14echo $tmpContent; 15 16 17

$tmpContent = $lipsumArr[$i];

$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 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;"> Î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
Content... MYTEXT;

Un conţinut formatat astfel poate fi pus într-o variabilă sau poate fi trimis direct la ieşire: $a=<<<MYTEXT Title
Content... MYTEXT; echo<<<MYTEXT Title
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=" "; echo strlen($a); 2 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");

1style="font-size: 14px;">

//return 1<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 style="font-size: 10px;">eaza 1

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 7 va fi: mytext my text My text MY TEXT

Exerciţiul nr. 1 În aplicaţie, intră următoarea variabilă: $string = "[email protected]";

Scrieţi expresia regulată cu care se va verifica dacă valoarea variabilei este adresa de e-mail.

Rezolvare: 1 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 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:

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.



…………………………………………………………

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 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 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 codulsursă 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("@"); = value.lastIndexOf("."); 6 dotpos 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 19 action="" 20
22Email: 23 24
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

5
6referer check 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
6?> 7 Acest exemplu corectează erorile (caracterele interzise) din denumirea URL-ului: 1 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 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
'; 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 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 8

Sau, pur şi simplu, să întrerupem executarea programului: 1 2 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

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 . "
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 logurilor î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).



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 Ș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 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 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 { return "my exception"; 5 } 6 }<span style="font-size: 14px; text-align: justify;"> 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
14 15 16 17 18 19 20 21?> 22 23 24 25

} try { includeFile("index1.php"); } catch(Exception $ex) { echo $ex->getMessage(); }

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 [email protected] (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 "; 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) { // output data of each row 19 while($row = mysqli_fetch_assoc($result)) { 20 echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . 21$row["lastname"]. "
"; 22 }

23} else { echo "0 results"; 24 } 25 26mysqli_close($conn); 27?> 28 29 30 31 1


Ca să putem accesa baza de date, trebuie să ştim unde se află aceasta, trebuie să ştim numele bazei pe care vrem să o
accesăm şi trebuie să 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) { die("Connection failed: " . mysqli_connect_error()); 3 } 4 5echo "Connected successfully!
";

Funcţia mysqli_connect_error va returna mesajul generat care mai degrabă

1indică motivul conexiunii eşuate cu baza.

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.

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) { // output data of each row 2 while($row = mysqli_fetch_assoc($result)) { 3 echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . 4$row["lastname"]. "
"; 5 } 6} else { echo "0 results"; 7 } 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.

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;">


Î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;">

Î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)) echo "ID: " . $rw[0] . " - Name: " . $rw[1] . "
"; 2 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 "; 12 echo "Tel: " . $row['Tel'] . "
"; 13 echo "E-mail: " . $row['email'] . "
"; 14 } } 15 mysqli_close($conn); 16 } 17?> 18 19 20 21 A Web Page 22 23
24

Enter the last name of the employee and click the "Search"



25 26 27 28 30 31
Company XYZ Directory
29
32 33 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 3 4 A Web Page 5 6
7

Enter the last name of the employee and click the "Search"

8 9 10 11 12 14
Company XYZ Directory
13
15
16 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 "; 14 echo "Tel: " . $row['Tel'] . "
"; 15 echo "E-mail: " . $row['email'] . "
"; } 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'] . "
"; echo "Tel: " . $row['Tel'] . "
"; echo "E-mail: " . $row['email'] . "
"; }

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. INSERT UPDATE DELETE

coloane Tabele, coloane Tabele, coloane Tabele

TRUNCATE Tabele INDEX

Tabele

ALTER

Tabele

CREATE

Baze de date, tabele

DROP

Baze de date, tabele

Permite utilizatorilor să introducă rânduri noi. Permite utilizatorilor să modifice valorile în rândurile existente ale tabelului. Permite utilizatorilor să șteargă rândurile existente. Permite utilizatorilor să şteargă toate rândurile Permite utilizatorilor să indexeze anumite 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. Permite utilizatorilor să creeze noi baze de date și tabele. Dacă în comanda GRANT este introdusă o anumită bază de date sau un 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. Permite utilizatorilor să șteargă bazele de date și tabelele.

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 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

Rezolvare, varianta 2: 1 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 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 echo "invalid"; 4 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

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 "; 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 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

Related Documents

Programarea Turelor
October 2019 12
Core
October 2019 85
Core
November 2019 59

More Documents from ""

May 2020 11
Bca Protein Assay
December 2019 27
April 2020 33