Aplicatie Php Html Ajax Joc Trivia

=== 3cc234a7b22ecf5faccd931af6a5cb181d5c9880_321133_1 ===

INTRODUCERE

La momentul actual, aplicații de Trivia sunt din ce în ce mai răspânidte. Deși acestea sunt destul de numeroase, proiectul de față se diferentiaza de celelalte existente prin anumite trăsături definitorii, precum:

1. Folosirea programării web în exclusivitate, fără o aplicație în back end de tip C++, Java servlets.

2. Accesibilitatea mobilă, utilizând adaptive design, site-ul afișându-se proporțional ataât pe PC cât și pe dispozitive mobile (telefon, tabletă).

3. Customizabilitatea unei camere de joc. Majoritatea aplicațiilor de Trivia permit un singur mod ghidat de joc (număr fix de întrebări, numar fix de jucători). Această aplicație permite utilizatorului să își seteze după preferințe camera de joc (număr de jucători, număr de întrebări, întrebări aparținând unei anumite categorie)

4. Folosirea de elemente asincrone care permit mai multor utilizatori sa acceseze în timp real aceeași cameră de joc și implicit, același chat.

Aplicatia Trivia se bazează pe următoarele două module:

1. Un modul de tipul CMS (Content Managment System) la nivelul căruia se pot adauga întrebări, valida întrebări adaugate în partea de front end, verifica userii care și-au creat cont, precum și verificarea camerelor sau a sesiunilor active pe site.

2. Secțiunea de front end unde utilizatorul își poate crea cont, poate adăuga întrebări și bineînțeles poate juca Trivia, fie cautând o cameră dupa o anumită categorie, fie creându-și singur o cameră în cadrul căreia, ulterior, pot participa și alți jucători care se află în căutare.

Aplicația se fundamentează pe o baza de date MYSQL relațională și este construită pe framework-ul Codeigniter. Acest framework urmărește tehnica MVC (Model-View-Controller) ceea ce permite o flexibilitate sporită a codului. Toate parolele sunt stocate în format MD5, o metoda de cryptare unidirecțională pentru ca userii care au acces la baza de date să nu poată avea acces la parolele utilizatorilor normali. Acest lucru este în conformitate cu metodologia generală a aplicațiilor online.

Am abordat acest subiect întrucât, după o analiza amănunțită a aplicațiilor similare nu am identificat una asemănătoare, care să permită flexibilitatea necesară și care să fie realizată doar în limbajele menționate.

Scopul acestei lucrări este de a prezenta aplicația aferentă de Trivia relizata în PHP/HTML fără folosirea unui limbaj external de programare și care este adaptată și pentru dispozitive mobile.

Modul de utilizare este simplist: un user își poate crea cont și intra în joc în doar câteva secunde. Crearea de cont nu este esențială, dar în cazul în care utilizatorul nu face acest lucru, el va fi identificat dupa IP și datele sale de sesiune.

Folosind extensii ale limabjului PHP, hooks, la fiecare nouă accesare a site-ului, datele utilizatorului sunt stocate în baza de date, respectiv în sesiune pentru a nota activitatea sa.

Modul de funcționare al aplicației este următorul:

Un utilizator poate crea sau căuta o camera de joc. In cazul în care acesta caută o cameră de joc, va fi asignat automat la o cameră care nu este plină, conform categoriei din care acesta dorește sa primească întrebări.

În cazul în care utilizatorul creeaza o cameră, este necesar ca acesta să specifice numărul de jucători și intrebari, precum și categoria, el fiind redirectionat direct către locul dorit. Totodată, utilizatorul va trebui să astepte până când camera se umple (numarul de utlizatori în cameră este egal cu numarul maxim de utilizatori).

Dupa umplerea camerei, intrebarile vor fi afisate pe rând, una cate una, la un interval fix de 20 de secunde. Intrebarile pe care jucătorul le primește au raspuns multiplu lucru, astfel încât se va permite o verificare rapidă a validitatii raspunsului.

In camera de joc este prezent si un tabel de scor care este updatat la cateva secunde pentru ca utilizatorii sa își poată vedea realizarile. Totodată, in camera de joc exista si o functionalitate de chat prin care utilizatorii pot comunica intre ei.

Daca un utilizator paraseste camera de joc, jocul va continue in absenta lui, iar niciun alt jucator nu va fi repartizat in acea camera. Exista si o functie de stergere a camerelor goale care este rulata prin CRON-JOB, o dată la 1 minut. Ea verifica statusul camerelor si le sterge pe cele care au fost deja folosite, lucru denotat de statusul camerei.

Baza de date este una relationala asigurand ca nu exista inconsecvente de date (intrebari care nu au categorii, etc) , aceasta fiind generata cu ajutorul MYSQL Workbench, (https://www.mysql.com/products/workbench/), o aplicatie gratuita. Codul a fost realizat cu ajutorul editorului Notepad++ (https://notepad-plus-plus.org/download/v6.8.8.html), deasemenea o aplicatie gratuita.

Versiunea de test a fost realizata local pe baza WAMP (http://www.wampserver.com/en/), aplicatie gratuita care permite utilizarea locala de baza de date MYSQL, precum si a unui server Apache.

Folosind elemente specifice de CSS formatul vizual al aplicatiei se modifică în funcție de rezolutia la care este afisat, permitand astfel o afisare proportionala si eleganta indiferent de mediul de pe care este accesat site-ul. Aceasta metoda este cunoscuta sub numele de adaptive design.

Toate elementele interne ale aplicatiei sunt orientate pe obiecte, modelele ocupandu-se cu extragerea informatiilor din baza de date, view-urile cu prelucrarea lor pentru utilizatori si Controllerele distrbuind datele de la modele la view-uri. Frameworkul Codeigniter abstractizeaza conexiunea la baza de date si permite rescrierea linkurilor printr-o functie de routare si folosirea .htaccess.

In cele ce urmeaza voi descrie principalele limbaje de programare folosite precum si tehnicile de programare care au facilitat la crearea aplicatiei, urand ca in final sa prezint ideea de functionare generala a aplicatiei precum si descrierea functiilor care permit conexiunea in timp real intre jucatori.

CAPITOLUL II. LIMBAJE FOLOSITE

Programarea Web se constituie astăzi, în contextul exploziei informaționale și a extinderii de neimaginat de acum câțiva ani a rețelei Internet, ca unul dintre domeniile dezvoltării de aplicații software cu un trend permanent ascendent, într-o continuă evoluție, atât calitativă, cât și cantitativă. Practic, un important segment al dezvoltărilor informatice este acaparat de proiectarea și dezvoltarea de aplicații destinate Internetului, categoria Web fiind predominantă în acest sens.

2.1 PREZENTAREA LIMBAJULUI HTML

HTML reprezintă acrononimul expresiei Hypertext Markup Language, ceea ce înseamnă de fapt limbajul pe care browserele de Internet îl ințeleg și prin prisma căruia pot fi afișate paginile web. Limbajul de marcaje HTML, piatra de temelie a oricărei aplicații Web. Deși schimbările în domeniul programării înregistrează în permanență un tren evolutiv, elementele de bază ale HTML nu au suferit schimbări radicale. Elementele de bază ale acestui limbaj de marcaje sunt reprezentate de o serie de câmpuri sau marcaje speciale, cunoscute și sub denumirea de tag-uri (etichete HTML). O altă caracteristică esențială a HTML o constituie posibilitatea realizării de legături (link-uri sau hyperlink-uri) spre alte documente/pagini Web, așa cum rezultă și din denumirea lui (HypertText – element creând o legătură spre un alt document). Protocolul destinat comunicației în cadrul WWW (Word Wide Web sau pe scurt Web) este HTTP (Hypertext Transfer Protocol), asigurând transferul de informație între un server Web și un client browser Web.

Analizând elementele de bază ale HTML, se observă că acestea sunt reprezentate de o serie de câmpuri sau marcaje speciale, numite și tag-uri sau etichete HTML. Una dintre trăsăturile esențiale ale HTML o constituie posibilitatea realizării de legături (link-uri sau hyperlink-uri) spre alte documente sau pagini Web, după cum se relevă și în denumirea sa (HypertText , ceea ce desemnează un element care are capacitatea de a crea o legătură spre un alt document). Pentru a comunica în World Wide Web , se impune un anumit protocol , respectiv HTTP, acronim al expresiei Hypertext Transfer Protocol, prin intermediul căruia se asigură transferul de informație între un server Web și un client browser Web.

Pentru a formata modul de afișare a informației publicate, se impune folosirea unor etichete HTML . Este esențial de precizat faptul că prin mod de afișare se înțeleg anumite caracteristici ale textului , respectiv:

scrierea boldată a textului

alegerea unui anumit fundal pentru pagina nou creată

inserarea imaginilor

afișare sub fromă tabelară

integrare de sunet

alte aspecte legate de formatarea unei pagini Web.

Tag-urile amintite anterior reprezintă coduri speciale care însoțesc conținutul propriu-zis al paginii Web, stabilind modul în care acesta este afișată pe parte de client apelant. Codul HTML (împreună cu informația propriuzisă), stocat la distanță pe un server Web, este transferat spre un browser Web (folosind HTTP), fiind interpretat corespunzător de către acesta. Multitudinea de browsere Web folosite face ca modul de interpretare al unor etichete HTML să difere uneori de la un caz la altul (din acest motiv, testarea unei aplicații Web trebuie realizată de multe ori pe o gamă largă de browsere). Pentru o primă exemplificare, se consideră eticheta HTML reprezentând tag-ul pentru o afișare bold a unui text. În cazul în care acest tag pereche încadrează un text (vezi exemplul următor), afișarea textului se va realiza cu bold:

<b>Acest text este bold!</b>

Se remarcă în această situație, existența unui tag complementar atașat la sfârșitul conținutului textual al cărui rol este de a închide secțiunea de bold și de a comunica browser-ului că formarea impusă se încheie în acest punct. Cele mai multe tag-uri au un tag complementar de închidere a secțiunii delimitate, astfel că aceste etichete, de cele mai multe ori, sunt considerate perechi de delimitatori ai informației de afișat.

Sistemul HTML este unul de operare, independent de platformă, dar cu toate acestea, programatorii trebuie să ia în considerare situația în care se apelează resurse ale sistemului cu particularități diferite de la unul la altul. Un document în format HTML constă, în esență, într-o mulțime de tag-uri împreună cu informația utilă. Învățarea sintaxei acestor tag-uri este sinonimă cu învățarea HTML, ca limbaj de descriere a documentelor. Totuși, fără apariția unor limbaje de programare ca Java, JavaScript, PHP, Perl, limbajul de marcare HTML ar fi fost doar o simplă transpunere pe ecranul calculatorului a unor texte și grafice, având un format static, dinamismul fiind asigurat doar prin posibilitatea de navigare de la o pagină la alta.

Pe parcursul timpului, HTML, ca limbaj de marcare pentru hypertexte, a înregistrat o evoluție continuă, de la versiunea 1.0 ajungând în prezent, la versiunea 5. Dacă HTML 1.0 a fost responsabil cu introducerea unor concepte de antet, paragraf, referințe, liste, succesorul său, HTML 2.0, a adus un plus prin posibilitatea de inserare a imaginilor. HTML 3.0 este reprezentativ prin prisma introducerii tabelelor, a textului în jurul figurilor sau a diverselor frame-uri. Începând cu HTML 4 și continuând cu actuala versiune 5 (integrând semnificative facilități multimedia), noi etichete sunt adăugate, specificațiile altora sunt modificate, tendința principală fiind de a apropia aspectul și funcționalitățile unei aplicații Web de cele ale unei aplicații desktop.

Evoluția HTML continuă și în prezent, pe măsură ce tehnologia avansează de la zi la zi, integrând o serie plugin-uri dedicate și în același timp, extinzând substanțial capabilitățile multimedia ale site-urilor Web. În ultima vreme, se vorbește din ce în ce mai des despre DHTML (acronim al expresiei Dynamic HTML). Acesta reprezintă o combinație între HTML, CSS și JavaScript, AJAX – ca o integrare HTML, JavaScript și XML (eXtended Markup Language) și multe altele, toate acestea conducând la o dinamică sporită a paginilor Web. Această tendință evolutivă este strâns legată și de versiunile succesive de dezvoltare a browser-elor utilizate pe piață (Netscape, Mozilla, Microsoft Internet Explorer, Mosaic, Opera, Safari, Google Crome etc), fiecare preluând uneori într-o manieră personalizată noile standarde HTML (după cum s-a precizat deja, putându-se vorbi de o dependență de browser, adică același document HTML este interpretat în mod diferit de browsere diferite).

Etichete HTML

Etichete primare

Unele dintre cele mai importante și uzual folosite tag-uri (etichete) care permit crearea unei pagini Web sunt etichetele primare. Sintaxa completă (dar nu obligatoriu necesară) la crearea unei simple pagini Web conținând doar cod HTML este următoarea:

<html

<head>

<title>Prima pagină HTML </title>

</head>

<body>

Conținut prima pagină HTML

</body>

</html>

În ideea realizării unei aplicații Web, este necesară deschiderea unui editor de texte, după care se va introduce conținutul de mai sus (salvat într-un fișier cu extensia .html sau .htm), iar apoi se poate deschide pagina astfel creată dintr-un browser. Imediat o sa apară o pagină cu fundal alb, având titlul „Prima pagina HTML" afișat pe bara de titlu și o linie de text simplu afișată în zona de afișare a browser-ului, conținând mesajul „Prima pagina HTML". Tag-urile au fost scrise cu bold și totodată, se poate observa structura și poziționarea acestora în cadrul documentului. Mai jos se regăsește o scurtă descriere a rolului acestora în cadrul paginii, respectiv:

<html> </html> – Specifică faptul că documentul este de tip HTML. Toate documentele încep și se termină cu acest tag.

<head> </head> – Creează o zonă de informație de tip meta, cum este cazul titlului documentului, cuvinte cheie sau informații care descriu pagina pentru motoarele de căutare.

<title> </title> – Creează un „titlu” pentru document. Orice este scris în interiorul acestui tag, va fi afișat de către browser în bara de titlu.

<body> </body> – Creează o zonă specială pentru conținutul documentului (text, imagini etc). Aceasta este secțiunea în cadrul căreia se vor insera toate elementele „afișabile” ale paginii.

Aproximativ 99% din documentele Web, indiferent de dimensiuni sau grad de dificultate, conțin cel puțin tag-urile prezentate mai sus. Ele descriu cadrul general al oricărui document HTML. Din definiția tag-ului se poate deduce că mare mare parte din acțiunea unei pagini HTML se desfășoară în această secțiune, de vreme ce acest tag cuprinde tot conținutul afișabil al documentului. În acest sens, utilizarea tag-urilor HTML este non-case-sensitive (se pot folosi atât caracter mici, cât și mari).

Setarea unui fundal al paginii

Una dintre primele operații pe care cei mai mulți programatori Web începători doresc să îl facă unei pagini de Web este adăugarea unui fundal (background), indiferent dacă e vorba de un background de tip culoare sau imagine. În mod implicit, un document fără background va fi afișat pe un fundal alb. Această culoare se poate schimba foarte ușor. În acest sens trebuie adăugat următorul cod în interiorul zonei delimitate de tag-ul <body>:

<body bgcolor=”XXXXXX”>

unde xxxxxx este codul hexa al culorii dorite. Dacă acest cod este greu de reținut, se poate folosi chiar numele culorii.

În ceea ce privește modul de adăugare al unei imagini în fundal, folosirea fișierului imagine ”backgr15.jpg” pe post de background (fundal), este posibilă cu ajutorul următoarei expresii:

<body background=”backgr15.jpg”>

Pentru a evita apariția unor probleme datorate dependenței de sistemul de operare în referirea unor resurse ale acestuia, fișierului imagine referit în codul HTML trebuie să folosească tipul/combinația exactă de caractere -mari și/sau miciutilizată în denumirea lui ca resursă fișier gestionată de platformă (problemă mai puțin relevantă pentru platformele Windows, dar extrem de relevantă pentru Unix, Linux).

Formatarea textelor în limbaj HTML

Una dintre cele mai importante funcționalități a limbajului HTML, integrată chiar începând cu primele versiuni, o constituie posibilitatea formatării informației de tip text, toate documentele Web conținând cel puțin o astfel de informație primară, ca și conținut propriu-zis. În continuare, fără a avea pretenția de a epuiza întreg subiectul, sunt prezentate câteva dintre tag-urile uzuale destinate stabilirii unui format textual.

Heading

Noțiunea de heading desemnează un text – de regulă pe post de titlu/subtitlu – scris cu caractere mai mari și îngroșate, scos în evidență față de restul conținutului paginii. Pentru crearea lor se poate folosi eticheta , unde în loc de ? se trece un număr de la 1 la 6 (1 corespunde celor mai mari caractere ale textului, iar 6 se scrie pentru a obține cele mai mici caractere pentru respectivul text). Spre exemplu:

<h1>BUNĂ ZIUA! </h1>

<h2>BUNĂ ZIUA! </h2>

<h3>BUNĂ ZIUA! </h3>

Paragraful

Un paragraf poate fi creat în HTML prin utilizarea etichetei <p> care are rolul de a creea o zonă de text, care este separată de restul documentului printr-o linie vidă deasupra și dedesubtul zonei de text.

<p> Acesta este primul paragraf. Acesta este primul paragraf. Acesta este primul paragraf. </p>

<p> Acesta este al doilea paragraf. Acesta este al doilea paragraf. Acesta este al doilea paragraf. </p>

De asemenea, se poate controla și modul în care este aliniat textul în cadrul unui paragraf, folosind atributul align. Acest atribut acceptă trei valori: left, center și right.

Spre exemplificare, pentru a alinia un text la marginea din stanga a documentului se folosește sintaxa:

<p align=”left”> Acesta este un paragraf aliniat la marginea din stânga a documentului. Acesta este un paragraf aliniat la marginea din stânga a documentului. Acesta este un paragraf aliniat la marginea din stânga a documentului. Acesta este un paragraf aliniat la marginea din stânga a documentului. </p>

Tot pentru o structurare a conținutului unui document Web se poate folosi și eticheta <br> (break row), asigurând trecerea pe o linie nouă a informației precedate de aceasta etichetă (fără însă a spația și alinia corespunzător conținutul textual, ca în cazul paragrafelor).

Bold și Italic

Aceste două caractere se obțin cu ajutorul tag-urilor <b>, respectiv <i>.

Setare culoare, mărime și tip caractere

În HTML se pot specifica mărimea, culoarea și tipul caracterelor ce formează textul. În acest sens se folosesc trei etichete specializate, după cum urmează:

<font color="#FF0000">Acest text este rosu</font>

<font size="6">Acest text este mai mare!< /font>

<font face="Times New Roman">Acest text este scris cu caractere de tip Times New Roman < /font>

Centrarea textului

Eticheta <center> permite centrarea rapidă a unui text într-o pagină.

Crearea de bare orizontale

Textul poate fi foarte bine structurat în cadrul unui document și cu ajutorul unor bare orizontale (linie cu o anumită grosime și lungime) care să delimiteze mai bine diferitele secțiuni ale acestuia. Aceste bare se obțin cu ajutorul etichetei <hr>. Pentru a schimba dimensiunile acesteia se pot folosi atributele width și size

Inserarea unei imagini

Browserele recunosc, in cadrul paginilor web, mai multe formate ale imaginilor. Cele mai raspandite sunt cele cu extensia .gif si cele care au una din terminatiile .jpg sau .jpeg. Iata in continuare cateva caracteristici ale acestor formate de imagini.

Asa cum ai vazut, la majoritatea site-urilor, imaginile dau o nota aparte paginilor web. Pentru a folosi imagini si in cadrul paginilor tale web trebuie sa folosesti tag-ul <img> insotit de atributul SRC (source) care indica adresa sau calea catre imaginea ce urmează a fi utilizată. Forma generală a acestui tag va fi: <IMG SRC="numeleimaginii.extensie">

Trebuie acordata o atentie deosebita extensiei. Aceasta trebuie scrisă extensia imaginii pentru ca altfel imaginea nu va fi afișată de browser. Ca și observație, trebuie să se țină cont de faptul că la încărcarea uneia sau mai multor imagini de mari dimensiuni poate constitui uneori sursa unei viteze de reacție scăzute din partea paginii Web (fiind vorba de un transfer al unui volum mai mare de informație). Din acest motiv, dimensiunea acestora trebuie să fie rezonabilă, recomandându-se utilizarea fișierelor imagine în format comprimat (jpg, png, tif).

Hiperlegături

Tot la capitolul caracteristici fundamentale ale HTML se încadrează și posibilitate de a crea hyperlink-uri, asigurând conexiunile spre alte pagini Web și implicit ―navigarea‖ pe internet. Legăturile sunt esențiale pentru WWW. În acest sens, evoluția și expansiunea WWW sunt asigurate prin conectarea în masă a unei multitudini de pagini Web (și nu numai) la nivel mondial. Hyperlink-ul este creat cu ajutorul etichetei ancoră <A>. . Aceasta necesită un atribut href, care specifică URL-ul (Uniform Resource Locator) , cel din urmă reprezentând obiectivul țintă de urmat după ce se dă click pe respectiva legătură.

<a href="http://www.yahoo.com">Click here for Yahoo</a> este legătura care trimite spre site-ul Yahoo. Totodată, se pot face legături folosind și imagini. Crearea de hyperlink-uri folosind imagini este presupune substituirea textului cu eticheta <img>.

Formulare

Majoritatea aplicațiilor Web utilizează script-urile în scopul prelucrarării informației introdusă prin intermediul unor fișiere HTML gen formular. Script-ul, de regulă un CGI, are rolul de a prelua informația, a o prelucra și de a returna un răspuns (o pagină HTML afișabilă de către un browser client) cu informația procesată ca rezultat. Altfel spus, rolul unui script constă în returnarea (pe baza unei procesări de informație realizată pe un server Web) a unor date la ieșirea standard (browser). Aceste date sunt precedate (dacă este cazul) de o serie de antete care vor permite o interpretare corectă a ieșirii scriptului. Astfel de scripturi permit interacțiunea în ambele sensuri între client și server. Antetul pe care scriptul îl trimite spre serverul Web trebuie să respecte specificațiile MIME (Multipurpose Internet Mail Extension). Spre exemplu, un astfel de antet poate să conțină o specificație de forma: Content-type: text/html (pentru documente HTML), Content-type: image/jpeg (pentru imagini JPEG) etc., care va precede informația direcționată spre ieșirea standard, precizând tipul de date care constituie flux de ieșire. Cele mai multe apeluri ale unui script CGI se fac prin intermediul unui document HTML gen formular, la apăsarea unui buton (de regulă- SUBMIT).

Formularele reprezinta o metoda de interactivitate cu utilizatorii paginii tale web. Prin intermediul unui formular poti obtine date importante de la vizitatorii paginii tale. Dupa ce formularul a fost completat, utilizatorul apasa un buton de trimitere, iar tu primesti datele introduse in formular sub forma unui e-mail sau datele vor fi procesate cu ajutorul unui limbaj de programare si adaugate intr-o baza de date. In aceasta lectie vom invata cum se pot adauga in cadrul unei pagini web diferite tipuri de formulare, dar si cum putem trimite datele introduse intr-un formular, prin email. Pentru a folosi un formular in pagina ta web, va trebui sa folosesti tag-urile <FORM> si </FORM>. Intre aceste tag-uri vor fi introduse toate elementele formularului.

Se observă că în cadrul formularului (FORM) se folosește metoda GET pentru transmiterea parametrilor spre scriptul indicat prin proprietatea ACTION (în cazul de față, un script PHP). Prin apăsarea butonului de tip SUBMIT ―Run Query‖, presupunând că inițial s-a tastat 5, respectiv 1000, spre scriptul apelat este transmis un șir (string) de forma

ani=5&salar=1000.

Acest șir de parametrii poate fi remarcat și în linia de apelare a scriptului, de altfel parametrii putând fi transmiși și direct spre script, printr-un apel (cu precizarea completă a căii spre scriptul PHP) cu parametri de forma:

http://localhost/scripts/exemplu.php?ani=5&salar=1000

De remarcat că, variabilele sunt delimitate prin caracterul &, iar caracterele speciale (\ sau ‗) sunt înlocuite de codul lor numeric (hexa), precedat de caracterul procent %. Spațiile se substituie prin semnul +. Atributul SIZE al unei etichete casetă INPUT setează dimensiunea vizibilă a acesteia pe ecran. Utilizând metoda GET, acest string este disponibil într-o variabilă de mediu QUERY_STRING. Funcție de mediul folosit pentru crearea scriptului CGI, aceste date utilizabile ca parametrii de intrare pot fi preluate, dacă este cazul, din cadrul acestei variabile de mediu. Același formular putea folosi ca metodă și metoda POST. În cazul metodei POST datele sunt disponibile, putând fi accesate de la intrarea standard (și nu prin intermediul unui string conținut în variabila de mediu QUERY_STRING, lungimea acestora (în octeți) fiind disponibilă în variabila de mediu CONTENT_LENGTH. Evident acest șir (văzut ca parametru de intrare cu GET) nici nu apare în linia de apelare a scriptului, așa cum se întâmplă la metoda GET. Se recomandă utilizarea metodei POST în situația transmiterii unui volum mare de date (gen <TEXTAREA> sau a unui fișier – printr-o acțiune de upload). Un exemplu de utilizare a etichetei TEXTAREA:

<textarea rows=”3”cols=”30”name=`nume`>

Se adaugă text pe primul rând.

Alt rând

</textarea>

Eticheta INPUT este cel mai des utilizată cu atributul type=‘text‘, valoare de altfel implicită, astfel încât se putea echivala cu

<input NAME=”ani”type=’text size=”2”maxlength=2 value=20>

folosindu-se în acest exemplu și alte două atribute deseori utile:

– maxlength – pentru a se limita numărul de caractere care pot fi introduse de la tastatură (size limitează doar numărul de caractere afișabile, putându-se introduce oricâte, dar zona afișabilă a casetei permite doar două caractere vizibile – ultimele două).

– value – pentru a seta o valoare inițială implicită (20 în cazul de față).

De asemenea, tipurile SUBMIT, respectiv RESET sunt strict legate de formularul FORM, transformând fiecare caseta aferentă într-un buton și activând transferul datelor prim metoda setată, respectiv resetând (ștergând) conținutul casetelor din formular. Atributul TYPE permite o listă de valori specifice, enumerându-se aici doar câteva dintre cele mai uzuale:

– button – folosit în special pentru activarea unui script/secvențe JavaScript la apariția unui eveniment

– checkbox– folosit pentru limitarea opțiunilor selectate (predefinite și în număr limitat), permițând selecția uneia sau mai multora (selecție multiplă).

– radio– folosit pentru limitarea opțiunilor selectate, permițând selecția doar a uneia sigure.

– password – asigură ascunderea conținutului introdus în casetă (cazul parolelor)

– file – generează o casetă, respectiv un buton Browse, necesare operației Upload de fișiere.

– image – definește un buton SUBMIT de tip imagine, atributul VALUE fiind înlocuit cu SRC pentru referirea unei imagini

– hidden– ascunde caseta, fiind util la transferul unor valori implicite din FORM spre o altă pagină, valori setate prin atributul VALUE.

Frame-uri

Frame-uri linie/coloană

Frame-urile (cunoscute și sub denumirea de cadre) sunt elemente HTML prin prisma cărora se realizează o împărțire a ecranului în mai multe zone (regiuni) de afișare, permițând utilizatorului afișarea simultană în același ecran a mai multor pagini Web.

O astfel de împărțire a ecranului în mai multe regiuni, permite o prezentare a informației într-o formă mai flexibilă, mai practică și uneori mai utilă. În fiecare frame (având un anumit nume) este afișat conținutul unui anumit fișier HTML (script), referit printr-un URL. Frame-ul poate fi redimensionat (opțional) de către utilizator. Cele mai uzuale marcaje (cuvinte cheie, tag-uri) specifice proiectării unei pagini Web utilizând frame-uri sunt: , (absolut obligatorii), respectiv (ca atribute opționale): <FRAMESET>, <FRAME>, <NOFRAMES> , TARGET, ROWS, COLS, FRAMEBORDER, BORDERCOLOR, FRAMESPACING, NORESIZE, MARGINWIDTH, MARGINHEIGHT, SCROLLING, <IFRAME> .

Utilizarea unor frame-urile în cadrul unei pagini Web presupune, într-o primă fază, o definire a acestora în cadrul documentului HTML. Definirea frame-urilor precizează tipul acestora, numărul și poziția lor în cadrul paginii Web, precum și URL-urile (adresele) către fișierele HTML care vor constitui conținutul lor (conținutul propriu-zis fiind practic stocat întotdeauna separat, într-un alt fișier HTML). Definiția unei succesiuni de frame-uri care vor fi plasate pe un ecran este marcată printr-o etichetă de tip <FRAMESET>. Dimensiunea și plasarea în pagină a unui frame sunt precizate în termeni de rânduri și coloane, utilizând combinații de etichete <FRAMESET> si <FRAME>.

Acum se recomandă evitarea folosirii frame-urilor (datorită modului deficitar în care este percepută o pagină dintr-un frame de către un motor de căutare), acestea oferă încă o alternativă simplă și eficientă de structurare a informației din mai multor pagini Web pe un singur ecran (fiind încă des întâlnite mai ales în cadrul aplicații Web intranet, neindexabile de către motoarele de căutare).

Frame-uri încuibate

Pentru a crea un aranjament mai complex al paginii Web se poate plasa o definiție FRAMESET și frame-urile asociate ei într-o altă definiție FRAMESET. Această metodă este cunoscută sub denumirea de încuibare de frame-uri.

Nu există o limitare a numărului de frame-uri care se pot grupa (încuiba), deși, în practică, utilizarea a mai mult de trei frame-uri pe ecran face ca lucrurile să devină complicate pentru utilizator. Pot încă apare situații de clienți Web care utilizează pentru navigare un browser non-frame (care nu suportă frame-uri). Problema este destul de importantă, deoarece trebuie să se asigure citirea conținutului paginii și în cazul utilizării unui astfel de browser. Elementul <NOFRAMES> permite asigurarea acestei cerințe. În interiorul etichetelor pereche <NOFRAMES>….</NOFRAMES> se poate pune orice informație care s-ar pune normal între etichetele <HTML></HTML>.

Dacă nu se oferă o alternativă de utilizare prin plasarea unei informații între etichetele <NOFRAMES>…</NOFRAMES> , un "cititor" al paginii care utilizează un browser care nu suportă frame-uri, nu va vedea nimic și va fi forțat să abandoneze navigarea pe acel site. Browser-ele care suportă frame-uri ignoră conținutul plasat între etichetele <NOFRAMES>.

Caracteristicile frame-urilor

Asupra frame-urilor se poate exercita un control setând corespunzător anumite proprietăți ale acestora. Astfel, se poate pune sau nu o bordură frameurilor, se pot colora, se pot îndepărta barele de rulare (scrooll) sau se poate realiza o redimensionare a lor. Atribute ale etichetei <FRAMESET>

FRAMEBORDER="yes|no"|0 – permite sau nu punerea unei margini (borduri) în jurul frame-urilor aferente unei definiții FRAMESET. În mod curent, începând cu Netscape Navigator 3 (și continuând cu Mozilla) se folosesc valorile yes și no, în timp ce Microsoft Internet Explorer folosește valoarea 0 pentru a scoate bordura (care altfel este implicită). Pentru ca marginile să nu fie trasate, toate frame-urile care își împart o margine comună, trebuie să aibă atributul FRAMEBORDER setat pe "no". Acest atribut poate fi folosit și cu eticheta <FRAME> pentru setarea marginilor pentru un singur frame, bine precizat.

BORDER=pixels – utilizat doar începând cu Netscape Navigator 3 (sau o versiune mai evoluată Mozilla), acest atribut permite setarea lățimii marginilor (bordurilor) în pixeli, într-o definiție FRAMESET.

BORDERCOLOR="#hexcolor|colorname" – se poate utiliza acest atribut (doar cu Mozilla), permițând setarea culorii bordurii frame-urilor cuprinse într-o definiție FRAMESET, prin specificarea unui triplet hexa RGB convențional sau direct a numelui culorii. Atributul poate fi utilizat și cu eticheta <FRAME>pentru setarea culorii marginii unui singur frame.

Caracteristici ale etichetei FRAME

Următoarele atribute pot fi aplicate la elementele pentru un control suplimentar la nivelul unui singur frame, bine precizat:

SCROLLING="yes|no|auto" – permite introducerea sau nu, a unei bare de derulare (scroll) a conținutului frame-ului. În lipsă, valoarea implicită este "auto", lăsând browser-ul să decidă dacă frame-ul are nevoie de bare de derulare (informația afișată în frame nu este vizibilă, nu încape în totalitate în zona de afișare aferentă frame-ului) sau nu.

NORESIZE – împiedică redimensionarea frame-ului. În lipsa lui, implicit, utilizatorul poate redimensiona frame-urile, trăgând marginile acestora într-o nouă poziție.

MARGINWIDTH=pixels – setează dimensiunea marginilor din dreapta și stânga frame-ului, în pixeli (distanța dintre text și margine). În lipsa atributului, implicit, browserul va decide singur dimensiunea marginilor.

MARGINHEIGHT="pixels" – setează marginea de sus și de jos a frameului, în pixeli. În lipsa atributului, browser-ul va decide singur dimensiunea acestor margini.

BORDERCOLOR="color" – începând cu Netscape Navigator 3 (actualmente Mozilla) este permisă setarea culorii marginii frame-ului, prin specificarea unui triplet hexa RGB convențional. Acest atribut poate fi utilizat și cu eticheta <FRAMESET> pentru seterea culorii marginii pentru un grup de frame-uri.

FRAMESPACING="pixels" – începând cu Microsoft Internet Explorer 3, atributul permite setarea spațiului liber din jurul frame-ului, definit în pixeli.

FRAMEBORDER="yes|no"|0 – permite plasarea sau nu a unei margini din jurul frame-ului. În mod curent, începând cu Netscape Navigator 3 se folosesc valorile yes și no, în timp ce începând cu versiunea Microsoft Internet Explorer 3 se folosește valoarea 0 (implicit, lipsa atributului, semnifică faptul că frame-ul are bordură). Acest atribut poate fi folosit și cu eticheta <FRAMESET> pentru setarea marginilor unui grup de frame-uri. Marginile unui frame vor fi eliminate numai dacă ambele frame-uri adiacente (chiar definite în FRAMESET-uri distincte) au atributele FRAMEBORDER setate în conformitate.

Frame-uri legate

Unul din principalele avantaje ale utilizării frame-urilor, constă în faptul că se poate utiliza o legătură (link) dintr-un frame, pentru a deschide (afișa) o anumită pagină într-un alt frame, pe aceeași pagină ecran. Apelând o anumită referință (sau apăsând un buton) într-unul din frame-uri (sursă), se poate deschide astfel o nouă pagină într-un alt frame (țintă, ―target‖) al aceluiași ecran, restul conținutului ecranului rămânând neschimbat.

Primul pas pentru a stabili un rol de ―target‖ pentru un frame constă în atașarea unui nume acelui frame. Această operație este realizată în eticheta de definire a frame-ului respectiv (<FRAME>)utilizând atributul NAME.

Direcționarea unei informații dintr-un fișier HTML spre un anumit frame ―target‖, se face utilizând atributul TARGET. Acest atribut nu se găsește în definirea frame-ului, fiind utilizat ca atribut pentru diverse etichete HTML (ancore, butoane) în scopul direcționării datelor/informației spre un anumit frame ‗țintă‘.

Dacă numele țintei specificate cu atributul TAGET nu există, documentul legat va fi deschis într-o nouă fereastră, având numele similar cu cel precizat în atributul TARGET. Există câteva nume ―țintă‖ speciale, predefinite. Toate acestea încep cu liniuță de subliniere ( _ ) și sunt folosite pentru încărcarea unor pagini în anumite frame-uri.

Aceste target-uri speciale sunt:

TARGET="_self" – documentul se încarcă în același frame care conține și legătura (frame-ul se încarcă pe el însuși, opțiune implicită).

TARGET="_parent" – documentul se încarcă în aceeași pagină frameset ca și legătura, în felul acesta îndepărtând orice alte "sub-frame-uri". Practic se încarcă pagina părinte în care este realizată definiția FRAMESET.

TARGET="_top" – documentul se încarcă în tot corpul ferestrei, aceasta eliberându-se de toate frame-urile. Această metodă este utilă atunci când o legătură direcționează utilizatorul spre un alt site.

TARGET="_blank" – documentul se încarcă într-o fereastră nouă. Atributul TARGET este deseori folosit în cadrul unui FORM inclus într-un frame, asigurând afișarea pagini apelate (spre care se transmit parametri) într-un alt frame.

Parametrii formularului sunt pasați spre pagina apelată (apel.php), aceasta procesând informația transmisă și o afișează în frame-ul numeframe (altul decât frame-ul în care este afișat formularul) Observație: Începând cu versiunea 3.01 Microsoft Internet Explorer suportă și așa numitele floating frames, prin utilizarea etichetei <IFRAME> plasarea unui frame putându-se face în orice poziție a unei pagini Web.

Tabele

O tabelă permite organizarea datelor pe linii (rânduri) și coloane, ca modalitate de prezentare a unei informații (text sau grafică) într-o pagină. Tabelele sunt extrem de utilizate ca mod de formatare a informației returnate prin interogarea unei baze de date. Cele mai uzuale marcaje (cuvinte cheie, tag-uri, etichete) specifice proiectării unei pagini Web utilizând tabele (afișări tabelate) sunt: <TABLE> <TR> <TD> <TH> etc.

Definiția oricărui tabel presupune utilizarea perechii de etichete <TABLE> </TABLE>. În definiția tabelei se poate folosi (opțional) o etichetă <CAPTION> , prin care se atașează un titlu tabelului. După cum se va prezenta în continuare, tabelele sunt construite succesiv, linie cu linie (o linie la un moment dat, apoi altă linie, s.a.m.d.). Liniile unei tabele sunt definite prin perechi de etichetele <TR> </TR>. În interiorul acestor etichete trebuie inclus cel puțin un header (cap de tabel) sau element de tip date (articol, informație) utilizând perechea de etichete <TH> </TH>, respectiv <TD></TD> (etichete controlând definirea unei coloane sau mai precis un element coloană al unei linii). De subliniat faptul că, construcția unei tabele începe tot timpul cu definiția unei linii (<TR>) iar în cadrul definițiilor liniilor sunt generate celulele aferente coloanelor(<TH> pentru celule cap tabel, <TD> pentru celulele date)

Controlul global al unui tabel

Există numeroase metode pentru a controla designul unui tabel. În primul rând, se poate adăuga o bordură (margine) fiecărei celule a tabelului; această operație creând practic un caroiaj pentru tabel. Se poate specifica poziția titlului tabelului (sus sau jos) și lățimea tabelului. Se poate, de asemenea, spația conținutul tabelului, adăuga spații între celulele tabelului sau crea margini (contururi) în jurul conținutului fiecărei celule. Toate aceste efecte pot fi realizate prin adăugarea unuia sau mai multora dintre atributele următoare, specifice etichetei de control global al designului unui tabel <TABLE>.

BORDER=value – includerea acestui atribut permite realizarea unei borduri în jurul tuturor celulelor tabelului. Lățimea bordurii se precizează în pixeli. Dacă atributul nu este utilizat, nu apare nici o bordură, totuși un spațiu liber va rămâne în jurul fiecărei celule ca și cum o bordură ar fi prezentă.

ALIGN=left/right – folosit pentru a afișa tabelul în stânga, dreapta sau centrat în fereastră. (pentru Nestcape, valabil începând cu versiunea 4, și continuând cu Mozilla).

CELLSPACING=value – permite specificarea dimensiunilor (în pixeli) a spațiilor inserate între celulele individuale ale tabelului.

CELLPADDING=value – permite specificarea dimensiunii (în pixeli) a spațiului inserat între marginea și conținutul unei celule din tabel.

WIDTH=value/percent – permite precizarea lățimii tabelului (în pixeli sau în % referitoare la lățimea documentului (paginii)).

Cel mai compactat tip de tabel trebuie să folosească atributele BORDER, CELLSPACING și CELLSPADDING setate pe zero.

Modificările care pot fi făcute afectează alinierea (pe orizontală sau verticală), lățimea și înălțimea celulelor, aranjarea textului ca informație. De asemenea se pot adăuga culori sau grafice (vezi paragrafele următoare). Următoarele atribute pot fi aplicate unei întregi linii, prin includerea lor între etichetele de tip <TR> sau unei celule individuale prin includerea între etichetele <TD> </TD>.

ALIGN=left/center/right – permite alinierea întregului text al unei linii sau celule.

VALIGN=top/middle/botton/baseline vertical align – utilizat pentru alinierea întregului text al unei linii sau celule (sus, la mijloc, jos) și de asemenea pentru a specifica faptul că toate celulele încep (sunt aliniate) de la aceeași linie de bază.

WIDTH=value/percent – permite setarea lățimii celulei (în pixeli sau % din lățimea tabelului). Fixarea unei lățimi particulare pentru o celulă, conduce la fixarea acelei lățimi pentru tot tabelul.

HEIGHT=value/percent – permite setarea înălțimii celulei (în pixeli sau % din lățimea tabelului). Fixarea unei înălțimi particulare pentru o celulă, conduce la fixarea acelei înălțimi pentru toată linia.

NOWRAP – specifică faptul că liniile dintre celule nu vor fi întrerupte pentru a seta lățimea celulei.

Combinarea celulelor Următorul pas pentru crearea unui tabel cu un aspect dorit, constă în unirea unor celule, atunci când aceasta se impune. Se pot uni celule astfel încât, o celulă să cuprindă două sau mai multe linii sau două sau mai multe coloane. Acest lucru se poate face utilizând atributele COLSPAN și ROWSPAN, astfel:

COLSPAN=value – utilizat pentru a specifica câte coloane sunt cuprinse întro celulă.

ROWSPAN=value – utilizat pentru a specifica câte linii sunt cuprinse într-o celulă.

Formatarea coloanelor Prin utilizarea etichetelor <COL> sau <COLGROUP> se poate specifica aranjarea textului în cadrul coloanelor unui tabel. În mod esențial, aceste atribute permit formatarea unor celule în cadrul unei coloane. Se utilizează atributul <COLGROUP> pentru a formata două sau mai multe coloane în același timp și <COL> pentru a formata o coloană individuală. Atributul trebuie întotdeauna inclus în cadrul unei perechi de etichete <COLGROUP>.

ALIGN=center/justify/left/right – alinierea textului (pe orizontală)

VALIGN=baseline/bottom/middle/top – aliniere pe verticală .

SPAN=number – setează numărul de coloane asupra cărora acționează atributele ALIGN și VALIGN.

WIDTH=pixels – setează lățimea coloanei în pixeli

Liste

Listele permit ordonarea după anumite criterii și afișarea informației pe ecran sub forma unor articole (item-uri) bine structurate. Există mai multe tipuri de liste care pot fi create, cele mai importante fiind listele ordonate și neordonate. Câteva etichete specifice creării unor liste sunt: <LI>, <OL>, <UL>, <MENU>, <DIR>, , <DL>, <DD>, <DT>.

O listă conține o succesiune de item-uri (articole/elemente). Tipul de listă determină cum sunt descrise (afișate) item-urile. Pentru cazuri mai complexe se pot crea și liste încuibate, pe mai multe nivele.

Mapări pe imagini

Mapările pe imagini constă practic în delimitarea anumitor zone active pe suprafața unei imagini (crearea unei ―hărți‖), sub forma unor regiuni de tip referință-link, la al căror apelare (click) se execută o anumită operație (de regulă încărcarea unui document HTML, apelul unui script etc.). Etichetele de bază pentru realizarea unei mape pe o imagine sunt : <MAP>, <AREA>

Alegând o imagine convenabilă, este necesară în primul rând afișarea graficului pe ecran și indicarea faptului, că referitor la respectiva imagine, există creată o mapare. Pentru a realiza acest lucru se folosește eticheta <IMG>, cu atributul USEMAP. În continuare este necesară descrierea coordonatelor care delimitează zonele active mapate și a acțiunilor care se execută la apelul acelei mape. Cu alte cuvinte, maparea unei imagini constă în atribuirea unei anumite acțiuni diverselor regiuni ale unei imagini, pe care se face click cu mouse-ul.

Dinamică și multimedia. HTML 5

Unul dintre obiectivele majore ale fiecărei noi versiuni HTML a fost îmbunătățirea dinamicii paginilor Web, asigurându-le o interactivitate cât mai mare, respectiv un design cât mai atractiv, în principal printr-o extindere a capabilităților multimedia. Câteva exemple care surprind aceste aspecte sunt punctate în continuare:

Crearea unui blinking text Limbajul HTML dispune de o etichetă pentru a crea un text special ca dinamică, care să se evidentieze atunci când un navigator accesează o anumită pagină. Aceasta este eticheta <blink> , iar textul marcat de ea va înregistra un efect dinamic de “clipire”:

<blink>Acesta este un text blink </blink>

Tag-ul <blink>este interpretat numai de browserele Mozilla, celelalte neasigurând o clipire a textului.

Elementul de tip <marquee> : Dacă se dorește o deplasare a unui text pe ecran, în genul unei reclame, un alt tag poate fi utilizat rapid și eficient. Doar Internet Explorer suportă eticheta specială <marquee> care asigură o defilare (scrolling display) pe ecran a oricărui text încadrat de ea.

<marquee> Dacă folosiți IE, textul trebuie să se deplaseze! </marquee>

Această etichetă nu este suportată de alte browsere, acestea afișând întregul text, fără însă a-l deplasa pe ecran.

Etichete META destinate multimedia – Cifra care apare în interiorul atributului CONTENT, asigură un refresh (reîncărcare) a secvenței multimedia după un interval de timp prestabilit.

HTML 5

Ultima versiune HTML 5 vine cu o serie de facilitați care îmbunătățesc performanțele multimedia ale aplicațiilor Web. Astfel, dinamica unei pagini este mult crescută prin introducerea unor noi etichete vizând partea audio, video și grafică, tratarea erorilor este mai simplă și eficientă, iar pentru o serie de etichete HTML anterioare sunt modificate și specificațiile/atributele.

Totodată o serie de etichete sunt abrogate. Spre exemplu, frame-urile nu mai sunt funcționale într-un document HTML 5, iar eticheta <object> permițând încapsularea unor obiecte plugin pentru diverse facilități (în special multimedia) este și ea abrogată, fiind substituita cu noi etichete HTML 5 . În momentul actual se poate vorbi de o confruntare în zona Web multimedia între tehnologia HTML 5 funcționând fără plugin-uri adiționale (aplicații software adiționale), respectiv tehnologia clasică bazată pe plugin-urile Flash. Actualmente, browser-ele într-o proporție covârșitoare suportă Flash, în timp ce sub jumătate dintre ele suporta HTML 5. HTML 5 implică o utilizare intensivă a altor tehnologii conexe bazate pe JavaScript, CSS, Canvas având o deschidere, conectivitate și capacitate mult mai mare de integrare cu noi tehnologii, ceea ce îl plasează ca potențial câștigător în confruntarea cu tehnologia bazata pe clasicele plugin-uri. De menționat totuși că în acest moment se pare ca nici un browser Web nu suporta în totalitate HTML 5, pe cele mai bune poziții situându-se în acest sens Google Crome, Safari și Firefox 4. Câteva secvențe de cod HTML 5 pentru simple exemplificări sunt punctate în cele ce urmează:

– orice cod HTML 5 este precedat de o declarație de tipul: <!DOCTPE html>

– rularea unei secvențe video (inclusiv tratarea erorii de compatibilitate)

– rularea unui fișier de sunet:

– definirea unui articol ca element afișat

Avantajul HTML 5 privind integrarea facilă cu o serie de alte tehnologii și limbaje de programare Web rulând pe partea de client, poate însă constitui un handicap privind compatibilitatea cu multitudinea de browsere existente. Astfel, utilizarea intensivă a limbajului JavaScript, în strânsă corelare cu noile etichete HTML 5 – cu toate problemele de compatibilitate funcție de tipul de browser – constituie un argument relevant în acest sens. Viitorul rămâne să decidă câștigătorul în această confruntare.

2.2 PREZENTAREA ELEMENTELOR CSS

Cascading Style Sheets (CSS) este practic un pseudo-limbaj de formatare, utilizat pentru a descrie modul de prezentare a documentelor scrise într-un limbaj bazat pe marcaje (HTML, XML etc.). Fișierele CSS (foi de stil în cascadă) permit separarea conținutului HTML propriu-zis al unui document, de stilul de afișare/formatare în pagină al acestuia. Codul HTML se utilizează, de obicei, doar pentru aranjarea conținutului în pagină, iar detaliile care țin de afișare (culori, fonturi, fundaluri, margini etc.) se realizează cu ajutorul CSS-urilor, acestea aplicându-se suplimentar peste codului HTML, în cadrul unui site Web. Cu alte cuvinte, CSS-urile realizează separarea prezentării paginii de structura sa efectivă.

Aplicarea foilor de stil în cascadă asupra codului HTML se poate face în mai multe moduri, putându-se vorbi de:

stiluri interne;

stiluri externe;

stiluri în linie;

clase CSS.

Stiluri interne

În cazul utilizării stilurilor interne, codul CSS se plasează în interiorul fiecărei pagini HTML pe care se dorește să se aplice stilurile respective, între tag-urile <head> </head>, după cum se poate vedea în continuare:

<head>

<title>Exemplu utilizare stiluri interne</title>

<style type="text/css">Aici se definesc stilurile CSS</style>

</head>

Utilizând aceasta metodă de aplicare a CSS-urilor asupra codului HTML, dacă se dorește o schimbare a stilului de afișare (mărimea fontului, culoare, etc) modificarea va trebui realizată în toate paginile care conțin acel stil. Ținând cont de aceste aspect, această metoda este indicat a fi folosită doar în situația în care se dorește stilizarea unui număr mic de pagini, fiind destul de neproductivă o realizare a acestor modificări pe zeci sau chiar sute de pagini ale unui site WEB.

Stiluri externe

Un fișier CSS extern poate fi scris cu orice editor simplu de text (Notepad, Wordpad, etc) sau cu editoare specializate (gen Dreamweaver). Fișierul CSS nu conține cod HTML, ci doar cod CSS și trebuie salvat cu extensia .css. Referirea fișierului extern CSS în paginile HTML se face prin plasarea unui tag link (legatură), în secțiunea <head> </head> a fiecărei pagini în cadrul căreia se dorește aplicarea stilul respectiv, având forma următoare:

<link rel="stylesheet" type="text/css" href="Calea catre fisierul.css" />

Această metodă de utilizare a unor fișiere de stil externe, este preferată în momentul în care un site WEB conține un număr mare de pagini utilizând aceleași reguli de stil, motivul fiind evident: atunci când se dorește modificare aspectului întregului site, este suficientă doar o modificare într-o singură locație, și anume fișierului CSS (efectul resimțindu-se asupra tuturor paginilor din site care folosesc foaia de stil respectivă). Astfel, printr-o singură operație, se poate schimba rapid aspectul întregului site, indiferent de dimensiunea lui (număr de pagini).

Stiluri în linie

Stilurile în linie se definesc chiar în codul etichetei HTML aferente elementului care se dorește a fi stilizat, după cum se poate vedea în exemplul următor:

<body>

<p style="color: #00ddff; font-size: 20;">Titlu</p>

<h2 style="font-size: 16;font-weight: bold; color: #ff3300;">Exemplu

utilizare stiluri in linie!!! </h2>

</body>

Stilurile în linie sunt mai puțin utilizate, deoarece ele nu permit schimbări rapide de stil pe mai multe fișiere în același timp, modificările trebuind realizate pe fiecare element în parte, și în fiecare pagină în parte. În situația în care, se folosesc două sau chiar trei metode de aplicare a CSS-urilor asupra codului HTML în același timp, se pune întrebarea: care este ordinea/prioritatea folosirii lor pentru o interpretare corectă de către browser? Răspunsul este: metodele se vor executa în cascadă, în ordinea următoare: prima oară -stilurile în linie, urmate apoi de stilurile interne, iar în final – stilurile externe, aceasta fiind și ordinea lor de prioritizare. Evident, un element deja stilizat, spre exemplu, cu un stil linie, nu este restilizat de o regulă de stil existentă într-un fișier CSS extern, acționând imediat ulterior

conform regulii de prioritizare anterior enunțate.

Clase CSS

Clasele CSS se utilizează pentru stilizarea în mod diferențiat a unor mulțimi de tag-uri HTML (distribuite în una sau mai multe pagini WEB). Acest mod de lucru este similar cu utilizarea stilurilor în linie, avantajul major fiind acela că atunci când se dorește efectuarea unei modificări de stil pe mai multe elemente/pagini, aceasta nu trebuie efectuată individual la nivelul fiecărui element. Astfel, este suficientă o modificare în cadrul clasei CSS care definește stilurile respective, efectul acesteia răsfrângându-se asupra tuturor elementelor pe care acționează clasa respectivă. Definirea unei clase CSS începe cu semnul punct (.), după care urmează numele clasei. Se recomandă folosirea unor denumiri sugestive pentru numele clasei, care să indice ce anume face stilul respectiv. O clasă CSS poate fi folosită în cadrul unui fișier HTML ori de câte ori este nevoie. În acest sens se poate da un exemplu de clasă care stabilește dimensiunea și culoarea unui text, după cum urmează:

.text20albastru

{

font-size: 20px;

color: 00ddff;

}

Pornind de la exemplificarea din la paragraful ―Stiluri în linie, se prezintă modul de definire și utilizare a unor clase CSS într-un document HTML, clasele fiind stocată într-un fișier de stil extern:

Fișierul HTML utilizând stiluri externe bazate pe clase:

<head>

<title> Exemplu de utilizare a stilurilor in linie!!! </title>

<link href="claseCSS.css" rel="stylesheet" type="text/css">

</head>

<body>

<p class="text20albastru">Titlu</p>

<h2 class="text16rosu">Exemplu utilizare stiluri in linie!!! </h2>

</body>

Fișierul CSS (claseCSS.css) în care sunt definite cele două clase (ambele stilizând texte, dar în mod diferit):

.text20albastru

{

font-size: 20px;

color: 00ddff;

}

.text16rosu

{

font-size: 16px;

font-weight: bold;

color: ff3300;

}

Stilizarea obținută în cadrul fișierului HTML anterior prezentat este evident identică cu cea obținută prin utilizarea stilurilor în linie. Ca o concluzie, în contextul dezvoltării unor aplicații Web tot mai complexe, conținând un număr tot mai mare de pagini, și implicit de fișiere script, stilurile CSS constituie la ora actuală strategia consacrată, de maximă eficiență, pentru formatarea și designul primar al acestora.

Meniuri create cu CSS

Una dintre aplicabilitățile cele mai uzuale ale CSS-urilor constă în crearea de meniuri necesare navigării într-o aplicație, atât foarte simple, cât și cu o complexitate deosebită. Scheletul HTML (ca fundament al unui meniu) pe care sunt aplicate stilurile CSS, consistă în structuri de tip listă (folosindu-se etichete pentru crearea unor liste neordonate <ul>, împreuna cu elementele lor constituente <li>), încapsulate eventual într-un DIV, respectiv hyperlink-urile aferente (ancore <a>). Din păcate dependența de browser se face resimțita și în cazul utilizării de stiluri CSS, astfel încât (mai ales pentru meniuri mai complexe), este foarte posibil ca un meniu care funcționează pe o familie de browsere, să nu fie complet funcțional pe o alta. Într-un astfel de caz, soluția de rezolvare constă în apelarea suplimentară a unor scripturi JavaScript.

Exemplul următor, utilizând doar CSS (fără elemente JavaScript), implementează un meniu simplu (fără submeniuri), fiind funcțional atât pe Mozilla, cât și pe Internet Explorer. Pentru crearea meniului s-a utilizat un fișier extern CSS, în care sunt definite mai multe stiluri.

Fișierul HTML (aferent unui meniu cu trei opțiuni) are următorul cod:

<link href="meniu-html.css" rel="stylesheet" type="text/css">

<div id="nav-menu">

<ul>

<li><a href="#">Optiune1</a></li>

<li><a href="#">Optiune 2</a></li>

<li><a href="#">Optiune 3</a></li>

</ul>

</div>

Fișierul implementând stilurile externe CSS (meniu-html.css) conține următoarele elemente de stilizare:

#nav-menu ul

{

padding: 0;

margin: 0;

}

#nav-menu li

{

float: left;

margin: 0 0.4;

background:#B3B3B3;

}

#nav-menu li a

{

background: url(background.jpg) #fff bottom left repeat-x;

height: 2em;

line-height: 2em;

float: left;

width: 9em;

display: block;

border: 0.1em solid #dcdce9;

color: #FFFFFF;

text-decoration: none;

text-align: center;

}

În cadrul fișierului CSS se poate remarca referirea #nav-menu specificând id-ul elementului DIV (înglobând întreaga construcție a meniului). Cele trei stiluri #navmenuul, #nav-menu li, #nav-menu li a, se referă la formatarea listelor (ul) având ca părinte DIV-ul (#nav-menu), a elementelor listelor (li), respectiv a conținutului ancorelor (a) , având ca părinte elemente ale listei (li), care la rândul lor au ca părinte DIV-ul (#nav-menu). Deși rulând codul anterior pe Mozilla, unele stiluri ar putea părea inutile, o simplă rulare pe Internet Explorer este relevantă pentru a dovedi necesitatea lor. Un exemplu de meniu mai complex, având și sub-meniuri (drop-down menu), este prezentat în cele ce urmează. Întregul cod, atât lista HTML, cât și stilurile CSS (ca stiluri interne), sunt integrate în același fișier HTML.

<ul id="menu">

<li><a href="#">Unu</a></li>

<li><a href="#">Doi</a>

<ul>

<li><a href="#">Doi-1</a></li>

<li><a href="#">Doi-2</a></li>

<li><a href="#">Doi-3</a></li>

</ul>

</li>

<li><a href="#">Trei</a>

<ul>

<li><a href="#">Trei-1</a></li>

<li><a href="#">Trei-2</a></li>

</ul>

</li>

</ul>

2.3 PREZENTAREA LIMBAJULUI PHP

Concepte

Unul dintre cele mai utilizate limbaje de programare folosit la ora actuală pentru dezvoltarea aplicațiilor Web este PHP-ul (semnificația acronimului PHP fiind – PHP: Hypertext Preprocessor). PHP-ul este un limbaj de scripting derivat din familia C, rulând multiplatformă (atât pe paltformele Windows, cât și Unix-Linux), permițând dezvoltarea rapidă de scripturi server-side de către orice programator familiarizat cu binecunoscutul și popularul limbaj C.

Ca software open-source și având o robustețe confirmată în cei aproape 20 de ani de utilizare, PHP-ul prezintă un cert avantaj în puternica competiție pe care o are cu alte limbaje și tehnologii de programare Web server-side, cum ar fi ASP, ASP.Net, JavaServer Pages (JSP) etc. Evident, fiind un limbaj rulând pe partea de server (de aceea se face o comparație a acestuia doar cu acest tip de limbaje de programare Web), scripturile PHP sunt rulate pe un server Web (folosind motorul interpretor PHP), iar utilizatorul (clientul browser) nu poate vedea codul sursă PHP al programului, ci doar codul paginii HTML returnată spre browser-ul client. Altfel spus, motorul limbajului interpretează codul sursă program PHP, generând pe baza acestuia cod HTML (integrat cu datele / informațiile utile returnate/generate), pasat apoi mai departe de către serverul Web spre browser-ul apelant, care știe să interpreteze/afișeze corespunzător codul HTML. Un alt mare avantaj al PHP-ului constă în faptul că suportă o mare varietate de tipuri de baze de date, cum ar fi MySQL, Oracle, PostgreSQL, IBM DB2, InterBase, Sysbase, Microsoft SQL Server (suportul pentru MySQL fiind încorporat nativ în interpretorul PHP).

Astfel, se pot crea foarte ușor aplicații Web pentru accesarea bazelor de date, PHP-ul oferind fie suport nativ, fie un suport concretizat prin utilizarea unor biblioteci .dll suplimentare externe (programatorul trebuind să utilizeze selectiv biblioteci specifice tipului respectiv de bază de date). Alt avantaj este faptul că suportă o serie de protocoale de rețea, printre care SMTP, NNTP, POP3 și HTTP.

Limbajul de scripting PHP a fost implementat în 1994 de Rasmus Lerdorf, la început fiind vorba de un proiect personal care includea câteva macro-uri și un modul care permitea interpretarea lor, menite să urmărească "activitatea" paginii sale personale. În 1995 este disponibil sub numele Personal Home Page. Începând cu versiunea 3, din 1997, a început să fie dezvoltat de o echipă de programatori, iar începând cu versiunea 4 dispune de engine-ul de scripting al firmei Zend Techologies. Există multe clasamente la ora actuală privind popularitatea limbajelor de programare, fiecare având diverse criterii luate în calcul, iar o simplă căutare pe Internet poate găsi o multitudine de asemenea surse vizând aceste clasamente. Din

acest motiv, fără a cita explicit o anumită sursă, se poate afirma că PHP este probabil cel mai folosit limbaj de programare Web pe parte de server, surclasându-și momentan toți concurenții prin preț, robustețe și longevitate, simplitate și viteză, posibilitate de integrare cu alte tehnologii (inclusiv baze de date), securitate, portabilitate, instalare facilă ș.a.

Observație: Limbaje (sau pseudo-limbaje) uzual folosite în programarea WEB: HTML-CSS, PHP, ASP.NET, JavaServer Pages, JavaScript, Perl etc. Pe partea de client rulează: HTML, JavaScript. Pe partea de server rulează: PHP, ASP.NET, JavaServer Pages, Perl. De asemenea, CSS poate fi considerat ca un pseudo-limbaj de formatare, utilizat pentru a descrie modul de prezentare / afișare a documentelor descrise printr-un limbaj bazat pe marcaje (HTML, etc.).

Instalare

Alt avantaj major al PHP îl constituie instalarea extrem de facilă, în contextul unei conexiuni atât cu serverul de Web Apache, cât și cu serverul de baze de date MySQL. Astfel, cel mai simplu mod de a opera cu PHP-ul, în tandem cu MySQL și Apache, este de a folosi pachetul WAMP, integrând perfect această tripletă PHP+MySQL+Apache și disponibil la adresa www.wampserver.com/en/. După simpla rulare a kit-ului de instalare WAMP, totul este deja pregătit pentru a scrie și rula scripturi PHP (inclusiv cu apeluri la serverul de baze de date MySQL), fără a mai fi necesară nici o altă setare suplimentară (în fișierele de configurare).

Observație: De remarcat faptul că, la un moment dat, pe un calculator poate rula doar un server Web, astfel încât, dacă un alt server este deja instalat și pornit, este necesară o oprire prealabilă a acestuia. Pachetul WAMP conține și aplicațiile PHPMyAdmin și SQLiteManager, folosibile pentru gestionarea cu ușurință a bazelor de date MySQL. WAMP este pachetul destinat operării sub Windows.

În mod similar se poate folosi LAMP pentru operarea sub Linux. Cu aceleași avantaje, se poate folosi și pachetul XAMP (Xml + Apache + Mysql + Php), oferind facilități similare. În cazul în care se utilizează componente disparate (interpretor PHP, server WEB, server de baze de date SQL), iar pe computer nu este instalat un server de WEB, este inițial necesară instalarea unuia. Versiunile mai vechi PHP (până la 3) erau disponibile doar ca pachet separat, integrarea lor cu un server de Web, respectiv server MySQL făcându-se manual, printr-o serie de setări în diverse fișiere de configurare (în principal fișierul php.ini), respectiv o setare corespunzătoare a serverului de Web (în special în cazul IIS).

De asemenea, realizarea unor anumite aplicații care necesită alte resurse conexe pachetului de bază PHP (biblioteci sau extensii), implică o configurare a PHPului prin diverse setări corespunzătoare în fișierul php.ini. Spre exemplu, pentru accesarea bazelor de date de tip Oracle este necesar ca extensie fișierul php_oci8.dll, iar pentru InterBase – fișierul php_interbase.dll (aceste biblioteci nefiind preinstalate implicit din motive de evitare a supraîncărcării serverul Web, fiind vorba de fișiere .dll care rămân rezidente în memorie). Operația de instalare a acestor biblioteci este simplă. Pentru cazul anterior menționat, spre exemplu, este necesară doar identificarea bibliotecilor extensie necesare, urmată de o simplă necomentare (eliminarea caracterului de comentariu ;), în fișierul de configurare php.ini, a liniilor pe care apar referite aceste fișiere din secțiunea Windows Extensions:

(în cazul de față php_interbase.dll sau php_oci8.dll) ;Windows Extensions; Note that ODBC support is built in, so no dll is needed for it.

extension=php_interbase.dll

extension=php_oci8.dll

Observație: Conținutul fișierului php.ini (și implicit starea variabilelor de configurare ale PHP) poate fi vizualizat printr-un apel al funcției PHP phpinfo( ). După o operație de reconfigurare (modificare a fișierului php.ini) este necesară o restartare a serverului Apache (sau a oricărui server Web folosit) pentru încărcarea și a acestor noi biblioteci. Toată configurarea manuală anterior descrisă poate fi făcută și utilizând opțiunile meniul grafic pus la dispoziție de WAMP după instalare. O serie de alte configurări necesare a fi realizate în fișierul de configurare php.ini vor fi precizate pe paragrafele următoare, funcție de contextul folosirii altor biblioteci extensie, respectiv funcție de modul de setare al interpretorului PHP (spre exemplu, pentru realizarea unor configurări de securizare eficiente prin setarea corespumzătoare a unor variabile speciale care, în cele mai multe cazuri, sunt realizate adecvat, implicit la instalare).

Codul PHP fiind interpretat pe partea de server Web (Apache, IIS, etc), nu prezintă nici o dependență față de browser-ul client (Internet Explorer, Mozzila, Netscape, FireFox, Opera, Chrome, etc.). Verificarea instalării cu succes a pachetului WAMP (și a startării serverului Web) se poate face printr-un simplu apel la adresa: http://localhost/. Locația de plasare pe serverul Apache (instalat prin intermediul pachetului WAMP) a surselor cod PHP este C:\wamp\www, iar rularea unui fișier script.php, plasat aici, se face printr-un apel de forma http://localhost/script.php (evident din browser-ul Web).

Comenzi PHP

Sintaxă și elemente de bază

Sintaxa comenzilor elementare PHP este extrem de asemănătoare cu a altor limbaje structurate, precum C, JavaScript, Perl (mai precis cu a comenzilor oricărui limbaj derivat din familia C, împrumutând însă câte ceva și de la limbajul Perl, în special pe partea de operare cu string-uri de date). Se vorbește despre comenzi elementare ca fiind acele comenzi care constituie nucleul de baza al oricărui limbaj de programare, dificultatea majora nefiind operarea cu acestea (în număr relativ limitat), ci mai degrabă constând în cunoaștere multitudinii de biblioteci extensie, a funcțiilor oferite de acestea pentru dezvoltarea diverselor tipuri de aplicații și funcționalități.

Deși PHP dispune și de capabilități specifice programării orientate pe obiecte (în special pentru versiunile mai noi, așa cum se va vedea într-un paragraf următor al prezentului capitol), exemplele imediat următoare consideră cazul unei abordări structurate (utilizarea lui ca limbaj structurat fiind de altfel cea consacrată). Un script PHP constă într-o serie de comenzi, executate secvențial, una câte una, de către interpretorul PHP și al căror rezultat (date+cod HTML) este pasat spre un server Web. O eventuală eroare apărută este semnalată de interpretor și afișată de browser (chiar la apelul scriptului), fără blocarea execuției comenzilor următoare. Fiecare comandă se încheie cu caracterul punct-și-virgulă (;). Ca aplicație introductivă, se prezintă codul celui mai simplu program PHP, echivalentul clasicul “Hello, World” din C (integrând opțional și cod HTML):

<html>

<body>

<?php echo “Hello, World !!!”; ?>

</body>

</html>

Se observă prezența unui tag pereche special, <?php … ?>, care încadrează sau delimitează codul PHP. Funcția echo asigură tipărirea pe ecran a șirului specificat ca parametru. PHP permite utilizarea și a altor sintaxe pentru definirea unei zone de cod sau chiar sintaxe diferite pentru referirea parametrului string al funcției de afișare echo:

<?php Echo ("acesta este un simplu test 1\n"); ?>

<?php echo ‗acesta este un simplu test 2<br>‗;?>

<script language="php">

echo ("Un alt exemplu de delimitare cod PHP");

echo "Inca un exemplu de de afisare a unui mesaj";

</script>

Totuși, cea mai răspândită sintaxă (folosită și în lucrarea de față) este cea utilizând perechea de etichete <?php … ?>, fișierul sursa având extensia .PHP (extensie implicit recunoscută de serverul Apache – instalat integrat cu WAMP- care va pasa automat un fișier script cu aceasta extensie spre interpretorul PHP).

Orice linie de comandă, după cum s-a mai menționat, folosește ca terminator de linie caracterul „ ; „ , la fel ca în C sau Java. Comentariile, de asemenea, împrumută sintaxa C, adică // pentru o linie individuală, respectiv /* …*/ pentru o secvență de cod înglobând mai multe linii.

Se consideră încă un exemplu pentru a evidenția câteva din caracteristicile limbajului (utilizând de data aceasta și funcția echivalentă print în loc de echo, cu același efect de afișare în browser a unei informații /cod HTML):

<html>

<head>

<title>Data curenta</title>

</head>

<body>

<b>Data curenta este: </b>

<?php

// se va afisa data calendaristica

echo "<p><b>";

print( date("d F Y, l. ") );

?>

</b> </body>

</html>

Deși secvența anterioară începe cu cod HTML și conține cod HTML în mare măsură, codul PHP constând practic în doar două linii, fișierul sursă va avea obligatoriu extensia PHP. Liniile dintre etichetele delimitatoare <?php, respectiv ?> reprezintă codul PHP. Serverului WEB detectează extensia fișierului, apoi trimite și cere motorului PHP instalat pe același localhost să interpreteze codul dintre cei doi delimitatori. Interpretorul PHP execută funcția date prin care citește data calendaristică de pe server (localhost) si, integrând-o ca pe un simplu string în codul HTML, trimite rezultatul astfel construit (date+cod HTML) spre browser-ul apelant.

Browser-ului i se prezintă un cod HTML ―curat, integrând sub forma unei informații de tip șir de caractere (string) date curentă (cod HTML vizibil cu opțiunea view source):

<html>

<head>

<title>Data curenta</title>

</head>

<body>

<b>Data curenta este: </b>

<p><b>02 July 2012, Monday. </b>

</body>

</html>

De remarcat că orice urmă de cod PHP dispare, singura indicație asupra existentei acestuia fiind extensia fișierului script apelat. În locul acestuia, secvența vizibilă este un simplu cod HTML standard. Exemplul scoate în evidență câteva avantaje majore ale script-urilor rulate pe partea de server:

a) Eliminarea problemelor de incompatibilitate vizând tipul de browser (specifice limbajelor client-side). Scriptul este rulat pe partea de server unde este instalat și interpretorul PHP, deci nu pot apărea probleme legate de tipul de browser folosit pe partea de client.

b) Acces la resursele de pe partea de server. Dacă aceeași aplicație ar fi fost scrisă în JavaScript, data respectivă ar fi fost data corespunzătoare calculatorului client (pe care rulează browser-ul). Pentru o informație precisă și unitară privind data sau momentul de timp al apelului, informația preluată de pe server este singura demnă de luat în considerare. Un alt exemplu în acest sens, vizează o aplicație Web cu baze de date, unde este foarte clar că baza de date (comună tuturor apelanților aplicației Web) trebuie plasată pe partea de server (chiar dacă, fizic, acest server SQL are alt remote host decât cel al serverului Web pe care rulează codul PHP).

c) Reducerea încărcării clientului. Rularea unui script pe partea de client (cazul JavaScript) poate fi destul de lentă, depinzând direct de performanțele calculatorului care găzduiește browser-ul client. În cazul script-urilor rulate pe partea de server, performanțele calculatorului client nu mai prezintă o importanță decisivă privind viteza de accesare a paginii Web.

Tipuri de date

Principale tipurile de date suportate de PHP sunt: integer, string, float, boolean, array, object, null. Spre deosebire de alte limbaje de programare (chiar cele din fanilia C), nu este necesară o declarare prealabilă a unei variabile (și evident o definire a tipului acesteia). Numele variabilelor sunt precedate de caracterul "$", făcându-se diferență între literele mari și mici folosite în cadrul numelor de variabile.

Exemplul următor este relevant în acest sens :

<?php

$var = "Ion";

$Var = "Dan";

echo "$var, $Var"; //se afișează: Ion, Dan

echo $var, $Var; //se afișează: IonDan

echo ‗$var, $Var‘; //se afișează: $var,$Var

?>;

Se poate remarca și faptul că, funcție de tipul de ghilimele simple, duble sau lipsa acestor, comanda echo interpretează în mod diferit conținutul variabilelor de afișat (ghilimele simple forțând o interpretare ad-literam -ca simplu string- a conținutului, chiar dacă caracterul $ indică prezența unor variabile care ar trebui interpretate ca și conținut și nu ca și nume ).

Observație: Cea mai amplă și completă sursă de documentare privind limbajul PHP o constituie manualul on-line al acestuia, accesibil la adresa http://php.net/manual/en/. Evident, descrierea sintaxei comenzilor, funcțiilor și a unor structuri de programare tratate în capitolul de față folosește ca sursă primară de documentare acest manual, venind însă în completarea lui printr-o manieră sintetică de prezentare selectivă și exemplificare a unora dintre cele mai importante și uzuale comenzi/structuri. De asemenea, prezentarea făcută are un puternic caracter aplicativ, exemplele fiind noutatea față de alte surse de documentare.

Structuri condiționale și de ciclare

Ca orice alt limbaj de programare, PHP-ul dispune de o serie de facilități pentru controlul fluxului de desfășurare al unui script. Astfel, limbajul beneficiază de aportul unor instrucțiuni prin care este permisă o deviere de la ordinea firească de derulare a fluxului de comenzi ale scriptului/programului (numite instrucțiuni/structuri de salt condiționat sau de ramificare, respectiv de ciclare). Câteva astfel de structuri de control ale fluxului unui program sunt detaliate în continuare la nivel de sintaxă, fiind însoțite fiecare de exemple de utilizare: structura if-else, structura condițională switch, structurile while și do-while, bucla for, respectiv comanda de ciclare foreach. Una din cele mai folosite structuri de control condiționale este if-else, în PHP având următoarea sintaxă simplificată:

if ( conditie )

{

// secvența care se execută dacă condiția este adevărată.

}

else //ramificație opțională

{

// (Opțional) secvența care se execută dacă condiția este falsă.

}

Structura if-else permite o bifurcare condiționată a programului. Iată un exemplu (în care trebuie remarcat și operatorul de comparare egalitate ==):

if ( $name == "Ion" ) {

echo("Mesaj de afisat pentru: $name");

} else {

echo("Persoana neidentificat");

}

Exemplificarea anterioară utilizează o sintaxă redusă a structurii condiționale if-else (putând să existe, de altfel, și o singură ramură condițională, evident if-ul). De subliniat faptul ca parantezele acolade { } sunt obligatorii, chiar dacă linia else delimitează clar sfârșitul secvenței executate la îndeplinirea condiției. O formă sintactică extinsă permite practic o ramificare nelimitată. Spre exemplificare, o ramificare pe patru ramuri poate avea următorul cod:

if (conditie 1) {

…cod PHP

} elseif (conditie2) {

…cod PHP

} elseif conditie3) {

…cod PHP

}else (conditie 4) {

…cod PHP

}

Fiecare ramură elseif este testată doar dacă condițiile impuse pe ramurile anterioare nu sunt îndeplinite. Îndeplinirea unei anumite condiții și execuția unei anumite ramuri elseif (sau a ultimei ramuri else, ca ramură finală opțională) conduce automat la ieșirea din structura condițională. Altfel spus, verificarea condițiilor se face secvențial, iar îndeplinirea uneia conduce automat la ieșirea din structură, verificarea tuturor ramurilor următoare fiind abandonată. O alternativă des folosită pentru o multi-ramificație bazată pe structura ifelseif- else o constituie structura condițională switch.

Pentru o exemplificare concretă comparativă switch / if-elseif se consideră următoarele secvențe:

if ($var == 0) {

echo "mesaj 0";

} elseif ($var == "ceva") {

echo "ceva";

} elseif ($var == 2) {

echo "mesaj 2";

}

switch ($var) {

case 0:

echo "mesaj 0";

break;

case "ceva":

echo "ceva";

break;

case 2:

echo "mesaj 2";

break;

}

Comanda break asigură ieșirea automată din structură, celelalte ramuri ne mai testându-se. Lipsa break-ului ar conduce la o verificare și a condițiilor de pe celelalte ramuri (care teoretic nu ar mai trebui îndeplinite, și deci nu și-ar mai avea sens testarea lor). Deși nerecomandată, comanda de salt necondiționat goto, este disponibilă și ea în PHP (doar începând cu versiune PHP 5.3 !) Trecând la structurile de ciclare, poate cea mai des utilizată este bucla while cu sintaxa clasică:

while (conditie) {

// secvența de comenzi executată

// repetat, cât timp condiția este adevărată

}

Această buclă permite executarea repetată a unei secvențe de comenzi atât timp cât este îndeplinită o condiție (verificată aprioric execuției corpului de comenzi). Oarecum echivalentă cu while este structura do-while, deosebirea majoră constând în faptul că testarea condiției se face ulterior execuție corpului de instrucțiuni (și nu aprioric ca în cazul while):

do {

// secvența de comenzi executată repetat,

// (prima execuție fiind implicită) cât timp condiția este adevărată

}

while (conditie);

Nu putea lipsi din cadrul structurilor de ciclare clasica buclă for cu sintaxa standard împrumutată de la limbajul C:

for (initializare_contor; conditie; actualizare_contor) {

// secvența de comenzi care se execută

// atât timp cât condiția este adevărată

}

Și în final, foarte des utilizată în contextul operării cu structuri de date de tip array, comanda foreach permite crearea unei bucle pentru accesarea secvențială a elementelor unui șir – array. Dacă o structură de date array este convertită într-o structură de tip object, foreach permite operarea și cu noua structură de date de tip object. Sintaxa generală foreach vizând tipul array este:

foreach (nume_array as $element)

{

// secvența de comenzi executată repetat, procesând variabila $element

}

Structurile repetitive implementate cu foreach sunt foarte des utilizate în contextul operării cu baze de date. Motivul îl constituie faptul că, de regulă, liniile unei tabele sunt disponibile succesiv sub forma unui array, iar accesul la fiecare element al acestuia se poate realiza cu o buclă foreach. Atenție însă, la fiecare nou ciclu foreach, valoarea anterior extrasă este ștearsă (suprascrisă). O alternativă la acest impediment o constituie comanda list, permițând extragerea într-o listă de variabile predefinite a elementelor unui șir (extragerea tuturor elementelor făcânduse simultan, nu succesiv).

Dacă numărul de variabile nu coincide cu numărul de elemente ale șirului array (indiferent că este mai mare sau mai mic), extragerea se va face doar pentru elementele disponibile, fără semnalarea unui mesaj de avertisment sau de eroare. Dezavantajul față de foreach constă în faptul că, dacă se dorește extragerea într-un set de variabile a întregului conținut al șirului, trebuie cunoscut aprioric numărul de elemente ale acestuia.

2.4 PREZENTAREA LIMBAJULUI MySQL

Pe lângă setul standard de comenzi aferente limbajului PHP, acesta dispune de o serie de funcții și variabile predefinite care ușurează munca programatorului, unele dintre ele fiind incluse implicit (built-in) în interpretor (spre exemplu, suportul pentru MySQL, FTP, XML), altele fiind disponibile prin utilizarea unor fișiere externe ca extensii (biblioteci .dll). Aceste fișiere extensie de tip .dll (cu numele generic php_*.dll) permit limbajului PHP să opereze cu o mare diversitate de tehnologii conexe, inclusiv cu baze de date (în acest ultim caz, ele înglobând funcțiile necesare accesării și manipulării unor baze de date de diverse tipuri). MySQL este unul dintre cele mai folosite sisteme de gestiune a bazelor de date client-server, fiind cel mai des utilizat în combinație cu scripturi PHP. Operarea cu baze de date MySQL nu necesită utilizarea unei biblioteci suplimentare (.dll), suportul pentru MySQL fiind inclus funcțional în motorul interpretorului PHP.

După instalarea pachetului WAMP, un client consolă MySQL este disponibil chiar din meniul WAMP, sub denumirea MySQL Console. User-ul cu rol de administrator al serverului MySQL are numele root și nu are o parolă implicit setată. Este indicat ca, după prima logare, să se seteze o parolă pentru acest important user.

Setarea unei parole pentu user-ul root se poate face cu o comandă de genul:

mysql> SET PASSWORD FOR ‗root‘@‘localhost‘ = PASSWORD(‗parola‘);

mysql> SET PASSWORD FOR ‗root‘@‘%‘ = PASSWORD(‗parola‘);

De sunt necesare două comenzi? Practic sunt doi useri administrator, cu același nume root, unul fiind dedicat conectării exclusiv de pe localhost, iar celălalt (cu același nume) pentru realizarea unor conexiuni din exterior (la distanță sau remote). Cei doi useri pot fi vizualizați cu comanda (parolele fiind criptate): mysql> select host, user, password from mysql.user;

Tot dupa instalarea serverului de baze de date, două baze sunt implicit create, având numele mysql (conținând informațiile pentru administrarea userilor, drepturilor acestora, parolelor de acces, etc.), respectiv test (bază de lucru pentru root).

Vizualizarea numelor bazelor de date existente pe server, respectiv deschiderea uneia sau alteia și afișarea numelor tabelelor din baza curentă, se poate face cu o secvență de comenzi de forma următoare:

mysql> SHOW DATABASE;

mysql> USE test;

mysql> SHOW TABLES;

Pentru proiectarea și implementarea unei noi aplicații, se recomandă crearea unei noi baze de date, respectiv crearea unui nou user și atribuirea de

drepturi acestuia doar pe această nouă bază de date. Spre exemplu:

mysql> CREATE DATABASE persoane;

mysql> CREATE USER ‗ion‘@‘localhost‘ IDENTIFIED BY ‗parola‘;

mysql> GRANT ALL ON persoane.* TO ‗ion‘@‘localhost‘;

Se presupune serverul MySQL plasat pe același host cu interpretorul PHP, cu serverul Apache și deci, implicit, cu scripturile PHP care integrează rolul de user). Astfel, un singur user MySQL permițând doar o conectare de pe localhost este suficient pentru operare (oferind în plus și o securitate suplimentară, doar un apel conexiune dintr-un script PHP fiind permis, respectiv orice apel extern, de la distanță (remote), fiind respins). Folosirea noului user implică deschiderea unei noi console client, aceasta putând fi startată printr-o comandă de rulare directă a aplicației client mysql.exe cu parametri (-h urmat de numele/adrea IP a host-ului, -u urmat de numele de user, –p precizând că este necesară și se va cere o parolă):

C:\wamp\mysql\bin\mysql.exe -h localhost -u ion -p

După tastarea parolei adecvate, prompter-ul mysql> va apare confirmând realizarea conexiunii la server și permițând deschiderea bazei dorite:

mysql> USE persoane;

În acest moment se poate trece la crearea tabelelor bazei de date și la o operare standard cu comenzi SQL consacrate (CREATE TABLE, INSERT, UPDATE, DELETE, SELECT, etc.).

Tabela table1, considerată în continuare în majoritatea exemplificărilor care vor urma (aparținând bazei de date persoane), a fost creată folosind comanda:

CREATE TABLE table1(

Nume CHAR(10),

Varsta INTEGER,

localitate CHAR(10));

Observații: Părăsirea consolei MySQL (și implicit închiderea conexiunii user-ului curent cu serverul) se face cu comanda exit. Din motive de comoditate vizând lansarea rapidă a unui ferestre consolă MySQL (permițând implicit conectarea doar ca user administrator), exemplele care urmează folosesc userul root pentru accesul la baza de date persoane.

2.5 PREZENTAREA LIMBAJULUI AJAX

Introducere în AJAX

JavaScript, ca limbaj de programare WEB (rulând pe partea de client), permite o mulțime de acțiuni care fac interfața cu utilizatorul mult mai prietenoasă.nAstfel, se pot implementa validări ale datelor introduse prin formulare, operare cu imagini (vezi exemplele din paragrafele nterioare) meniuri, mesaje gen popup etc.

Fiind un limbaj de programare rulând pe partea de client, JavaScript nu permite însă transferul informației între browser-ul (clientul) Web și serverul Web (fiind interpretat uneori chiar diferit de diversele tipuri de browsere). Dacă se dorește preluarea unor date de la un server de baze de date sau trimiterea unor informații spre un script PHP (rulând partea de server Web), codul HTML, mai precis un formular HTML (FORM) oferă metodele GET și POST pentru comunicarea (transferul) de parametri spre server, realizând astfel un apel parametrizat al unor scripturi. În momentul în care user-ul apăsa un buton de tip Submit, eventualii parametri sunt transferați spre server, așteptându-se un răspuns din partea scriptului apelat, având ca rezultat afișarea unei noi pagini integrând informația returnată. Dacă serverul Web răspunde mai puțin rapid (din diverse motive), utilizatorul are de așteptat un anumit timp până la încărcarea și afișarea completă a noii pagini.

AJAX (acronimul pentru Asynchronous JavaScript And XML, reprezentând practic o grupare de tehnologii, gen JavaScript, XML, CSS, DOM, HTML și DHTML), încercă să remedieze această problemă, lăsând codul JavaScript să comunice direct cu serverul Web, prin utilizarea un obiect special JavaScript numit XMLHttpRequest (sau un ActiveXObject). Cu ajutorul acestui obiect, codul JavaScript poate trimite sau primi informații de la/spre server, fără a fi necesară reîncărcarea completă a paginii Web (printr-un eventual Reload), făcând astfel

posibil un schimb bidirecțional, asincron, de date cu serverul (practic cu scripturi rulând server-side). Astfel, o secvență specifică de cod JavaScript (rulând pe parte de client), poate comunica cu cod rulând pe partea de server Web .

AJAX încearcă totodată să elimine diferențele de funcționalitate și interactivitate existente între o aplicație desktop și o aplicație Web (ultima implicând, în tehnologia clasică, o actualizare permanentă a conținutului întregii pagini). Astfel, o soluție AJAX oferă posibilitatea de a utiliza dinamic controale HTML și de a construi o interfața interacționând cu utilizatorul și oferindu-i facilități specifice aplicațiilor desktop .

AJAX nu este o tehnologie în sine, ci mai mult o colecție de tehnologii grupate în jurul unui nucleu central fundamentat pe JavaScript. Pot fi enumerate următoarele tehnologiile de bază implicate (mai mult sau mai puțin) în construcția unei aplicații AJAX:

HTML – folosit pentru construcția formularelor Web, ca elemente interactive de bază;

JavaScript – elementul central a unei aplicații AJAX, coordonând o comunicație asincronă între interfața client și nucleul aplicație rulând pe partea de server (nucleul AJAX, utilizând obiecte dedicate, fiind implementat în JavaScript);

DHTML (Dynamic HTML) permite o actualizare dinamică a paginii, punând la dispoziție elemente dinamice HTML gen DIV, SPAN lucrând integrat cu HTML;

DOM (Document Object Model) – utilizat (prin intermediul JavaScript) pentru a conlucra atât cu structura HTML (prin evenimente atașate), cât și (dacă este cazul) cu datele XML returnate de server;

XML (eXtensible Markup Language)- utilizat ca format pentru transferul datelor.

Caracteristicile funcționale principale ale AJAX sunt următoarele:

În momentul în care utilizatorul declanșează un eveniment (spre exemplu, o apăsare de buton), o secvență de cod JavaScript și DHTML poate actualiza imediat interfața (sau o zonă a acesteia), lansând o cerere asincronă spre server pentru a trimite / prelua date.

După ce serverul generează un răspuns, se poate folosi cod Javascript (AJAX) și CSS pentru actualizarea interfeței grafice, fără a se face un REFRESH al întregii pagini. În momentul în care se întâmplă acest lucru, pagina utilizator (ecranul) nu clipește, nu dispare sau pierde din viteză, doar o zonă bine precizată a acesteia fiind actualizată (spre exemplu, o zonă DIV).

Caracteristica esențială AJAX constă în capacitatea sa de a comunica asincron cu serverul (utilizând diverse obiecte specializate, gen XMLHttpRequest sau ActiveXObject), fără a necesita un refresh al întregii paginii Web. În esență, AJAX plasează tehnologia JavaScript și obiectul specializat (gen MLHttpRequest) pe un strat de mijloc, ca liant, între componenta client-side (scripturi HTML, CSS, JavaScript) și componenta server-side (scripturi PHP, Perl, ASP etc.).

PHP cu AJAX

Utilizare obiect XMLHttpRequest

Orice aplicație utilizând AJAX implică utilizarea unei secvențe JavaScript relativ standard, referită în continuare ca nucleu AJAX, necesitând instanțiere unui obiect special realizând comunicația asincronă, bidirecționala, cu serverul Web (mai precis, cu scripturi rulând server-side). Funcție de tipul de browser apelant, există mai multe astfel de obiecte. Astfel, clasa XMLHttpRequest este folosită pentru browsere ale familiilor Mozilla, Firefox, Safari, Opera, respectiv clasele bazate pe ActiveXObject – pentru familia Internet Explorer (cu parametri chiar diferiți, funcție de versiunea browser-ului). Pentru o simplă exemplificare a integrării unui nucleu AJAX într-o pagină Web, e consideră o aplicație de apelare asincronă (AJAX) a unui script PHP care permite afișarea automată, la declanșarea unui anumit eveniment, a momentului de timp curent (preluat de pe serverul Web). Din motive de realizare a unei simple comparații între un apel clasic, respectiv un apel AJAX, se va prevedea o afișare a momentului de timp curent, atât la încărcarea paginii printr-un apel clasic (acesta fiind actualizat doar la încărcarea paginii sau la un refresh explicit al acesteia), respectiv o a doua afișare (într-o casetă a unui formular) declanșată de un eveniment, afișarea fiind asincronă și nu necesită un refresh al întregii pagini Web.

Structural, o aplicație AJAX conține un script rulând pe partea de client, integrând cod HTML-JavaScript (inclusiv nucleul AJAX), realizând un apel al unui al doilea script rulând server-side (în cazul de față, serverTime.php), după cum s-a mai precizat. În exemplificarea curentă, din motive de tratare comparativă a celor două tipuri de apeluri (clasic/AJAX), în primul script se prevede, în aceiași pagină, și o afișare inițială, statică, necesitând un apel clasic al unui script PHP (din acest motiv, fișierul referit are extensia PHP, și nu HTML cum ar fi uzual). Structura acestui fișierul apel.php (rulând majoritar -ca și cod- pe partea de client) conține:

funcția JavaScript ajaxFunction, conținând practic nucleul AJAX (integrat în orice aplicație AJAX), generând prin instanțiere un obiect de comunicație asincronă cu serverul, specific fiecărui tip de browser (din clasa XMLHttpRequest,spre exemplu pentru Mozilla, sau diverse versiuni de ActiveX-uri pentru Internet Explorer).

codul aferent comunicației bidirecționale propriu-zise utilizând obiectul anterior instanțiat (numit aici ajaxRequest), realizând apelul asincron al unui script rulând server-side, prin utilizarea unor funcții/metode/proprietăți specifice acestuia:

onreadystatechange – eveniment stocând funcția care procesează răspunsul serverului (ce se întâmplă când răspunsul serverului este gata să fie procesat);

readyState – proprietate stocând starea răspunsului serverului (0- cerere neinițializată, 1-cerere nesetată, 2 -cerere trimisă, 3-cerere în procesare, 4- cerere completă)

responseText – metodă permițând preluarea datelor returnate ca răspuns de către server (în exemplul de față, acestea fiind pasate spre documentul curent conținând formularul MyForm, respectiv spre caseta time, ca și conținut value al acesteia).

open și send – ca metode utilizate pentru trimiterea cererii spre server (apelul, eventual parametrizat al scriptului rulând server-side). Prima metodă are trei parametrii: metoda folosită (GET sau POST), adresa scriptului apelat de pe partea de server, iar ultimul parametru stabilește dacă cererea este asincronă sau nu. A doua metodă efectuează cererea propriu-zisă, pasând și eventualii parametri, dacă este cazul (pentru metoda GET, parametrul acesteia este tot timpul null).

Codul fișierului apel.php, integrând secvența AJAX, este următorul:

<html> <body>

<script language="javascript" type="text/javascript">

//Creare NUCLEU AJAX –asigurare compatibilitate browser

function ajaxFunction(){

var ajaxRequest; // variabila obiect Ajax

try{

// Opera 8.0+, Firefox, Safari

ajaxRequest = new XMLHttpRequest();

} catch (e){

// Internet Explorer

try{

ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e) {

try{

ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e){

alert("Eroare");

return false;

}

}

// Funcție care preia date de la server Web

ajaxRequest.onreadystatechange = function(){

if(ajaxRequest.readyState == 4)

document.myForm.time.value = ajaxRequest.responseText;

}

//Apel și pasare date spre server Web

ajaxRequest.open("GET", "serverTime.php", true);

ajaxRequest.send(null);

}

</script>

<form name='myForm'>

Name: <input type='text' onBlur="ajaxFunction()" name='username' /> <br />

<b>Afisare cu AJAX</b><br>

Time: <input type='text' name='time' />

</form>

<b>Afisare fara AJAX </b><br>

<?php include 'serverTime.php'; ?>

</body>

</html>

Partea de cod clasic HTML-JavaScript, implementează un formular cu două asete INPUT, părăsirea primei casete (evenimentul onblur, echivalentul lui onLeave din alte limbaje) conducând (prin apelul funcției AJAX aferente ajaxFunction) la completarea în cea de-a doua casetă a timpului citit de pe server, prin apelul asincron implicit al scriptului rulat pe partea de server serverTime.php:.

<?php

echo date("H:i:s");

?>

Apelul asincron putea fi declanșat și la un eveniment onClick chiar pe caseta a doua în care se afișează timpul, dar în acest caz aplicația va reacționa doar la un eveniment declanșat strict de mouse (nu și de tastatură):

<input type='text' name='time' onClick="ajaxFunction()" />

Exemplul anterior permite apelul asincron și refresh-ul datelor afișate într-un element de tip caseta INPUT. În unele situații însă, se dorește refresh-ul unei zone bine delimitate de pe ecran, spre exemplu utilizând o etichetă de tip DIV. În acest caz, în partea de cod HTML (eliminându-se caseta INPUT time), după formular se poate prevedea o astfel de zonă DIV (cu un ID bine precizat, prin care aceasta poate fi referită):

<div id="Elem_DIV"><b> <?php include 'serverTime.php'; ?></b><br></div>

De asemenea, codul JavaScript pentru referirea zonei DIV de afișare/refresh implică următoarea modificare aferentă metodei AJAX (responseText) care interceptează și procesează răspunsul serverului:

ajaxRequest.onreadystatechange = function()

{

if(ajaxRequest.readyState == 4)

document.getElementById('Elem_DIV').innerHTML=

ajaxRequest.responseText;

}

Se poate remarca modul specific de referire pentru încărcarea cu date a unui element DIV, comparativ cu un element INPUT:

Eticheta HTML DIV este de regulă cea mai folosită pentru implementarea unei zone limitate de afișare și actualizare asincronă folosind AJAX. Exemplul de față realizează un apel asincron, folosind metoda GET, fără pasare de parametri. Asupra modului de folosire și al metodei POST, respectiv asupra modului de pasare de parametri ai apelului, se va reveni în exemplificările din paragrafele ulterioare.

Grafică dinamică cu AJAX

Una dintre aplicabilitățile cele mai des utilizate ale AJAX-ului este cea de afișare dinamică, într-o zonă cu rol de header al unei pagini Web, a unei informații multimedia destinată reclamei (schimbarea făcându-se automat și aleator). Exemplificarea de față consideră o afișare a unui ceas marcând timpului curent (preluat de pe host-ul serverului Web), respectiv a unor imagini într-o ordine aleatoare, acțiunea desfășurându-se într-o zonă DIV a paginii Web .

Evident că simpla afișare aleatoare a unor imagini (creând un efect de dinamică), se poate realiza și folosit doar cod JavaScript clasic. Avantajul major oferit de AJAX (care impune utilizarea lui într-o astfel de situație) constă în faptul că dinamica generată de acesta nu implică un refresh al întregii pagini Web (cu efecte negative privind viteza de încărcare, clipirea conținutului, momente de întrerupere a operării în pagină în așteptarea reîncărcării etc.), ci doar o reîncărcare a zonei DIV referite (în plus, aceasta făcându-se și asincron, fără generare de sincope în zona utilă de lucru a paginii).

Aplicația considerată pentru exemplificare conține următoarele elemente:

Trei zone de afișare DIV (pentru a demonstra refresh-ul doar pe o zonă a paginii Web). În primul DIV (plasat în celula unui tabel pentru a limita dimensiunile lui) se încărcă periodic (printr-un apel asincron AJAX – la intervale de 1 sec.) timpul citit de pe server, respectiv un set aleator de câte două imagini (situație des întâlnită pentru afișarea dinamică aleatoare a unor reclame într-o zona header a unor site-uri). Al 2-lea și al 3-lea DIV – sunt folosite pentru simple exemplificări ale faptului că restul paginii rămâne static (nu se face refresh), respectiv exemplificări ale modului de design/stilizare pentru un element DIV. Se poate observa că designul și dimensiunile unui DIV se pot seta doar folosind CSS. Un DIV simplu (fără alte setări de atribute făcute prin CSS) ocupă întreaga lățime a paginii (înălțimea fiind dată de dimensiunea conținutului lui sau de modul de spațiere al acestuia).

Codul aferent aplicației este următorul:

<html>

<body>

<table border='1'>

<tr><td>

<div style="color:#0000FF; font-size: 30; background-color:#B3B3B3;"

id='ajaxDiv'>Diviziunea 1</div>

</td>

<td>

<form name='myForm'>

<b>Zona de lucru </b><br>

Name: <input type='text' onBlur="ajaxFunction()" name='username' /> <br />

Time: <input type='text' name='time' />

</form>

</td></tr>

</table>

<b>Afisare fara AJAX </b><br>

<div style="display:inline-block; color:#0000FF; font-size: 30; backgroundcolor:#

B3B303; width: 70%; width: 70%; height: 300px" id='ajaxDiv1'>

<?php include 'serverTime.php'; ?>

</div>

<div style="color:#0000FF; font-size: 30; background-color:#B3B3B3;"

id='ajaxDiv2'>Alt div</div>

</body>

</html>

<script language="javascript" type="text/javascript">

function ajaxFunction()

{

var ajaxRequest;

try{

// Mozilla, Opera 8.0+, Firefox, Safari

ajaxRequest = new XMLHttpRequest();

} catch (e){

// Internet Explorer

try{

ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e) {

try{

ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e){

alert("Your browser broke!");

return false;

}

}

}

// Funcție de recepție

ajaxRequest.onreadystatechange = function()

{

if(ajaxRequest.readyState == 4)

{

var ajaxDisplay = document.getElementById('ajaxDiv');

ajaxDisplay.innerHTML = ajaxRequest.responseText;

setTimeout('ajaxFunction()',10000);

// reamorsare periodica

}

}

ajaxRequest.open("GET", "serverTime.php", true);

ajaxRequest.send(null);

}

//startare prima oară la apel pagină (eveniment-apel pagină)

ajaxFunction();

</script>

Ca și în exemplul precedent, în momentul în care cererea este completă (ajaxRequest.readyState == 4), DIV-ului identificat prin id i se trimite răspunsul cererii asincrone, și totodată se restartează un timer (setTimeout) care va redeclanșa (reamorsa) funcția AJAX după un interval de 10 secunde:

setTimeout('ajaxFunction()',10000);

Apelul explicit în scriptul JavaScript al funcției ajaxFunction() conduce la o prima rulare în momentul încărcării paginii.

Scriptul PHP (serverTime.php) apelat si rulat pe partea de server are codul următor:

<?php

$var1=rand(1,5); //generare numere aleatoare întregi in interval [1,5]

$var2=rand(1,5);

echo date("H:i:s"); //timp server Web

echo "&nbsp";

// este necesara existența a 5 imagini cu numele 1.jpg, 2jpg,….,5.jpg

echo "<img src='".$var1.".jpg'"." height='200' weight='200' >";

//încărcare imagine

echo "&nbsp"; //spațiu între cele două imagini

echo "<img src='".$var2.".jpg'"." height='200' weight='200' >";

?>

Scriptul PHP practic generează numere aleatoare în intervalul [1,5] și răspunde/returnează ora curentă, respectiv câte două imagini selectate aleator dintr-un set predefinit. Rulând aplicația se poate remarca că doar conținutul primului DIV se modifică, fără a afecta restul paginii (practic doar conținutul celulei tabelului în care este plasat primul DIV). În plus, s-a prevăzut un apel manual al funcției AJAX (conducând la o refresh-are imediată a timpul și a imaginilor afișate) la un eveniment onBlur atașat unei casete INPUT (declanșarea făcându-se la părăsirea acestei casete).

Deoarece transferul printr-o metodă GET cu AJAX nu funcționează pe Internet Explorer, utilizarea metodei POST (permițând funcționarea și pe Internet Explorer) implica următoarea modificare de cod a funcției AJAX:

// Functie de receptie

ajaxRequest.onreadystatechange = function()

{

if(ajaxRequest.readyState == 4)

{

var ajaxDisplay = document.getElementById('ajaxDiv');

ajaxDisplay.innerHTML = ajaxRequest.responseText;

setTimeout('ajaxFunction()',1000);

}

}

ajaxRequest.open("POST", "serverTime.php", true);

var params =""; //nu sunt parametri de transmis

http.setRequestHeader("Content-type", "application/x-www-formurlencoded");

http.setRequestHeader("Content-length", params.length);

http.setRequestHeader("Connection", "close");

ajaxRequest.send(params);

}

Observație

Dacă la un apel AJAX cu parametri, folosind metoda GET, codul aferent utilizat

este de forma:

var params = "? "+"par1=" + var1 + "&par2=" + var2;

ajaxRequest.open("GET", "ajax-example.php" + params, true);

ajaxRequest.send(null);

trecerea la metoda POST implică o construcție a un string cu parametri de transmis

de forma (atenție la ‖?‖):

var params = "par1=" + var1 + "&par2=" + var2;

CAPITOLUL III. METODE FOLOSITE

3.1 FRAMEWORK

Framework-uri pentru dezvoltarea aplicațiilor

Framework-urile ofera dezvoltatorilor un cadru general pentru construirea de aplicatii ce respecta un anumit tipar (de exemplu, aplicatii web). Infrastructura defineste o serie de entitati generice si asigura comunicarea de nivel scazut intre acestea (de exemplu, generarea de evenimente intr-un context event-driven). In laboratoarele anterioare, am studiat paradigma MVC, dar intrebuintarea a fost limitata la nivel de componente vizuale. Conceptul se poate extinde pentru a descrie intreaga arhitectura a aplicatiei. In acest mod, se induce conceptul de inversion of control, in sensul ca dezvoltatorul nu mai este preocupat de realizarea unor sarcini cu caracter general (frozen spots), cum este proiectarea unui flux de control in aplicatie, ci se concentreaza pe aspectele specifice situatiei date (hot spots), urmand ca acestea sa fie integrate in fluxul implicit. Paradigma este adesea pusa in legatura cu principiul Hollywood.

De exemplu, intr-o aplicatie de e-commerce, accentul cade pe aspectele de nivel inalt, ca gestionarea produselor si a comenzilor, si nu pe cele de nivel scazut, ca accesul la baza de date. De aici se desprinde principalul avantaj. Un alt avantaj ce rezulta imediat este reutilizabilitatea. Urmarind inlantuirea fireasca a lucrurilor, obtinem o sporire a fiabilitatii, deoarece intrebuintarea repetata a infrastructurii conduce la depistarea eventualelor erori si la imbunatatirea corespunzatoare. Dezavantajul principal provine din limitarea flexibilitatii.

Orice aplicatie dezvoltata utilizand un anumit framework se va supune fluxului generic pe care acesta il defineste. Acest lucru poate conduce la cuplaje complicate chiar in situatii simple.

Framework-ul CODEIGNITER

Codeigniter s-a impus in ultimii ani printre framework-urile PHP celebre si intensiv folosite de catre dezvoltatorii web. CodeIgniter permite dezvoltarea rapida de aplicatii web, ofera solutii la o mare parte dintre problemele intalnite in mod frecvent de programatorii PHP, este un framework suplu, este construit folosind arhitectura MVC si impune folosirea ei in cadrul aplicatiei, este opensource si bine documentat.

Primul lucru pe care il remarca un nou utilizator al CI este usurinta cu care se instaleaza acesta pe server, faptul ca nu este necesar accesul la promptul de comanda al serverului, posibilitatea de lucra cu majoritatea tipurilor de baze de date.

Un aspect extrem de important al CI este organizarea codului. Lucrul cu baza de date este separata de Controller, prezentarea este separata de aplicatie in sine. Acest lucru permite lucrul eficient in echipe de dezvoltatori. Daca o echipa lucreaza la design-ul aplicatiei acest lucru nu afecteaza echipa care se ocupa de functionalitatile necesare si interogarea bazei de date. Pentru acceasi aplicatie se pot realiza mai multe "skin-uri" care se pot schimba intre ele relativ usor. Acest lucru este foarte important pentru ca de foarte multe ori ne-am intalnit cu situatii in care un client dorea modificarea designului si dupa implementarea modificarilor descopeream ca unele functii nu se comporta cum ne asteptam sau, si mai grav, eram nevoiti sa rescriem aproape toata aplicatia pentru ca nu exista o minima organizare a codului.

Un alt deosebit de util al CI este posibilitatea de a extinde bibliotecile de baza, de a scrie clase si biblioteci noi pe care apoi sa le integram usor in structura framework-ului. De asemenea daca dorim sa nu folosim o parte dintre clasele din nucleul CI putem sa facem acest lucru intr-un mod relativ usor.

CodeIgniter permite si chiar faciliteaza realizarea de aplicatii prietenoase cu motoarele de cautare. CI permite realizarea unei scheme de URL-uri prietenoase de genul www.siteulmeu.com/numele-paginii, permitand astfel navigarea prin URL, oferind utilizatorului inca o cale de a accesa continutul cautat intr-un mod cat mai facil, dar acest lucru implica folosirea rewrite engine.

Trăsături esențiale ale framework-urilor

Abstractizarea bazei de date: Framework-urile conferă un nivel de abstractizare al bazei de date SQL. Astfel, se poate oricând schimba baza de date din MySQL în MSSql de exemplu, fără a fi nevoie să se rescrie vreun rând de cod. Acest nivel de abstractizare poate în același timp să recunoască legăturile dintre tabele, ceea ce ne scutește de bătăile de cap când vine vorba de JOIN-uri.

Abstractizarea cache-ului: În loc să se folosească funcții spcifice pentru cache (cum ar fi apc_add sau apc_fetch) se vor utiliza clase specifice de caching cum ar fi Memcache, APC sau  XCache.

Management-ul form-urilor: Form-urile pot fi definite ca și cod PHP. Apoi framework-ul se ocupă de generarea codului HTML, validare și securitate.

Autentificarea: Majoritatea framework-urilor vin cu un modul de autentificare. Acestea se ocupă de log in și log out, înregistrare, management de sesiune, permisiuni. Aceste module sunt ușor de modificat pentru a crea formulare customizate pentru înregistrare și logare.

Depanare ușoară: Unele framework-uri vin în ajutorul programatorului cu unelte care fac depanarea mai ușoară. Acestea permit inspectarea variabilelor, a query-urilor, a duratei de timp în care rulează script-ul etc.

Internaționalizarea: Majoritatea framework-urilor permit traducerile, ceea ce înseamnă că se poate construi ușor un website în limba dorită de client.

Avantajele folosirii unui framework

Portabilitate: Abstractizarea bazei de date și a cache-ului fac ca aplicațiile construite cu un framework să poată rula pe servere, având diferite configurații fără a fi necesară rescrierea vreunui rând de cod.

Timp de dezvoltare mai scurt: Asta se datorează în primul rând faptului că nu mai trebuie să scriem codul pentru form-uri, înregistrare, log in și log-out etc.

Securitate: Framework-ul se ocupă de securitatea pentru modulele buid-in: autentificare, formulare, query-uri SQL.

Suportul comunității: Framework-urile au forumuri specializate, canale de IRC unde putem găsi oricând un răspuns la problemele pe care le întâmpinăm legate de framework atunci când dezvoltăm aplicația.

Plugin-uri și module: Nu am descoperit noi roata. A fost descoperită de alții înaintea noastră. Este așadar foarte probabil ca modulul sau plugin-ul de care avem nevoie să fi fost deja dezvoltat de alți programatori și tot ceea ce trebuie să facem este să îl descărcăm și să îl folosim în aplicația noastră.

Standard de codare: Framework-urile „forțează” într-un anume fel programatorii să urmeze principiul Model->View->Controller. Asta înseamnă că vom gândi mai întâi structura codului, pentru ca apoi ne apucăm de scris.

Documentație: Framework-urile sunt foarte bine documentate, ceea ce ușurează înțelegerea codului.

3.2 MVC (MODEL-VIEW-CONTROLLER)

In general, scopul multor computere este acela de a prelua informatii dintro anumita locatie, de a o prelucra dupa preferintele utilizatorului si, in cele din urma, de a o afisa utilizatorului. Dupa ce utilizatorul modifica continutul informatiei si dupa aplicarea unor eventuale procesari aditionale, sistemul reinoieste informatia in locul de unde a preluat-o initial. Cea mai usoara metoda de a realiza o aplicatie care realizeaza aceste operatii este de a pune laolalta operatiile si de a le trata ca pe un tot. Aceasta metoda este buna in sensul ca este usor de implementat. Ulterior apar insa probleme cand se doreste schimbarea uneia din componentele fluxului de date, spre exemplu atunci cand se doreste schimbarea interfetei. O alta problema tine de logica de business ce trebuie incorporata, logica care si ea este supusa schimbarilor si care merge dincolo de simpla interschimbare de informatie.

Apare asadar nevoia de a modulariza aplicatia, de a delimita in mod clar partile componente spre a putea fi usor modificate si ca dupa modificare sa fie inca compatibile cu celelalte module ce formeaza aplicatia. O solutie la aceasta problema este arhitectura Model-View-Controller (MVC) care separa partea de stocare a datelor de cea de prezentare si de prelucrare. Se remarcă asadar trei clase distincte:

Model-ul se ocupa de comportarea si datele aplicatiei; raspunde la cereri despre starea sistemului, la cereri de schimbare de stare si notifica utilizatorul atunci cand aceste schimbari au avut loc pentru ca acesta sa poata reactiona. View-ul transpune model-ul intr-o forma care permite o interactionare usoara, in mod tipic o interfata vizuala. Pot exista multiple view-uri pentru un singur model pentru scopuri diferite. Controller-ul primeste input de la utilizator si initiaza un raspuns in urma cererilor catre obiectele model.

Controller-ul este cel care controleaza celelalte doua clase de obiecte, view si model, instructandu-le sa execute operatii pe baza input-ului primit de la utilizator.

MVC a fost descris pentru prima oara in 1979 de catre Trygve Reenskaug care pe vremea aceea lucra la Smalltalk din cadrul Xerox PARC. Implementarea originala este descrisa in detaliu in lucrarea Applications Programming in Smalltalk-80: How to use Model–View–Controller.

O aplicatie orientata pe principiile MVC poate fi o colectie de triade model/view/controller, fiecare responsabila de un element diferit al interfetei cu utilizatorul. MVC este des intalnit in in aplicatii web unde view-ul este codul HTML generat de aplicatie.

Controller-ul primeste variabile GET si POST ca si input si decide ce sa faca cu acestea, trimitandu-le mai departe model-ului. Model-ul, care contine logica de business si regulile aferente, poate efectua operatiile necesare asupra datelor pentru a putea permite aplicatiei generarea codului HTMl mai sus mentionat via engine-urile de template, pipeline-uri XML, cereri de tip Ajax, etc.

Model-ul nu este neaparat doar o baza de date, fiind adesea atat baza de date cat si logica de business necesara pentru a manipula datele in interiorul aplicatiei. Multe aplicatii folosesc un mecanism persistent de stocare a datelor. MVC nu specifica in mod explicit nivel de acces la date tocmai pentru ca este de la sine inteles ca acesta se afla incapsulat in model. In unele aplicatii simple care au putine reguli de business logic impuse, model-ul se poate limita doar la o baza de date si la functionalitatile oferite de aceasta. View-ul, de asemenea nu este limitat doar la afisarea informatiei, el avand un rol important si in interactiunea cu utilizatorul. In cazul exemplului de mai sus al aplicatiilor web interfata generata via cod html este cea care se ocupa si de preluarea input-ului si de masurile luate pentru ca acesta sa fie corect. Controller-ul este adesea confundat cu aplicatia insasi, pe cand rolul sau este de a dirija datele intre celelalte doua clase de obiecte. Intr-adevar, se pot executa multe operatii asupra datelor de catre model, insa aceste operatii tin de formatul in care se prezinta datele la un moment dat. Adesea se intalneste cazul in care datele afisate/culese de la utilizator difera semnificativ de cele stocate in baza de date.

Aceste diferente se datoreaza conversiilor ce pot fi aplicate asupra datelor de catre controller pentru a facilita traficul de informatie intre componente. Fiecare clasa de obiect are anumite expectative definite in ceea ce priveste formatul datelor, ori aceste transformari de format trebuie realizate automat pentru a mentine un flux constant de date, degrevand celelalte clase de grija conversiilor si asigurand aplicatia ca fiecare modul primeste ceea ce asteapta. Asta pe langa functia de baza de controla traficul de cereri intre module.

Schema de functionare a unei aplicatii modelate dupa arhitectura MVC decurge, in linii mari, in felul urmator:

1. Userul interactioneaza cu interfata. (exemplu: apasa un buton la tastatura)

2. Controller-ul primeste actiunea apasarii butonului si o converteste intr-o actiune pe intelesul model-ului.

3. Controller-ul notifica model-ul de actiunea utilizatorului, urmand de obicei o schimbare a starii model-ului. (exemplu: model-ul reimprospateaza starea campului de adresa)

4. Un view interogheaza model-ul pentru a genera o interfata corespunzatoare. (exemplu: view-ul afiseaza noua adresa alaturi de cea veche alaturi de un buton de confirmare)

5. Interfata asteapta actiuni suplimentare din partea utilizatorului, ciclul reluandu-se.

Variatii

In Application Programming in Smalltalk-80: How to use Model-ViewController (MVC), Steve Burbeck descrie doua variante de MVC: un model pasiv si un model activ.

Modelul pasiv este folosit cand un controller manipuleaza model-ul exclusiv. Controller-ul modifica model-ul si apoi informeaza view-ul ca model-ul a fost schimbat si ca trebuie reimprospatat. In acest scenariu model-ul este complet independent de view si controller, ceea ce inseamna ca model-ul nu are cum sa raporteze schimbarile sale de stare.

Protocolul HTTP este un exemplu eleocvent al acestui model pasiv. Browserul nu are cum sa primeasca update-uri asincrone de la server. Browserul afiseaza view-ul si raspunde la input utilizator dar nu detecteaza schimbari in datele de pe server. Doar atunci cand utilizatorul cere in mod explicit o reimprospatare serverul este interogat pentru eventualele schimbari.

Modelul activ este folosit cand model-ul isi schimba starea fara implicarea controller-ului. Acest lucru se poate intampla cand alte surse schimba datele iar schimbarile trebuie reflectate in view-uri. Un exemplu de astfel de model implementat este banda de stiri in timp real a canalelor de stiri.

Aceasta afiseaza in timp real datele din baza de date pe masura ce acestea sunt modificate. (pe masura ce noi stiri sunt adaugate) Totusi, pentru a avea acest model ar insemna ca view-ul sa fie dependent de model, ori noi dorim ca ambele sa fie independente unul de celalalt. Introducem notiunea de observator care este un obiect ce notifica celelalte obiecte de schimbari de stare fara a introduce dependente intre acestea. Viewurile se subscriu la observator pentru a primi notificari. Cand un model se schimba el notifica toate observatoarele atasate lui de schimbarea produsa. La randul lor, observatoarele notifica view-urile de schimbarile raportate lor. Aceasta metoda este cu atat mai eficienta cu cat exista un numar mai mare de modele si view-uri care opereaza dupa modelul dinamic.

Comunicare model – view

In mod normal, modelul nu are nici o informatie in legatura cu view. Totusi exista o comunicare intre aceste 2 parti si ea are loc daca:

• A fost apasat un buton si a fost trimisa o comanda model-ului.

• O valoare noua a fost scrisa intr-un „text field” si un mesaj de actualizare a fost trimis model-ului.

• Daca o valoare este necesara view-ului, o cerere ii este trimisa model-ului pentru acea valoare. Astfel, comunicarea are loc daca se intampla un eveniment.

View-ul trimite o cerere catre model care trebuie sa fie capabil sa o descifreze si sa ii trimita un raspuns, indiferent daca acest raspuns este o valoare sau o serie de operatii mai complicate. Bineinteles ca este nevoie de o programare buna a modelului care trebuie sa fie capabil sa descifreze un numar mare de astfel de operatii.

In Java putem folosi interfata „java.util.Observer” ca baza a componentei view, interfata ce cuprinde subclasa „javax.swing.Jpanel”. In urmatorul exemplu, view este implementat in clasa DiagramView. Implementarea a fost simplificata astfel incat o mica schimbare a modelului provoaca redesenarea. Acest lucru este realizat in functie de update-ul din interfata Observer.

View decide asupra reprezentarii actuale a diagramei. Singurele lucruri adaugate conexiunii sunt titlurile si punctul central al nodurilor. View trebuie sa retina informatiile despre dreptunghiurile de selectie ale nodurilor (harta structurii de date rcache).

Ierarhia view/subview

View-urile sunt construite pentru a fi imbricate. Cele mai multe ferestre contin doua view-uri, unul imbricat in celalalt. View-ul extern, cunoscut ca topView, este o instanta a StandardSystemView sau o subclasa a lui. StandardSystemView gestioneaza fiecare atribut din tabelele ferestrei. In interiorul topView sunt unul sau mai multe subView-uri care au controlere asociate ce gestioneaza optiunile de control disponibile pentru fiecare View. De exemplu, un „workspace” familiar are StandardSystemView ca topView si StringHolderView ca subView. Un subView poate avea, optional, alt subView, dar asta se intampla foarte rar in aplicatii.

Relatiile subView/superView sunt inregistrate in variabile mostenite de la View. Fiecare View are o variabila superView in care se contine pe sine si contine si alte subView-uri care reprezinta OrderedCollection pentru subView-uri. Astfel, topView-ul din fereastra reprezinta varful ierarhiei, urmand apoi variabilele superView si subView.

In continuare se va prezenta un exemplu care contruieste si lanseaza o „triada” MVC. Acest exemplu este o versiune simplificata a codului care deschide „methodListBrowser”-browser-ul pe care il vedem cand alegem implementatorii si expeditorii din lista de metode a subView-urilor. SubView-ul superior afiseaza o lista de metode; cand selectam o metoda, codul sau apare in subView-ul inferior. In exemplu voi numerota liniile de cod pentru a face referire mai usor la ele cand le voi explica:

openListBrowserOn: aCollection Label: labelString initialSelection: sel "Create and schedule a Method List browser for the methods in aCollection." |topView aBrowser|

1. aBrowser:=MethodListBrowser new on: aCollection

2. topView:=BrowserView new.

3. topView model: aBrowser; controller: StandardSystemController new;

4. label: labelString asString; minimumSize: 300@100.

5. topView addSubView:

6. (SelectionInListView on: aBrowser printItems: false oneItem: false

7. aspect: #methodName change: #methodName: list: #methodList

8. menu: #methodMenu initialSelection: #methodName)

9. in: (0@0 extent: 1.0@0.25) borderWidth: 1.

10. topView addSubView:

11. (CodeView on: aBrowser aspect: #text change: #acceptText:from:

12. menu: #textMenu initialSelection: sel)

13. in: (0@0.25 extend: 1@0.75) borderWidth: 1.

14. topView controller open

1. Creare model

2. Creare topView (in general acesta este StandardSystemView, dar in acest exemplu am folosit BrowserView care este o subclasa a StandardSystemView)

3. Specificare model si controler (daca nu specificam controler-ul, el este furnizat de metoda defaultController cand este prima data apelat)

4. Specificare dimensiunea minima pentru topView

5-9. Instalare subView superior care este SelectionInListView

10-13. Instalare subView inferior

14. Deschidere controle

Afisarea view

View poate avea nevoie de propriul protocol de afisaj care va fi utilizat atat pentru afisarea imaginii initiale, cat si pentru reafisarea imaginii in cazul unei schimbari a modelului. Dupa o actualizare a modelului, View trimite „propriul afisaj” (self display). „View display” trimite pe rand „self displayBorder”, „self displayView”, „self displaySubviews”.

Daca View cere o afisare speciala diferita de cea mostenita, el considera afisarea ca fiind una dintre cele trei enumerate mai sus. Pentru diverse tehnici de afisare putem cauta implementari in displayView. Observam modificari ale afisajului in functie de fiecare metoda folosita. Schimbarile afisajului sunt instante ale WindowingTransformation. Ele dirijeaza scalarea si translatarea in functie de conexiunea la fereastra si la porturile View-ului. O fereastra este o intrare a transformarii. Este un dreptunghi intr-un afisaj abstract avand coordonate arbitrare in sistem, dar apropiate de nevoile aplicatiei noastre. Un port este reprezentat de un dreptunghi specific ferestrei abstracte care poate fi mapat. Clasa WindowingTransformation calculeaza si aplica scala si coeficientii de translatie pentru obiectele afisate ca puncte si dreptunghiuri, formand aWindow care, transformata, corespunde unui aViewport. Cu toate aceste, transformarea doar scaleaza si modifica un set de coordonate, neexistand nicio legatura directa cu afisarea pe ecran; astfel, transformarea poate avea alta destinatie.

Cele mai importante metode View:

Display: desenam ceva care sa reprezinte „view-ul”. Este tot timpul desenat pe instanta DisplayScreen care ii atribuie o variabila globala Display (aceasta metoda nu permite afisarea mai multor surse in fereastra principala; o solutie mai buna este metoda „displayOn: aDisplayScreen”). Implementarea „libera” deseneaza intai chenarul (#displayBorder), apoi view-ul propriu-zis (#displayView), la sfarsit desenand subview-urile (#displaySubViews). Exista metode ca #emphasize si #deEmphasize care pot fi folosite pentru a activa „widget” sau fereastra. Aceste metode nu sunt prea bune deoarece, in urma aplicarii lor, fereastra „palpaie” pentru ca desenul este afisat prea des.

„update: aSymbol”: aceasta metoda este apelata cand modelul dependent numeste metoda „#changedmethod”. Putem folosi metoda pentru a optimiza desenul bazandu-ne pe o stare noua a modelului.

„containsPoint: aPoint”: metoda raspunde cu „adevarat” daca aPoint face parte din View. Putem suprascrie metoda pentru afisaje non-rectangulare. De exemplu, StandardSystemView suprascrie aceasta metoda deoarece a folosit o eticheta non-rectangulara.

3.3 ADAPTIVE DESIGN

Adaptive design reprezintă capacitatea site-ului de a se ajusta în funcție de dimensiunea ecranului pe care este privit. Importanța designului adaptiv a crescut odată cu dezvoltarea și diversificarea telefoanelor inteligente și a tabletelor. Mai nou Google favorizează în rezultate site-urile care sunt adaptive. Acesta este un design care se pliază și arată excelent pe orice telefon, tabletă, computer personal sau chiar pe televizoarele inteligente. Înainte de a realiza un proiect web cu un design adaptiv, trebuie să ținem cont de câteva elemente esențiale:

Schemă flexibilă

O schemă flexibilă în formă de grilă ajută la structurarea mai bună a informației care se va afișa pe ecran. Aceste coloane te ajută să poziționezi și să orientezi conținutul în pagină în funcție de aparatul pe care acesta este afișat. Bineînțeles, se poate simplifica foarte mult aceasta grilă folosind doar două coloane principale, una să reprezinte partea de meniu, iar cealaltă conținutul.

.main{

margin-left: 20px;

}

.sidebar{

width: 200px;

float: left;

}

Elemente media adaptabile

Elementele media pot să reprezinte imaginile folosite în proiecte, player-ele video sau audio. De exemplu, imaginile se vor putea adapta în funcție de dimensiunea container-ului , iar aceasta presupune ca imaginile să aibă lungimea setată în procente.

img{

width: 100%;

}

Când vorbim despre un design adaptiv, trebuie să ținem cont și de performanță. Imaginile folosite trebuie optimizate pentru o vizualizare în condiții optime pe telefoane. Unul dintre "trucuri" pentru a putea realiza această optimizare, este folosirea javascript pentru a manipula atributul sursă al imaginii ("src") și pentru a înlocui imaginea în funcție de dimensiunea ferestrei.

Interogări media

CSS3 oferă această posibilitate de a putea identifica și determina dimensiunea ecranului, astfel încât să se poată modifica proprietățile elementelor din site în funcție de necesități.

@media screen and (max-device-width: 480px){

.main{

width: 100%;

}

.sidebar{

width: 100%;

float: none;

}

}

Din fericire, sunt disponibile framework-uri care pot ajuta la realizarea acestor proiecte adaptive fără a fi pornite de la zero; printre ele se regăsește și Twitter Bootstrap. Acest framework oferă:

Sistem de grilă fluid pe 12 coloane. Aceasta înseamnă că folosește procente în loc la dimensiuni fixe. Bineînțeles, gridul are caracteristicile unui design adaptiv.

Machete predefinite pentru conținut, iar ele pot să conțină coloane adaptabile la dimensiunea ecranului sau fixe.

Suport pentru design adaptiv cu un set de interogări predefinite pentru acoperirea tuturor device-urilor.

/* Monitoare cu dimensiuni mari */

@media (min-width: 1200px) { … }

/* Tablete în mod portrait sau landscape */

@media (min-width: 768px)and (max-width: 979px) { … }

/* Telefoane în mod landscape până la tablete în mod portrait */

@media (max-width: 767px) { … }

/* Telefoane în mod landscape sau cu dimensiuni mai mici */

@media (max-width: 480px) { … }

Stilurile pentru diverse componente sunt:

Font-uri,

Tabele,

Meniuri,

Paginare,

Formulare,

Butoane,

Imagini,

Iconițe/pictograme.

Funcții javascript pentru realizarea:

Tab-urilor,

Carusel de imagini,

Tooltip-uri,

Căsuțe de alertă.

Avantajele utilizării

Proiectele oferă o bună experiență pentru utilizator, fiind un proiect consistent din punct de vedere al stilului și al conținutului pe toate versiunile afișate.

Optimizare mai bună pentru motoarele de căutare. (referințe externe către o singură adresă și nu la adrese multiple, exemplu: www.starbucks.com,mobile.starbucks.com, m.starbucks.com)

Funcțional pe toate aparatele, indiferent de sistemul de operare folosit.(Exemplu iOS, Android, Windows)

Un timp mai scurt alocat pentru realizarea unui singur proiect decât pentru realizarea mai multor proiecte cu aceleași funcționalități. Acest aspect implică bineînțeles costuri mult mai reduse pentru proprietarul proiectului.

Timpul redus pentru întreținerea conținutului site-ului, decât sincronizarea conținutului pe două/trei variante ale site-ului.

Actualizarea de conținut/stil/flow se va face la doar un singur proiect.

Dar pe lângă toate aceste avantaje, sunt bineînțeles și câteva dezavantaje:

Unele resurse pot fi încărcate inutil pentru versiunea mobilă, dacă ne referim la javascript, stiluri, imagini. Toate acestea implică un timp mai mare de încărcare a paginii.

Efortul alocat pentru compatibilitatea dintre versiunile de browsere.

Interacțiunile sunt diferite de la ecranele cu touch la controlul site-ului pe un computer personal cu ajutorul unui mouse/tastaturi.

Ideea principală este că fiecare site trebuie să aibă un design adaptiv, astfel încât să nu se compromită experiența utilizatorului, indiferent de aparatul pe care îl folosește. Cu toate acestea, sunt proiecte care folosesc un design adaptiv parțial. De exemplu, www.microsoft.com. În acest caz, din păcate, designul adaptiv este folosit doar pe pagina principală a site-ului, iar link-urile de pe pagină te vor redirecționa către secțiuni care nu sunt adaptive la dimensiunea ecranului. Din acest motiv experiența utilizatorului va fi diferită de la o pagină la alta, iar acest aspect va crește procentul de părăsire a site-ului. Un alt exemplu, dar de data aceasta cu un site complet adaptiv, este www.starbucks.com. Cu această abordare, starbucks.com este mai ușor de navigat, fiind adaptat pentru mobile, tablete. Implicit și zona video este îmbunătățită, și aceasta cu ajutorul noilor tehnologii HTML 5, cu care se poate reda în condiții optime pe browser, indiferent dacă este sau nu instalat FLASH.

Pentru a realiza o soluție fiabilă adaptabilă pentru majoritatea aparatelor mobile, trebuie să ținem cont de următoarele aspecte:

Ergonomie: Un proiect cu o ergonomie bună poate oferi o serie de beneficii. O interfață grafică trebuie să fie intuitivă, ușurând deciziile pe care trebuie să le ia un utilizator.

Conținut: Pentru telefoanele mobile, defilarea în jos a informației poate deveni un chin. Din acest motiv, este important ca informația afișată să fie condiționată de dimensiunea ecranului.

Html5: Micile facilități oferite de html5 pot să facă diferența și să realizeze o experiență extraordinară pentru utilizator. Exemplu:

autofocus – câmpul care are acest atribut va fi automat selectat la încărcarea paginii.

email – câmpul va fi interpretat de navigatoarele moderne ca o căsuță de email, iar împreună cu atributul "required"se va face automat o validare de email.

number – la editare, browserele moderne vor afișa doar tastatura numerică

datetime -în cazul modificării căsuței, browser-ele moderne vor afișa un calendar

list – atributul list împreună cu elementul "datalist" va afișa o selecție de informații relevante cuvintelor introduse în câmp.

Performanță și Optimizare: Aplicațiile la care timpul de încărcare este redus, vor avea o notă mai bună pentru SEO. De asemenea, contează afișarea conținutului să fie una cât mai relevantă și adaptată pentru utilizator.

În concluzie, o aplicație cu un design adaptiv este o soluție recomandată pentru orice aplicație web, dar trebuie să ținem cont de toate aspectele care trebuie implementate pentru a realiza un pachet complet și adaptat pentru conglomeratele de aparate care ne înconjoară.

3.4 ELEMENTE ASINCRONE IN PROGRAMAREA WEB ( AJAX/JAVASCRIPT)

Termenul AJAX se referã în prezent la o serie de tehnologii care fac ca anumite pagini Web sã aibã un timp de actualizare mai mic, prin apel asincron la server si modificarea partialã a paginii afisate (“partial refresh”). AJAX aduce aplicatiile Web mai aproape de aplicatiile desktop (locale) prin diversitatea de componente de interfatã si printr-o interactivitate mai bunã.

Aplicatiile Web moderne folosesc tehnologii de tip AJAX pentru o interactivitatea sporitã, în sensul unui timp de rãspuns mai bun la actiuni ale utilizatorilor care folosesc un browser pentru accesarea aplicatiei. AJAX este una din caracteristicile aplicatiilor Web 2.0 (numite si aplicatii RIA=Rich Internet Applications sau Rich Web Applications).

Semnificatia initialã pentru AJAX (Asynchronous JavaScript Technology and XML) a fost extinsã în sensul utilizãrii JSON (Javascript Object Notation) în loc de XML pentru transmiterea rãspunsului de la server la client în urma cererilor asincrone emise din paginile client. In prezent existã o diversitate de tehnologii sub denumirea AJAX, care au în comun posibilitatea oricãrui browser Web de a interpreta cod JavaScript, de a crea si folosi un obiect XMLHttpRequest (XHR) sau XMLHTTP pentru dialogul client-server.

Abordarea anterioarã AJAX (clasicã) era aceea ca orice gest din partea utilizatorului care necesitã o modificare a paginii HTML sã declanseze retrimiterea paginii modificate de cãtre server în întregime, chiar dacã o mare parte din pagina respectivã rãmânea nemodificatã. Tehnologiile AJAX permit modificarea partialã (incrementalã) si asincronã a paginii afisate de browser, pe baza unor date primite de la server si folosesc o reprezentare internã a acestei pagini (ca arbore DOM). Ideea este ca programul browser sã nu mai primeascã doar pagini întregi ci si instructiuni de modificare a unei pagini primite anterior si memorate într-o structurã de date care permite astfel de modificãri.

AJAX a fost adus în atentia publicã în 2005 prin Google Suggest: când începem sã tastãm într-un câmp text un cuvânt pentru cãutare cu Google, ni se oferã o listã de sugestii pe baza literelor din cuvânt deja tastate (trimise de server pe baza unui apel asincron cu literele tastate).

Tehnologiile AJAX sunt recomandate pentru situatii cum ar fi: validare localã, în timp real, a datelor introduse de utilizator (într-un formular), fãrã a trimite pagina spre validare la server; autocompletare prin prezentarea unei liste de selectie din care se poate alege la completarea unui câmp text (pozitionarea pe un câmp are ca efect trimiterea de cãtre server doar a listei de optiuni spre afisare sub acel câmp); încãrcarea la cerere a unor pagini HTML în avans si fãrã o cerere explicitã de la utilizator; aducerea în pagina curentã a unor controale (obiecte grafice) pentru o interactiune mai bunã: calendare (pentru a facilita introducerea unei date), tabele de date, meniuri, arbori (din care se poate alege ceva pentru completarea unui câmp), bare de progres, editoare; modificare partialã a paginii afisate pe baza unei cereri explicite (“partial submit”); actualizarea unor tabele afisate în paginã pe baza datelor trimise de server (scoruri, date despre vreme, cotatii actiuni sau cursuri de schimb); actualizarea se poate face prin interogare repetatã de cãtre client (“polling”) sau, mai eficient, prin pãstrarea unei conexiuni persistente între client si server si trimitere la initiativa serverului (“server-side push”, “asynchronous Web”); mixarea de date externe cu date din aplicatie (“Mashups”), cum ar fi o harta Google cu date din aplicatie; pagini ca aplicatii: pagini care aratã si se comportã ca aplicatii desktop.

Figura urmãtoare ilustreazã secventa de operatii într-un dialog client-server de tip AJAX care afiseazã un mesaj în urma validãrii continutului unui câmp text.

1. Utilizatorul genereazã un eveniment (prin mouse sau prin taste), care apeleazã o functie JavaScript

2. Functia JavaScript creeazã si configureazã obiectul XHR, precum si o functie “callback” care va primi rãspunsuri asincrone de la server.

3. Obiectul XHR face un apel cãtre server

4. Programul din server (ValidateServlet) prelucreazã cererea de la XHR .

5. ValidateServlet trimite ca rãspuns un document XML sau JSON sau HTML

6. Obiectul XHR apeleazã functia “callback” care prelucreazã documentul primit.

7. Arborele DOM al paginii HTML este actualizat, deci si imaginea oferitã utilizatorului.

Pentru concretizare vom considera cã în câmpul text trebuie introdus unul din numele “duke” sau “greg” si cã orice alt text va produce un mesaj de eroare “invalid”. In detaliu operatiile enumerate implicã urmãtoarele secvente de cod:

1. Pagina afisatã contine urmãtorul cod HTML:

<input type="text" size="20" id="userid" name="id" onkeyup="validate();">

La orice tastã actionatã în acest câmp se apeleazã functia Javascript “validate”

2. Functia “validate” creeazã si configureazã obiectul XHR:

var req;

function validate() {

var idField = document.getElementById("userid");

var url = "validate?id=" + encodeURIComponent(idField.value);

if (typeof XMLHttpRequest != "undefined") {

req = new XMLHttpRequest();

} else if (window.ActiveXObject) {

req = new ActiveXObject("Microsoft.XMLHTTP");

}

req.open("GET", url, true);

req.onreadystatechange = callback;

req.send(null);

}

Argumentele functiei “open” sunt: metoda HTTP folositã (GET, POST), URL-ul componentei din server cu care interactioneazã, “true” dacã apelul este asincron (cu functie callback).

3. In acest exemplu apelul se face cu o metodã GET fãrã continut, dar datele (id-ul introdus de utilizator) se trimit prin URL: req.send(null)

Metoda POST necesitã un antet “Content-Type”. Exemplu:

req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

req.send("id=" + encodeURIComponent(idTextField.value));

4. Cererea este prelucratã de ValidateServlet, care verificã id-ul primit prin cãutare într-un dictionar cu utilizatori autorizati si trimite unul din mesajele “valid” sau “invalid” sub forma unui document XML:

public class ValidateServlet extends HttpServlet {

private ServletContext context;

private HashMap users = new HashMap(); // all users

public void init(ServletConfig config) throws ServletException {

super.init(config);

this.context = config.getServletContext();

users.put("greg","account data"); // user “greg”

users.put("duke","account data"); // user “duke”

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws IOException, ServletException {

response.setContentType("text/xml");

response.setHeader("Cache-Control", "no-cache");

String targetId = request.getParameter("id");

if ((targetId != null) && users.containsKey(targetId.trim()))

response.getWriter().write("<message>valid</message>");

else

response.getWriter().write("<message>invalid</message>");

}

}

5. Rãspuns trimis de ValidateServlet pentru un “id” gãsit în dictionarul “users”:

<message> valid </message>

6. Functia callback, unde “req” este referinta cãtre obiectul XHR:

function callback() {

if (req.readyState == 4) {

if (req.status == 200) {

// update the HTML DOM based on whether or not message is valid

}

}

}

Rãspunsul XML primit este accesibil ca obiect DOM prin variabila “req.responseXML”, iar ca sir prin variabila “req.responseText”. Acestea fac parte dintr-un API JavaScript pentru acces la arborele DOM echivalent paginii curente afisate.

Exemplu de functie simplã care modificã elementul “message” din arborele DOM al paginii curente pe baza documentului XML anterior:

function parseMessage() {

var message = req.responseXML.getElementsByTagName("message")[0];

setMessage(message.childNodes[0].nodeValue);

}

7. Functia “setMessage” cautã în arborele DOM (identificat prin “document”) un element (nod) care contine atributul ID al unui element din pagina HTML (“userIdMessage”):

<script type="text/javascript">

function setMessage(message) {

var mdiv = document.getElementById("userIdMessage");

if (message == "invalid") {

mdiv.innerHTML = "<div style=\"color:red\">Invalid User Id</ div>";

} else {

mdiv.innerHTML = "<div style=\"color:green\">Valid User Id</ div>";

}

}

</script>

<body>

<div id="userIdMessage"></div>

</body>

Modificarea proprietãtii “innerHTML” are ca efect imediat modificarea portiunii afectate din pagina afisatã. Daca proprietatea “innerHTML” contine elemente de tip <image> sau <iframe> atunci continutul specificat de aceste elemente este redat pe ecran; aceasta este metoda de creare/modificare treptatã a hãrtilor Google Map prin adãugarea unor elemente de imagine.

Dezavantajul acestei solutii este acela cã fragmente de HTML sunt folosite direct în codul JavaScript, ceea ce face codul dificil de citit si de modificat, amestecând logica de modificare cu elemente de prezentare HTML. O altã solutie este crearea sau modificarea dinamicã de noduri DOM prin adãugarea sau înlocuirea de fii ai unor elemente existente, ca în exemplul urmãtor:

<script type="text/javascript">

function setMessage(message) {

var userMessageElement = document.getElementById("userIdMessage");

var messageText;

if (message == "invalid") {

userMessageElement.style.color = "red";

messageText = "Invalid User Id";

} else {

userMessageElement.style.color = "green";

messageText = "Valid User Id";

}

var messageBody = document.createTextNode(messageText);

// if the messageBody element has been created simple replace it otherwise

// append the new element

if (userMessageElement.childNodes[0]) {

userMessageElement.replaceChild(messageBody, userMessageElement.childNodes[0]);

} else {

userMessageElement.appendChild(messageBody);

}

}

</script>

<body>

<div id="userIdMessage"></div>

</body>

Pot exista diferente între modul de acces la DOM si la obiectul XHR din JavaScript în diferite programe browser, dar bibliotecile AJAX existente (Prototype, Dojo, Scriptaculous,YahooUI) fac sã disparã aceste diferente. Exemplul urmãtor aratã diferenta dintre utilizarea unui combobox cu autocompletare programat cu obiect XHR si unul din biblioteca Dojo.

Fragment din pagina HTML care afiseazã un câmp text ce trebuie completat de utilizator:

<input type="text" size="20" id="complete-field" name="id" onkeyup="complete();">

La tastarea în acest câmp este apelatã functia Javascript “complete” care apeleazã un servlet “complete” caruia îi trimite numele câmpului care trebuie completat (“id”) ca parametru URL si numele functiei apelate (“processRequest”) ca rãspuns la cererea GET (apel asincron).

Functie “complete” la nivel de lucru direct cu obiect XHR:

function complete() {

if (window.XMLHttpRequest) req = new XMLHttpRequest();

else if (window.ActiveXObject) req = new ActiveXObject( "Microsoft.XMLHTTP");

var url = "autocomplete?action=complete&id=";

initRequest(url);

req.onreadystatechange = processRequest;

req.open("GET", url, true);

req.send(null);

}

function processRequest() {

if (req.readyState == 4) { // daca obiectul XHR a primit raspuns de la servlet

if (req.status == 200) // daca raspunsul este fara erori

parseMessages(); // prelucrare date din mesajul XML si modifica arborele DOM

else // daca raspuns eroare de la servlet

clearTable(); // nu se afiseaza tabelul ptr autocompletare

}

}

function parseMessages() {

if (! names) names= document.getElementById(“names”);

clearTable();

var employees= req.responseXML.getElementsByTagName (“employees”)[0];

if (employees.childNodes.length > 0) {

var autorow=document.getElementById (“menu-popup”);

autorow.style.visibility =”visible”;

}

for (k=0;k<employees.childnodes.length;k++) {

var employee= employees.childNodes[k];

var firstName= employee.getElementsByTagName(“firstName”)[0];

var lastName= employee.getElementsByTagName(“lastName”)[0];

var employeeId= employee.getElementsByTagName(“id”)[0];

appendEmployee (firstname.childNodes[0].nodeValue, lastname.childNodes[0].nodeValue,

employeeId.childNodes[0].nodeValue);

}

}

Aceeasi functie “complete” dar folosind biblioteca Dojo:

dojo.require("dojo.io.*"); // incarca codul Javascript pentru biblioteca Dojo

// Retrieve data through a Dojo call.

var bindArgs = {

url: "autocomplete?action=complete&id="+key, // URL cu nume servlet si nume camp

mimetype: "text/xml", // format pentru raspuns

load: processRequest

};

// functie callback

function complete() {

req=dojo.io.bind(bindArgs);

}

In prezent existã o diversitate de metode pentru includerea de functionalitate AJAX în pagini Web, care pot fi clasificate astfel:

– Scrierea manualã si integralã a codului JavaScript care lucreazã direct cu obiectul XHR si modificã reprezentarea internã a paginii afisate;

– Utilizarea unei biblioteci de componente prefabricate JavaScript la client, care ascund operatiile de nivel coborat cu obiectul XHR si simplificã programarea altor operatii cum ar fi validarea (Dojo Toolkit, Prototype, Scriptaculous, jQuery, s.a.).

– Utilizarea unui framework client-server, care ruleazã pe server, cu rezultat redat la client si care necesitã programare partial în Java si partial în JavaScript (functiile callback), cum este JSF (Java Server Faces). Componentele (“widgets”) pot reactiona la evenimente generate de utilizator (prin mouse si taste), la fel cu componentele Swing din aplicatii locale cu interfata graficã si pot fi folosite în programarea vizualã a paginilor Web.

– Utilizarea unui framework care permite programarea exclusivã în Java a functionalitãtii AJAX, simplificarea utilizãrii de componente UI, validãrii datelor, scrierii de noi componente si depanarea lor. Cel mai cunoscut este GWT (Google Web Toolkit), care foloseste modelul de programare Swing pentru pagini Web, un translator din Java în Javascript si o comunicare de tip RPC intre client si server.

Variante de implementare AJAX pe server:

1) Content Centric Ajax : rãspunsul la un apel asincron este cod HTML folosit la actualizarea paginii;

2) Data Centric Ajax : rãspunsul la un apel asincron are forma unui document XML sau JSON

3) Script Centric Ajax : rãspunsul la un apel asincron este cod JavaScript, interpretat de browser.

JSF2 Ajax (JEE6)

Componentele UI din JSF2 pot dobândi functionalitate AJAX folosind marcajul <f:ajax>. In felul acesta nu este necesarã scrierea de cod Javascript , nu trebuie intervenit în servleti care primesc apeluri asincrone, se pot utiliza de cãtre codul Ajax clasele suport (backing beans) iar functiile Ajax sunt integrate natural în componentele JSF2.

Exemplu simplu de buton JSF2 cu functionalitate Ajax:

<h:commandButton … action="…">

<f:ajax render="id1"/>

</h:commandButton>

<h:outputText … value="#{…}" id="id1"/>

La apãsarea butonului se face un apel la server, se executã actiunea specificatã prin atributul “action” care produce valoarea asociatã componentei “id1”, se trimite aceastã valoare înapoi la client unde înlocuieste elementul corespunzãtor din arborele DOM cu noua valoare.

Forma generalã a tag-ului Ajax este:

<f:ajax render="id1 id2" execute="id3 id4" event="blah" onevent="javaScriptHandler"/>

“render” : elementul din paginã reafisat (de obicei de tip <h:outputText>

“execute”: elemente trimise la server (de tip <h:inputText> , <h: selectOneMenu>, …)

“event”: eveniment Javascript la care se rãspunde (keyup, blur, etc)

“onevent”: functie Javascript (callback) apelatã la producere eveniment

Atributele “render” si “execute” pot specifica mai multe componente (separate prin blancuri) si pot folosi urmãtoarele valori speciale (predefinite):

@this : componenta care include tag-ul <f:ajax> (este implicit)

@form : formularul care include tag-ul <f:ajax> (util ptr a trimite mai multe câmpuri)

@none: nu se trimite nimic (componenta afisatã îsi modificã periodic valoarea)

@all : toate componentele UI din pagina curentã

Evenimentul onereadystatechange

Acest eveniment este declanșat de fiecare dată când readyState se modifică. Proprietatea readyState deține statutul de XMLHttpRequest.

<!doctype html>

<html>

<head></head>

<body>

<h2>AJAX</h2>

<button type="button" onclick="ajax()">DATA</button>

<div id="a"></div>

<script>

function ajax(){

var xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange=function(){

if (xmlhttp.readyState==4 && xmlhttp.status==200){

document.getElementById("a").innerHTML=xmlhttp.responseText;

}

}

xmlhttp.open("POST","nume-fisier.txt",true);

xmlhttp.send();

}

</script>

</body>

</html>

În ceea ce privește JavaScript, se poate aminti de apelul asincron. Mai jos se poate observa o soluție care ar putea să fie o alternativă în cazul în care se dorește evitarea utilizării unor arhitecturi prea “grandioase” pentru un “banal” apel asincron de metodă. Structura acesteia cuprinde elementele prezentate în diagrama de mai jos. Entitățile din structura unui apel asincron implică următoarele activități:

clientul creează un obiect de tip MethodRequest (instanța clasei Print) ce implementează metoda Do(executată concurent);

clientul apelează metoda BeginInvoke al clasei AsyncCall, transmițîndu-i obiectul de tip MethodRequest,dar și primind un obiect MethodResult care ne va “identifica” apelul;

AsyncCall prin metoda sa BeginInvoke va crea firul ce în momentul execuției va apela metoda Do al obiectului de tip MethodRequest;

la finele execuției metodei Do rezultatul va fi “salvat” în obiectul de tip MethodResult;

clientul va putea afla rezultatul execuției prin apelul metodei EndInvoke al clasei AsyncCall transmițind “identificatorul” MethodResult;

Această soluție nicidecum nu este o soluție completă sau perfectă. Ea poate fi dezvoltată astfel încît metoda invocată să poată avea și parametri. În această ordine de idei o sugestie ar putea fi clasa lui Rakhitha Karunarathne ce utilizează tehnici Reflection.

CAPITOLUL IV. DESCRIEREA APLICAȚIEI

4.1 INTRODUCERE

În cele ce urmează vor fi prezentate aspectele specifice ale acestei aplicatii de la baza de date, pana la elementele asincrone din cadrul jocului pana la exemple ale celor mai importante functii.

4.2 BAZA DE DATE

Aplicatia foloseste o baza de date MYSQL care este accesata in mod constant de catre parte de front-end. Mai jos in figura 1, este prezentate structura bazei de date:

Tabele: Admin_users: servesc la logarea utilizatorilor in interfata de administrare(CMS) unde parolele sunt stocate in format MD5.

Sessions: tine datele utlizatorilor in momentul de fata pe site. Durata de viata a unei sesiuni este de 2 ore si include date precum, data utlizatorul este logat, date despre camera pe care a creat-o, scorul in cadrul acesteia etc

Users: tine date despre utilizatori care si-au creat cont.

Scoruri: un tabel legat 1-1 cu cel de users fiecare utilizator avand un scor asociat.

Intrebari: tabelul care contine intrebarile, cele 4 variante de raspuns precum si raspunsul corect. Variabila booleana valid permite intrebarilor sa fie afisate. Intrebarile adaugate de utilizatori din front-end trebuiesc validate de catre un administrator inainte de a putea aparea pe site pentru a elimina riscul intrebarilor gresite.

Categorii: un tabel simplu care determina categoriile intrebarilor (sport,geografie etc). Acest tabel contine o categorie de baza (general) la care toate intrebarile sunt asociate in mod automat.

Intrebari_has_categori: un tabel asociativ n-n care permite asignarea unei intrebari in mai multe categorii.

Camere: tabelul cel mai important pentru functionarea aplicatiei, contine un UUID (Universally unique identifier) aferent camerei. Dupa acest UUID userii vor fi redirectionati catre aceasta camera. Desi exista o singura pagina de joc, prin intermediul acestuia userii pot fi conectati intre ei. Tabelul mai contine si date generale despre camera cum ar fi numarul curent de useri, numarul maxim de useri, care odata atins duce la inceperea jocului, si o variabila de status care dicteaza functionarea camerei.

Camere_has_useri: tabelul de legatura dintre camera si useri, contine date despre user cum ar fi nicknameul (fie cel ale de utilizator in cazul in care este logat, fie unul de tip guest asignat automat), ip-ul (necesar in cazul in care utilizatorul nu este logat) si numarul de puncte in cadrul jocului curent. Aceste puncte sunt adaugate la sfarsitu jocului la totalul general al userului daca acesta este logat.

Camere_has_intrebari: Odata ce o camera a fost creata ei ii sunt atribuite in mod aleator numarul selectat de intrebari din categoria selectata. Ordinea este aleatorie pentru a preveni monotonia. Relatia este de tip one to many intrucat o camera are mai multe intrebari.

Tabelele contin chei primare pentru identificarea usoara a unui element precum si chei externe unde este cazul pentru a asigura ca legaturile dintre tabele sunt exacte si nu permit lipsuri. Astfel toate intrebarile au asociata cel putin o categorie(cea generala) dar pot avea si mai multe asocieri. Aceste asocieri pot fi modificate oricand din interfata de administrare. Validitate intrebarilor este asigura tot din interfata de administrare unde un utilizator special le poate bifa ca active sau debifa astfel asigurand ca nu vor aparea in frond-end intrebari gresite.

Deasemenea se pot adauga categori si se pot asocia intrebari deja existente acestor categorii.

4.3 DESCRIERE IN LIMBAJ NATURAL

4.3.1 Structura linkurilor

Deoarece aplicatia se bazeaza pe frameworkul Codeigntier am decis sa pastrez elementele sale definitorii pentru a ajuta in cadrul proiectului. Astfel partea de abstractizare a conexiunii la baza de date este facuta in cadrul frameworkului, fisierul config/database continand datele de conectare. Deasemenea partea de rescriere a linkurilor cunoscuta si sub numele de routing este facut tot prin intermediul frameworkului dar si din fisierul de .htaccess pe care l-am creat manual. Astfel linkurile sunt diferite de cele native aferente frameworkului care arata de forma www.sitename/index.php/controller/function/arguments in ceva natural si usor de descris astfel www.sitename/controller_function. O lista a acestor rescrieri se afla in fisierul application/config/routes. Pentru eliminarea index.php am folosit fisierul .htaccess care este prezent in root-ul aplicatiei.

4.3.2 Structura fisierelor

Fisierele sunt aranjate in conformitate cu standardul MVC. Astfel se vad in root-ul aplicatiei cele 3 foldere aplication,system si assets precum si fisierul de .htacces si index.php care se ocupa cu redirectarea. In folderul system se aflat fisierele de baza ale frameworkului Codeigntier care se ocupa de o multitudine de aspecte precum conexiunea la baza de date, libraria de email, routare, etc. In fisierul assets se afla fisierele statice necesare aplicatiei, de la imagini pentru design la fisierele de CSS necesare pentru adaptive design precum si functii de javascript. Printre acestea mentionez: jquery, esential in programarea javascript, chosen – un plugin util pentru stilizarea formularelor, flipclock – un plugin de countdown. Toate acestea sunt pluginuri gratuite.

Folderul de aplication contine aplicatia in sine. Avem un folder de config, unde sunt setate conexiunea la baza de date, routarile necesare, modulele autoincarcate in cadrul aplicatiei ( de sesiune, de stilizare) precum si hook-urile, extensiile care se aplica inaintea incarcarii paginii care au un rol crucial in functionarea corecta a aplicatiei. Avem deasemeena folderul de controllers care face legatura dintre modele si view-uri. Aici avem un controller pentru interfata de administrare (admin), un controller pentru aplicatia in sine (main), un controller pentru cron-jobs (cron) si un controller denumit ajax unde se afla toate functiile apelate asincron in cadrul paginilor.

Avem deasemenea folderul de models, care contine 2 modele, unul pentru front-end (main_model) si unul pentru interfata de administrare (admin_model). Aceste modele fac legatura cu baza de date si trimit datele catre controller care apoi le distribuie la view-uri. Aceasta abordare permite refolosirea de cod mult mai usor, nefiind nevoie de cod in plus pentru a folosi o functie de mai multe ori.

Folderul de views contine fisiere care prelucreaza date primite de la controller pentru a face utilizarea siteului mai usoara. Intrucat headerul si footerul sunt aceleasi in fiecare pagina am creat 2 fisiere separate pentru acestea care sunt incarcate de fiecare data, dar care pot fi modificate usor fara a necesita vreo modficare in continutul paginilor. Aceeasi metodologie am folosit-o si pentru admin unde fisierele de header si footer sunt separate.

In folderul errors se afla pagina de 404, un element nelipsit in cadrul oricarui site, iar in folderul hooks se afla 2 fisiere care sunt accesate inaintea incarcarii oricarui element al paginii, lucru specificat in fisierul de configurare /config/hooks, iar ele sunt folosite pentru a asigura accesul la interfata de administrare(access_control) si dicteaza ce date sunt stocate in sesiunile userilor din front-end (site_control).

4.3.3 Structura aplicatiei.

Aplicatia este impartita in 2 module.

Primul este modulul de administrare. Acesta este blocat de accesul extern si paote fi accesat numai cu un user si parola speciale stocate in baza de date in tabelul admin_users. Modalitate de logare este una simpla, parola userului este criptate MD5 ( algoritm 1 way) si este comparata cu valoarea din baza de date aferenta userului introdus. Textul introdus la parola este sanitizat pentru a preveni atacuri de genul sql injection.

In interfata de administrare avem urmatoarele pagini:

Intrebari: o vizualizare a intrebarilor adaugate, de unde se poate modifica cu usurinta o intrebare, fie se poate valida sau invalida (nu ii este permis sa apara in front-end), fie ea poate fi stearsa de tot din baza de date, fie ii pot fi modificate categoriile aferente. Am adaugat si o filtrare dupa categorie, precum si o paginare cu posibilitatea de a sari la o anumite pagina. Deasemenea se pot si adauga intrebari folosind un formular simplu.

Useri: consta in afisarea userilor precum si ip-urilor acestora. Este deasemenea prevazuta cu paginare si jump to page.

Camere: o afisare succinta a camerelor active care contine numarul de utilizatori curenti, numarul maxim de utilizatori precum si intrebarile asociate acestei camere.

Sesiuni: o afisare a sesiunilor active pe site in orice moment.

Categorii: o Afisare a categoriilor precum si a numarului de intrebari din cadrul fiecareia. Exista desigur si o functionalitate de adaugare de categorie.

Cel de-al doilea modul este cel de font-end. Prima pagina contine toate informatiile necesare utilizatorului. El are aici optiunea de a se loga/deloga, de a adauga o intrebare, de a incepe un joc. Exista un numar de pagini statice care servesc un scop general, dar necesar pentru orice aplicatie( contact, termeni si conditii, informatii etc).

Aplicatia adevarata se afla in spatele butonului de joc nou. Aici utilizatorul are doua optiuni:

1. El poate cauta un joc dupa o categorie. In acest caz el va fi redirectionat la o pagina de asteptare care verifica la fiecare 5 secunde disponibilitatea unei camere corespunzatoare categoriei alese. Aici avem un ceas care contorizeaza timpul de asteptare iar in urma unui apel cu succes al functiei de cautare, utilizatorul va fi redirectionat in camera aferenta.

2. Utilizatorul poate crea o camera pe o anumite categorie, cu un numar specificat de jucatori si intrebari. Dupa crearea camerei utilizatorul va fi redirectionat in camera specifica.

Odata ajunsi intr-o camera utilizatori trebuie sa astept umplerea acesteia. O functie in cadrul paginii de joc face aceasta verificare o data la 4 secunde. In cazul in care camera a atins numarul adecvat de jucatori functia de verificare se dezactiveaza si o functie de joc se activeaza. Aceasta afiseara intrebarile pentru utilizatori in acelasi timp dandu-le o parioada de 20 se secunde pentru a apasa pe unul din raspunsuri. Dupa 20 de scunde intrebarea dispare si este inlocuita cu urmatoarea. Scorul se updateaza independent odata la 4 secunde. Chat-ul foloseste un principiu asemanator de refresh odata la 4 secunde. El le permite utilizatorilor sa vorbeasca intre ei cu un mic delay. Dupa ce au fost parcurse toate intrebarile interfata de joc dispare si este inlocuita cu un mesaj care il informeaza pe utilizator despre statusul lui in cadrul jocului curent.

4.4 DESCRIERE TEHNICA SI EXEMPLE DE FUNCTII.

Voi prezenta in cele ce urmeaza exemple de functii in cadrul aplicatiei punand accentul pe elementele distinctive specifice programarii MVC orientata pe obiecte

4.4.1 Exemplu de controller

Controllerul main contine numeroase functii care reprezinta de fapt paginile siteului. Un astfel de exemplu este functia de adaugare intrebare. Mai jos este descierea acestei functii

EXEMPLU C1:

public function add_q()

{

$ret="";

if (isset($_POST["inst"])) $ret=$this->main_model->addq1($_POST);

if (isset($_POST["inst2"])) $ret=$this->main_model->addq2($_POST);

$data["logged"]=$this->main_model->get_logged();

$data["current_user"]=$this->main_model->get_user();

$data["scor_total"]=$this->main_model->get_scor();

$data["CURRENT_PAGE"]="Adauga Intrebare";

$data["fbh"]=0;

$data["title"]=$this->config->item('main_title');

$data["meta_description"]="";

$data["meta_keywords"]="";

$data["current"]="";

$data["loginfo"]=" Logat ca : ".$data["current_user"];

$data["cat"]=$this->main_model->get_cats();

$data["ret"]=$ret;

$this->load->view('header',$data);

$this->load->view('main_addq',$data);

$this->load->view('footer',$data);

}

In primul rand verificarile de $_POST sunt folosite pentru a semnala daca a fost introdusao intrebare. In caz afirmativ datele de POST sunt predate functiei de adaugare din cadrul modelului, functie care va fi explicata mai jos.

Controllerul apeleaza numeroase functii din cadrul modelului pentru a strange date. Astfel statusul de logat este luat prin intermediul functiei get_logged, scorul total este luat prin intermediul functiei get_scor, iar lista categoriilor necesare pentru asocierea intrebarii sunt luat prin functia get_cats. Variabila $ret contine rezultatul incercarii de adaugare a intrebarii. (pot aparea erori cum ar fi intrebare duplicata).

Ultima parte a functiei cheama view-urile aferente pentru generarea codului HTML aferent paginii. Dupa cum am mentionat anterior headerul si footerul sunt separate de interfata de adaugare pentru o asigura un mediu de creare fluid si usor de folosit.

4.4.2 Exemplu de model

Voi prezenta mai jos cateva exemple de functii din cadrul modelului (care face interogarile in baza de date si prelucreaza datele).

EXEMPLU M1:

public function get_cats()

{

$ret=array();

$sql="SELECT * FROM categorii ";

$catt=$this->db->query($sql)->result_array();

foreach ($catt as $ca)

$ret[$ca["id"]]=$ca["nume"];

return $ret;

}

Aici avem o functie simpla care selecteaza toate categoriile din tabel si le plaseaza intr-un array de tip id->denumire.

EXEMPLU M2:

public function get_logged()

{

$log=$this->session->userdata('flop');

return $log;

}

O functie care verifica in sesiune variabila flop care determina daca utilizatorul este logat sau nu.

EXEMPLU M3:

public function addq1($data)

{

//printr($data);

$user=$this->session->userdata('nick');

$sql="INSERT INTO `intrebari`

(`text`, `a`, `b`, `c`, `d`, `corect`, `added_by`) VALUES

('".$data["intrebare"]."', '".$data["rasp1"]."', '".$data["rasp2"]."', '".$data["rasp3"]."', '".$data["rasp4"]."', '".$data["corect"]."', '".$user."')";

$this->db->query($sql);

$idint=$this->db->insert_id();

$this->db->query("INSERT INTO `intrebari_has_categorii`(`id_intrebare`, `id_categorie`) VALUES ('".$idint."','1') ");

if (isset($data["cat"]) && is_array($data["cat"]))

{

foreach ($data["cat"] as $cc=>$name)

{

$sql="INSERT INTO `intrebari_has_categorii`(`id_intrebare`, `id_categorie`) VALUES ('".$idint."','".$name."') ";

//echo $sql;

$this->db->query($sql);

}

}

return " Intrebare adaugata cu success";

}

Aceasta functie este apelata de catre controler in cazul in care utilizatorul a introdus date in vederea adaugarii unei intrebari. Astfel se selecteaza usernameul din sesiune, se creeaza un sql de insertie, se selecteaza id-ul nou inserat. Apoi intrebarea este asociata in mod automat in categoria generala, iar in cazul in care utilizatorul a specificat mai multe categori, intrebarea este asociata cu fiecare dintre ele.

EXEMPLU M4:

public function logi($data)

{

$user=$data["username"];

$pwd=$data["password"];

$cripte=md5($pwd);

$valid=$this->db->get_where('users', array('nick' => $user,"pwd"=>$cripte));

if ($valid->num_rows()>0)

{

$newdata = array(

'nick' => $valid->row()->nick,

'flop'=>'1',

'id_user' => $valid->row()->id

);

$this->session->set_userdata($newdata);

$ip= $_SERVER['REMOTE_ADDR'];

$this->db->query("UPDATE users SET ip='".$ip."' WHERE id ='".$valid->row()->id."'");

return "GOOD";

}

else

{

return "Username sau parola gresit";

}

}

Acest ultim exemplu de functie din cadrul unui model face logarea unui user in cadrul siteului. Parola este criptate si verificata impreuna cu usernameul. In cazul logarii corecte se returneaza mesajul "GOOD", iar in cazul unei logari gresite: "Username sau parola gresit". Aceste raspunsuri sunt parsate de view si il avertizeaza pe user despre eroare sau il redirecteaza inapoi si ii incarca in sesiune datele aferente.

4.4.3 Exemplu de view

In exemplul ce urmeaza voi prezenta o parte din view-ul pentru adaugarea intrebarii. Se pot observa doua formulare fiecare dintre ele in cadrul unui div cu clasa Form1 respectiv Form2.

<div class="ter">

<div class="inner_titlu">

<h2 style="color:#000000;text-transform: uppercase;">

<strong>Adauga intrebare</strong>

</h2>

<div style="float:right; margin-top:-20px; margin-right:5px;">

<strong>

<div class="form1"><a href="<?=base_url()?>">Inapoi la pagina principala</a></div>

</strong>

</div>

</div>

<div class="lini">Adaugati o intrebare pentru a ii provoca pe ceilalti useri.</div>

<div class="lini">Folosind formularul de mai jos puteti adauga o intrebare in mai multe categorii.</div>

<div class="lini">Intrebarile vor trebui validate de un administrator inainte de a putea aparea pentru concurenti.</div>

<div class="lini">Va rugam sa pastrati intrebarile in limita decentei si a bunului simt.</div>

<div class="lini">Deasemenea in formularea intrebarii va rugam sa folositi date exacte ( EX: "in anul 2015" versus "anul acesta").</div>

<div class="lini">Incercati sa adaugati intrebari la care sa se poate da raspunsuri. (EX: nimeni nu stie si nimanui nu ii pasa cate medalii de bronz a luat Venezuela la Olimpiada din 1924).</div>

<div class="inner_titlu"></div>

<div align="center"><font color="#FF0000">

<?=$ret?>

</font>

</div>

<div class="form1">

<div align="center">

<div class="formo" >

<form name="dekstop_add" method="post">

<div class="titleq">Enunt:</div> <div class="formq"><input type="text" name="intrebare" id="intrebare" size="150"/></div>

<div class="emptydiv"></div>

<div class="titleq">Raspuns A:</div> <div class="formq"><input type="text" name="rasp1" id="rasp1" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq">Raspuns B:</div> <div class="formq"><input type="text" name="rasp2" id="rasp2" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq">Raspuns C:</div> <div class="formq"><input type="text" name="rasp3" id="rasp3" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq">Raspuns D:</div> <div class="formq"><input type="text" name="rasp4" id="rasp4" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq">Corect:</div>

<div class="formq">

<div class="radioo"><input type="radio" name="corect" value="a">A</div>

<div class="radioo"><input type="radio" name="corect" value="b">B</div>

<div class="radioo"><input type="radio" name="corect" value="c">C</div>

<div class="radioo"><input type="radio" name="corect" value="d">D</div>

</div>

<div class="emptydiv"></div>

<div class="titleq">Categorie</div> <div class="formq">

<select data-placeholder="Selectati categoria" name="cat[]" id="cat" multiple >

<? foreach ($cat as $cc=>$name):?>

<option value="<?=$cc?>"><?=$name?></option>

<? endforeach;?>

</select>

</div>

<div class="emptydiv"></div>

<div class="emptydiv"></div>

<input type="hidden" value="desktop" name="inst" />

<div align="center"><button type="submit" id="btnSubmitss" class="myButton3">Adauga</button></div>

</form></div>

</div>

</div>

</div>

<div class="form2">

<div align="center">

<form name="phone_add" method="post">

<div class="titleq2">Enunt:</div>

<div class="emptydiv"></div>

<div class="formq2"><input type="text" name="intrebare2" id="intrebare2" size="150"/></div>

<div class="emptydiv"></div>

<div class="titleq2">Raspuns A:</div>

<div class="formq2"><input type="text" name="rasp12" id="rasp12" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq2">Raspuns B:</div>

<div class="formq2"><input type="text" name="rasp22" id="rasp22" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq2">Raspuns C:</div>

<div class="formq2"><input type="text" name="rasp32" id="rasp32" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq2">Raspuns D:</div>

<div class="formq2"><input type="text" name="rasp42" id="rasp42" size="45"/></div>

<div class="emptydiv"></div>

<div class="titleq2">Corect:</div>

<div class="formq2">

<div align="center">

<div class="radioo2"><input type="radio" name="corect2" value="a">A</div>

<div class="radioo2"><input type="radio" name="corect2" value="b">B</div>

<div class="radioo2"><input type="radio" name="corect2" value="c">C</div>

<div class="radioo2"><input type="radio" name="corect2" value="d">D</div>

</div>

</div>

<div class="emptydiv"></div>

<div class="titleq2">Categorie</div>

<div class="formq2">

<select data-placeholder="Selectati categoria" name="cat2[]" id="cat2" multiple >

<? foreach ($cat as $cc=>$name):?>

<option value="<?=$cc?>"><?=$name?></option>

<? endforeach;?>

</select>

</div>

<div class="emptydiv"></div>

<div class="emptydiv"></div>

<input type="hidden" value="phone" name="inst2" />

<div align="center"><button type="submit" id="btnSubmitss" class="myButton3">Adauga</button></div>

</form>

<div class="emptydiv"></div>

<div class="emptydiv"></div><div class="emptydiv"></div>

<div class="emptydiv"></div><div class="emptydiv"></div>

<div class="emptydiv"></div><div class="emptydiv"></div>

<div class="emptydiv"></div>

</div>

</div>

Cu toate ca pagina contine 2 formulare, ele nu vor aparea niciodata afisate impreuna. Acest lucru se datoreaza css-ului care are urmatoarele setari cheie:

@media (min-width: 767px)

{

.form1 {visibility: visible; display: block;}

.form2 {visibility: hidden;clear: both;float: left;margin: 10px auto 5px 20px;width: 28%;display: none;}

}

@media (max-width: 767px)

{

.form1{visibility: hidden;clear: both;float: left;margin: 10px auto 5px 20px;width: 28%;display: none;}

.form2 {visibility: visible; display: block;}

}

Aceste setari ii transmit browserului o serie de instructiuni conform carora daca rezolutia ecranului pe care este vizualizat site-ul scade sub 767px (dimensiune strandard de telefon) sa dezafiseze primul formular si sa il afiseze pe cel de-al doilea care este structurat mai compact. Acest exemplu serveste ca o explicatie a modului in care datele care sunt preluate din controller sunt afisat pentru utilizator, cat si un exemplu de adaptive design.

4.4.4 Exemplu de functii Ajax

Inima aplicatiei sunt functiile Ajax care cheama asincron functii din controlerul Ajax si permit conectarea intre useri in timp real precum si demararea si rularea jocului de trivia.

Primul exemplu este unul mai simplu. Este vorba de functia de alocare in camere a unui user care cauta un joc. Ea se afla in pagina de cautare.

<script>

window.setInterval(function(){

$.ajax({

type: "POST",

url: "<?=base_url()."ajax/check_for_room"?>",

data: {},

}).done(function( msg ) {

if (msg!="0")

{

varr= "http://www.softpageinternet.ro/camera/"+msg;

window.location.replace(varr);

}

});

}, 5000);

</script>

Structura este una simpla. Folosind window.setInterval aceasta functie ruleaza in mod automat la fiecare 5 secunde. Se apleaza functia /check_for_room din cadrul controlerului ajax fara parametrii acestia fiind luati din sesiunea utilizatorului. In cazul in care apelul returneaza o valoare diferita de 0, userul este redirectat la camera cu UUID-ul gasit ca fiind corect. Functia din controlerul ajax arata astfel:

public function check_for_room()

{

$id_cat=$this->session->userdata('id_cat');

$status="creat";

$valid_uuid="0";

if ($id_cat==0 || $id_cat=="")

{ echo "0"; }

else

{

//chekc room neplin si pe categorie

$sql="SELECT id,uuid,nr_maxim_users,nr_curent_users FROM camere WHERE id_categorie='".$id_cat."' AND status='".$status."'";

$room=$this->db->query($sql);

if ($room->num_rows()>0)

{

foreach ($room->result_array() as $rom)

{

if ($rom["nr_curent_users"]==$rom["nr_maxim_users"]) continue;

$sql="SELECT id_camera FROM camere_has_useri

WHERE

(

id_user='".$this->session->userdata('id_user')."'

OR ip='".$this->session->userdata('ip_address')."'

)

AND id_camera='".$rom["id"]."'";

//echo $sql;

$userc=$this->db->query($sql);

if ($userc->num_rows()>0) continue;

$valid_uuid=$rom["uuid"];

}

}

echo $valid_uuid;

}

}

Întrucat functia Ajax asteapta ca raspuns o variabila text, folosesc echo in loc de return. Se poate observa ca functia cauta in tabelul de camere dupa categorie pana gaseste una libera iar apoi functia ajax in redirectioneaza pe user in camera pe baza UUID-ului.

Pagina de joc contine numeroase functii ajax care ii confera posibilitatea de a susine un joc cu mai multi utilizatori separati.

In primul rand avem functia:

interval = setInterval(update_users,4000);

function update_users(){

$.ajax({

type: "POST",

url: "<?=base_url()."ajax/check_room_full"?>",

data: {uuid:'<?=$uuid;?>' },

}).done(function( msg ) {

if (msg=="go")

{

clearInterval(interval);

someFunction();

refreshIntervalId = setInterval(someFunction,20000);

refreshIntervalId2 = setInterval(someFunction2,5000);

$( ".joci" ).show(10);

$( "#joci" ).delay( 2010 ).hide(10);

$( "#question" ).delay( 3010 ).show(10);

}

else

{

if ( msg!= $("#userss").html() )

{

$("#userss").empty();

$("#userss").html(msg);

}

}

});

Aceasta functie verifica odata la 4 secunde daca s-a atins numarul necesar de useri. Ca parametru are UUID-ul camerei iar in cazul in care camera nu este inca plina, ea va inlocui continutul divului cu id-ul userss cu lista de useri curenta de useri, fie ca aceasta s-a schimbat sau nu. In cazul in care camera a atins capacitatea necesara, functia isi inceteaza autoapelarea la 4 secunde si activeaza 2 alte functii someFunction care parcurge intrebarile odata la 20 de secunde si someFunction care este asemanatoare cu functia de mai sus dar afiseaza atata useri din camera cat si scorurile acestora.

function someFunction2() {

$.ajax({

type: "POST",

dataType: "json",

url: "<?=base_url()."ajax/get_scor"?>",

data: {uuid:'<?=$uuid;?>' },

}).done(function( response ) {

//alert(response.lala);

if (response.valid=="1")

{

$( "#userss" ).html(response.tabel);

}

});

function someFunction() {

$.ajax({

type: "POST",

dataType: "json",

url: "<?=base_url()."ajax/get_question"?>",

data: {uuid:'<?=$uuid;?>',currentq: $( "#quidd" ).val() },

}).done(function( response ) {

//alert(response.lala);

if (response.valid=="1")

{

//changeq

$( "#qqq" ).text(response.text);

$( "#rasp1" ).removeClass('div_gresit').removeClass('div_corect').removeClass('div_nimerit').addClass('div_rasp').text(response.a);

$( "#rasp2" ).removeClass('div_gresit').removeClass('div_corect').removeClass('div_nimerit').addClass('div_rasp').text(response.b);

$( "#rasp3" ).removeClass('div_gresit').removeClass('div_corect').removeClass('div_nimerit').addClass('div_rasp').text(response.c);

$( "#rasp4" ).removeClass('div_gresit').removeClass('div_corect').removeClass('div_nimerit').addClass('div_rasp').text(response.d);

$( "#intrebare_id" ).val(response.quid);

$( "#quidd" ).val(response.new_quid);

$( "#question" ).removeClass('notter')

$( "#raspuns_text" ).empty();

$( "#raspuns_text" ).text(" INTREBAREA " + response.new_quid + "/" + <?=$nri?>);

}

else

{

$( "#qqq" ).text("re");

$( "#question" ).hide(10);

$( "#finnal" ).show().text(response.text_final);

clearInterval(refreshIntervalId);

clearInterval(refreshIntervalId2);

}

});

Aceasta a doua functie cicleaza prin intrebarile asociate camerei odata la 20 de secunde. Deasemenea ea reseteaza divurile cu raspunsuri la o variante initala lipsita de culoare, si permite userului sa bifeze din nou un raspuns.

$( "#rasp1" ).click(function rasp1() {

$.ajax({

type: "POST",

dataType: "json",

url: "<?=base_url()."ajax/rasp"?>",

data: {

uuid:'<?=$uuid;?>',

currentq: $( "#quidd" ).val() ,

question_id: $( "#intrebare_id" ).val(),

rasp: "a"

},

}).done(function( response ) {

$( "#raspuns_text" ).text(response.text);

$( "#rasp1" ).removeClass('div_rasp').addClass(response.stil_1);

$( "#rasp2" ).removeClass('div_rasp').addClass(response.stil_2);

$( "#rasp3" ).removeClass('div_rasp').addClass(response.stil_3);

$( "#rasp4" ).removeClass('div_rasp').addClass(response.stil_4);

$( "#question" ).addClass('notter')

});

});

Exista 4 astefel de functii, cate 1 pentru fiecare raspuns, ele valideaza raspunsul utilizatorului, marcheaza dupa caz divurile de raspuns (raspuns corect, raspuns incorect, raspuns corect nimerit etc), precum si blocheaza divul de raspuns pentru ca utilizatorul sa nu poata raspunda la aceeasi intrebare de mai multe ori. Aceasta functie ajax are nevoie de un raspuns de tip json, astfel inca in functia de verificare datele sunt transformate intr-un array json: $ret=json_encode($st);echo $ret;

public function get_scor()

{

$valid=0;

$uuid=$_POST["uuid"];

$datas=$this->db->query("SELECT nr_intrebari,id,nr_maxim_users,nr_curent_users FROM camere WHERE uuid='".$uuid."'")->row();

$cid=$datas->id;

$datt=$this->db->query("SELECT * FROM camere_has_useri WHERE id_camera='".$cid."' ORDER BY puncte DESC");

$re="<table class='gridtable'><tr><th>User</th><th>Scor</th></tr>";

foreach ($datt->result_array() as $rr)

{

$re.="<tr><td>".$rr["nick"]."</td><td>".$rr["puncte"]."</td></tr>";

}

$re.="</table>";

$valid=1;

$ret=json_encode(array(

"valid"=>$valid

"tabel"=>$re

));

echo $ret;

}

Aceasta este o functie din cadrul controlerului Ajax care returneaza scorul baza pe UUID-ul camerei. Se observa cum variabila $ret contine un un tabel abstract care apoi este afisat in cadrul paginii prin intermediei functiei ajax someFunction2 descrisa mai sus, precum si o variabila de validitate, care verifica daca functia s-a executat in mod corect.

CONCLUZII

Prezenta lucrare se constituie ca suport al cunoștințelor dobândite pe parcursul studiilor univeristare în domeniul programării Web. Prin conținut și maniera de prezentare, prin setul generos de exemplificări bine documentate, lucrarea poate fi de un real folos oricărui cititor interesant de domeniu, cât și programatorilor lucrând la dezvoltarea de aplicații Web.

Pe parcursul a patru capitole, sunt tratate atât sub aspect teoretic, cât și mai ales aplicativ, cele mai relevante problematici cu care se poate întâlni în mod uzual un programator care utilizează suita de limbaje și tehnologii selectate ca suport de implementare: HTML, PHP, MySQL, JavaScript, AJAX.

Alegerea acestei suite, dintr-o gamă extrem de variată de alte limbaje și tehnologii de programare Web, oferă o amplă imagine asupra procesului de dezvoltare a aplicațiilor Internet, respectiv o prezentare tehnică a unui set complet de limbaje și instrumente software destinate finalizării acestui proces printr-un produs end-user: o aplicație de Trivia funcțională la parametrii optimi.

Punctul de start al prezentei lucrări îl constituie dezvoltarea unei aplicații de Trivia. Prin modificările și adaptările operate, prin subiectele revizuite și tematicile integrate, atât la nivel teoretic, cât și mai ales aplicativ, lucrarea de față este practic, ancorată în noile realități ale unui domeniu într-o continuă expansiune. Prin titlul ales, considerat a descrie mult mai bune conținutul actualizat în conformitate cu noile tendințe și dezvoltări din domeniu informatic abordat, lucrarea dezvăluie direct, fără echivoc, subiectul stabilit ca obiectiv principal: programarea Web. Întrucât plaja de referință a unui asemenea obiectiv este practic imposibil de cuprins și tratat complet, în vastitatea ei, într-o singură lucrare,obiectivul principal a fost focalizat pe expunerea utilității uzuale, a unor informații de maximă eficiență aplicativă, precum și pe descrierea amănunțită a aplicației web de Trivia destinată tuturor utilizatorilor de jocuri online, mai ales celor pasionați de jocuri de cultură generală , cu răspunsuri multiple.

De asemenea, din imensa gamă de limbaje și tehnologii de programare utilizate la ora actuală pentru dezvoltarea și întreținerea vastei construcții numită Internet, lucrarea se oprește doar asupra unei suite restrânse, oferind însă un meniu complet de instrumente software permițând proiectarea și implementarea oricărui tip de aplicații Web cerute pe piață. Suita la

care se face referire are următoarele componente: HTML, CSS, PHP, MySQL, JavaScript, AJAX, acoperind practic întreaga arie de problematici care se cer a fi rezolvate la dezvoltarea unui site Web. Abordarea subiectelor tratate este caracterizată printr-o puternică reprezentare aplicativă, orice secvență de cod prezentată putând fi imediat rulată, astfel încât programatorul să dispună din start de o bază de cod inițială, funcțională, imediat utilizabilă, adaptabilă și extensibilă conform cerințelor acestuia. De asemenea, abordarea este graduală, fiecare nou exemplu venind ca o completare a celor precedente, respectiv ca un pas în față pentru rezolvarea unei alte probleme, succesiv și logic apărute după rezolvarea celei precedente.

BIBLIOGRAFIE

1.Ioan Filip – Tehnologii de programare a aplicațiilor Internet cu baze de date,Editura Orizonturi Universitare, Timișoara, 2003.

2. Peter Belesis, Arman Danesh s.a. – Dynamic HTML, Sams.net Publishing, Indianapolis, USA, 1998.

3. Kris Jamsa, Ken Cope –Programarea aplicațiilor Internet, Editura All Educational SA, București, 1998.

4. Louis Kahn, Laura Logan –Build Your Own Web Site, Microsoft Press 1996.

5. Jon Duckett – Beginning Web Programming With HTML, XHTML, and CSS, John

Wiley & Sons, 2004.

6. Ian S. Graham – HTML Stylesheet Sourcebook, Wiley, 1997.

7. Brett McLaughlin – What Is HTML5?, O'Reilly Media, 2011.

8. Darren Levy – HTML/CSS / JavaScript: From Beginner to Whiz‖, Amazon Digital Services, 2011.

9. Julie Meloni, Michael Morrison – Sams Teach Yourself HTML and CSS in 24

Hours‖, Sams, 2009.

10. Stig Sæther Bakke, Alexander Aulbach s.a. -PHP Manual, PHP Documentation

Group (http://www.php.net/docs.php), 2003.

11. MySQL 5.0 Reference Manual (dev.mysql.com/doc/refman/5.0/en/), 2012.

12. Kevin Yank – Build Your Own Database Driven Web Site Using PHP & MySQL,

Copyright © 2009 SitePoint Pty. Ltd., USA, 2009.

13. Ioan Filip – Sisteme de gestiune a bazelor de date, Editura Orizonturi

Universitare, Timișoara, 2007.

14. Ethan Cerami – Web Services Essentials‖, O'Reilly Media, 2002.

15. Adam Trachtenberg, David Sklar – PHP Cookbook, O'Reilly Media, 2006.

16. Phill Ballard -AJAX în lectii de 10 minute, EdituraTeora, Bucuresti, 2007.

17. John Pollock – JavaScript, A Beginner's Guide, Third Edition‖, McGraw-Hill

Osborne, 2009.

18. Phil Ballard, Michael Moncur – Sams Teach Yourself Ajax, JavaScript, and PHP

All in One, Sams, 2008.

19. www.php.net/

20. php.net/manual/en/index.php

21. www.wampserver.com/en

22. www.zdnet.com/blog/carroll/ajax-vs-desktop-development/1519

23. www.prologue.ro/blog-Web-design/flash-vs-html-5/

24. langpop.com/

25. www.phpromania.net/articol/10/Tipuri_de_date_Variabile_Constante_Operatori_

Definire_functii_.html

26. www.herongyang.com/PHP/php_soap.html

27. blog.claudiupersoiu.ro/2009/05/24/

28. www.scottnichol.com/nusoapintro.htm

29. searchsoa.techtarget.com/definition/object-oriented-programming

30. www.w3schools.com/js/js_intro.asp

31. www.tizag.com/ajaxTutorial/ajax-mysql-database.php

Similar Posts