. Aplicatie Web cu Baze de Date, Gestiunea Camerelor Unei Pensiuni

Cuprins

=== l ===

Cuprins

PREZENTAREA TEMEI

Motivația

O prezenta puternica pe Internet a devenit o

necesitate pentru orice firma care se respecta.

Tot mai multi conducatori de firme decid sa

construiasca un site web pentru firma lor.

Datorită implicării tot mai accentuate a calculatoarelor în multe domenii de activitate, sfera problemelor rezolvate cu ajutorul calculatorului s-a extins foarte mult. A apărut astfel o specializare a programelor (pachetelor de programe), orientate spre rezolvarea diverselor tipuri de probleme: matematice, tehnice, economice, de proiectare, de gestiune, etc.

În prezent aproape jumătate de miliard din populația globului are acces la Internet. Site-urile care oferă produse sau servicii sunt într-o continuă creștere. Utilizatorii tind să prefere rezervări on-line datorită comodității de a se folosi de anumite servicii fără efort sau deplasare.

Prin tema „Aplicație web cu baze de date: Gestiunea camerelor unui hotel” se oferă o varietate de posibilități încurajatoare. Sunt flexibile și iți permit să-ți construiești o viziune a programului tău individual, a scopurilor tale și a bugetului.

Aplicația conține două părți : cea de utilizator și cea de administrator.

Utilizatorul :

poate să se informeze despre serviciile și facilitățile oferite de Hotel Imperial.

poate să se înregistreze ca și client al acestui hotel.

poate să opteze pentru un anumit tip de cameră (simplă, dublă, garsonieră, apartament).

după ce și-a ales tipul de cameră o poate închiria începând cu ziua curentă sau o poate rezerva în ce perioadă a anului dorește.

după ce s-a înregistrat poate să activeze meniul de servicii prestate în care sunt prezentate produsele puse la dispoziție, precum și prețul acestora.

se poate informa cu privire la personalul hotelului și persoana de contact.

Administratorul gestionează întreaga bază de date și asigură buna desfășurare a activităților hoteliere. El poate vizualiza care sunt camerele închiriate sau rezervate și clienții înregistrați. El este singurul care are dreptul de a accesa baza de date, modifica sau șterge un client prin intermediul unei parole de administrator.

Obiective

Se urmărește posibilitatea de a vizita site-ul de către orice posibil client.

Posibilitatea de a afla informații despre hotel, personalul hotelului și persoana de contact.

Securitatea și gestionarea bazei de date.

Capitolul 1 – PHP

1.1 Introducere

1.1.1 Începuturile PHP

PHP (PHP: Hypertext Prepocessor), cunoscut în versiunile mai vechi și sub numele de PHP/FI (Personal Homepage/Form Interpreter), inițial a fost gândit a fi o simplă aplicație CGI pentru interpretarea formularelor definite prin HTML și procesate de un program scris într-un limbaj Perl, script shell, executat pe server. În cazul interfeței CGI era necesară permisiunea de a rula programe pe server, ceea ce ducea la lacune în securitate și în plus la disocierea de documentul HTML a programului care procesa datele.

PHP (în versiunea curentă PHP 4.0) reprezintă un pachet puternic care oferă un limbaj de programare accesibil din cadrul fișierelor HTML, limbaj asemănător cu Perl sau C, plus suport pentru manipularea bazelor de date într-un dialect SQL (dBase, Informix, MySQL, mSQL, Oracle, PostgreSQL, Solid, Sybase, ODBC etc.) și acces la sisteme hipermedia precum Hyperwave. De asemeni, PHP suportă incărcarea fișierelor de pe calculatorul client: upload (standard propus de E. Nebel și L. Masinter de la Xerox, descris în RFC 1867) și oferă suport pentru cookies (mecanism de stocare a datelor în navigatorul client pentru identificarea utilizatorilor, propus de Netscape).

Această aplicație este disponibilă gratuit pe Internet, pentru medii Unix și mai nou pentru medii Windows (inclusiv sursele), integrându-se în popularul sever Apache.

Istoria PHP-ului începe la sfârșitul anului 1994, când Rasmus Lerdorf dezvoltă prima versiune, ca proiect personal. PHP-ul este făcut public în debutul anului 1995 sub denumirea de Personal Home Page Tools, fiind considerat un analizor simplist care interpreta câteva macrouri ce puteau fi incluse în cadrul documentelor HTML, permițând contorizarea accesului la paginile Web sau accesarea unei carți de oaspeți (guestbook). Analizorul a fost rescris la mijlocul aceluiași an și denumit PHP/FI 2.0, unde FI era o alta aplicație scrisă de Rasmus Lenford, un interpreter de formulare HTML. A fost adăugat și suportul pentru bazele de date mSQL și astfel PHP/FI a început să aibă succes, fiind disponibil gratuit pe Web. Se estimează că la sfârșitul lui 1996 cel puțin 15 mii de site-uri Web utilizau PHP/FI, iar în anul 1997 numărul acestora era de 50 de mii.

Programatorii Zeev Suraski și Andi Gutmans rescriu analizorul PHP și noua aplicație formează nucleul versiunii PHP 3.0 care include o parte din vechile surse PHP/FI 2.0. Relativ recent, la începutul anului 2000, a fost facută publică versiunea PHP 4.0, utilizând puternicul motor de scriptare Zend și oferind suport nu numai pentru servrul Apache ci și pentru alte servere Web. De asemeni, PHP 4.0 oferă posibilitatea accesării documentelor XML via DOM.

Se estimează că numărul site-urilor care folosesc în prezent PHP este de peste un milion. Deja, pe Web, exista o multitudine de aplicații și utilitare concepute în PHP, care se regăsesc grupate și în așa-numitul PEAR (PHP Extension and Add-on Repository).

1.1.2. Ce este PHP?

PHP este un limbaj de script care funcționează alături de un server Web.

Fie următorul exemplu:

<html>

<head>

<title>Exemple</title>

</head>

<body>

<?php

echo "Salut, eu sunt un script PHP!";

?>

</body>

</html>

Este de notat diferența cu alte limbaje script CGI scrise în limbaje precum Perl sau C: în loc de a scrie un program cu o multitudine de linii de comanda afișate în final într-o pagină HTML, veți scrie o pagină HTML cu codul inclus pentru a realiza o acțiune precisă (în cazul nostru se va afișa un text).

Codul PHP este inclus între tag-urile speciale de început și de sfârșit care permit utilizatorului să treacă din "modul HTML" în "modul PHP".

Față de alte limbaje script, precum Javascript, la PHP codul se execută pe server. Dacă pe serverul Web se află un script similar, clientul nu va primi decât rezultatul execuției scriptului, fără a avea nici o posibilitate de acces la codul care a produs rezultatul. Vă puteți configura serverul de Web să prelucreze (analizeze) toate fișierele HTML ca fișiere PHP. Astfel nu există nici un mijloc de a distinge paginile care sunt produse dinamic de paginile statice.

1.1.3. Ce poate face PHP?

Limbajul PHP posedă aceleași funcții ca alte limbaje permițând să se scrie scripturi CGI, să colecteze date și să genereze dinamic pagini web sau să trimită și să primească cookies.

Marea calitate și cel mai mare avantaj al limbajului PHP este suportul cu un număr mare de baze de date. A realiza o pagină web dinamic cu o baza de date este extrem de simplu. Următoarele baze de date sunt suportate de către PHP:

Limbajul PHP are deasemenea suport pentru diverse servicii server utilizând protocoale precum IMAP, SNMP, NNTP, POP3 și HTTP.

1.2. Initiere in php

1.2.1 Structura limbajului

Sintaxa fundamentală. Trecerea de la HMTL la PHP

Există 4 moduri pentru a trece de la HMTL la PHP:

1. <? echo ( "cea mai simplă cale de introducere…\n"); ?>

2. <?php echo ( "Daca vreți să afișați documente XML sau XHTML faceți ca aici.\n"); ?>

3. <script language="php">

echo ( "Anumite editoare nu acceptă tag-uri necunoscute (de exemplu FrontPage)");

</script>

4. <% echo ( "Puteți utiliza tag-uri în stil Asp."); %>

A doua metodă este cea mai utilizată, pentru că permite o implementare ușoara a PHP-ului cu generația urmatoare XHTML.

Separatori de instrucțiuni

Instrucțiunile sunt separate, ca în C sau ca în Perl, prin punct și virgulă la sfârșitul unei instrucțiuni. Semnele de sfârșit, '?>', implică sfârșitul instrucțiunii, deci implicit punct și vigulă.

Exemplu:

<?php

echo "Acesta este un test";

?>

<php echo "Acesta este un alt test" ?>

Comentarii

Comentariile pot fi făcute în stilul celor din limbajele C, C++ și shell-urile UNIX (bash de exemplu).

Exemplu:

echo "Acesta este un test"; // Acesta este un comentariu pe o linie în stilul C++

/* Acesta este un comentariu pe mai multe linii;

încă o linie de comentariu */

echo "Acesta este un alt test";

echo "Ultimul test"; # Un comentariu în stil Unix

Stilul de comentariu pe o linie ține până la sfârșitul liniei sau al blocului curent al codului PHP.

<h1>Acesta este un <? # echo "simplu"; ?> exemplu.</h1>

<p>Linia de mai sus va afisa: "Acesta este un exemplu."</p>

1.3. Tipuri de date

1.3.1 Numere întregi

Numerele întregi se pot specifica în modul următor:

$a = 1234; # Număr întreg în baza 10

$a = -123; # Număr întreg negativ

$a = 0123; # Număr întreg în baza 8, octal (echivalent cu 83 în baza 10)

$a = 0x12; # Număr întreg în baza 16, hexazecimal (echivalent cu 18 în baza 10)

1.3.2 Numere reprezentate în virgulă mobilă

Numerele reprezentate în virgulă mobilă (double) pot fi utilizate în oricare din sintaxele următoare:

$a = 1.234;

$a = 1.2e3;

Dimensiunea numerelor în virgulă mobilă este independentă de platformă. Precizia uzuală este de 14 cifre.

Observații:

De obicei fracțiile zecimale simple, precum 0.1 sau 0.7, sunt convertite intern cu o mică pierdere de precizie; aceasta poate să ducă la rezultate mai puțin exacte. De exemplu: floor( 0,1 + 0,7*10) întoarce de obicei 7 în loc de așteptatul 8, rezultatul reprezentării interne fiind de genul 7,9999999999;

Este imposibil să se exprime cu exactitate fracțiile zecimale cu număr infinit de cifre; de exemplu, 1/3 în formă zecimală devine 0,33333333…;

Dacă aveți nevoie de o precizie mai mare în compararea valorilor în virgulă mobilă trebuie să utilizați funcțiile matematice de precizie arbitrară.

1.3.3. Șiruri de caractere

Șirurile de caractere pot fi delimitate de ghilimele sau apostrofuri, în ultimul caz inhibându-se evaluarea variabilelor din interiorul șirului respectiv (exact ca la bash).

Dacă șirul de caractere este delimitat de ghilimele atunci variabilele din interiorul șirului vor fi evaluate și înlocuite prin valoarea lor. Ca și în C sau Perl, caracterul backslash (\) este utilizat pentru a proteja un carcater special.

Orice caracter se poate transforma, teoretic, în secveță escape, dar se produce un avertisment la cel mai înalt nivel. A doua metodă încadrează șirurile între apostrofuri; în acest caz singurele secvențe escape înțelese sunt '\\' și '\'. Variabilele nu vor fi expandate într-un șir încadrat între apostrofuri. O altă metodă de a delimita șirurile este folosirea sintaxei doc '<<<'. După acest delimitator trebuie specificat un identificator, apoi șirul de caractere propriu-zis și, în încheiere, același identificator care a precedat șirul.

Șirurile pot fi concatenate utilizând operatorul '.', operatorul '+' fiind impropriu pentru această operație.

1.3.3.1 Conversia șirurilor

Când un șir este evaluat ca valoare numerică, valoarea și tipul rezultat sunt decise după cum urmează:

– șirul va fi evaluat ca un double dacă conține unul din caracterele '.', 'e' sau 'E'. Altfel va fi evaluat ca un întreg;

– valoarea este dată de începutul șirului. Dacă șirul începe cu o dată numerică validă, aceasta va fi valoarea utilizată. Altfel valoara va fi 0. O dată numerică validă este formată din semn (opțional), una sau mai multe cifre (opțional un puct zecimal), încheiate eventual cu un exponent. Acest exponent ('e' sau 'E') este urmat de una sau mai multe cifre. Când prima expresie este un șir tipul varibilei va depinde de a doua expresie.

Exemplu:

$aaa = 1 + "10.5"; // $aaa este double (11.5)

$aaa = 1 + "-1.3e3"; // $aaa este double (-1299)

$aaa = 1 + "bob-1.3e3"; // $aaa este integer (1)

$aaa = 1 + "bob3"; // $aaa este integer (1)

$aaa = 1 + "10 Small Pigs"; // $aaa este integer (11)

$aaa = 1 + "10 Little Piggies"; // $aaa este integer (11)

$aaa = "10.0 pigs" + 1; // $aaa este double (11)

$aaa = "10.0 pigs" + 1.0; // $aaa este double (11)

1.3.4. Tablouri

În PHP tablourile se comportă și ca tablouri asociative (hash tables) și ca tablouri indexate (vectori).

1.3.4.1. Tablouri unidimensionale

PHP acceptă atât tablouri scalare cât și asociative. De fapt nu există nici o diferență între cele două. În PHP tabolurile se pot crea utilizând funcțiile list() și array() sau se poate seta explicit fiecare element din tablou.

Exemplu:

$a[0] = "abc";

$a[1] = "def";

$b["aaa"] = 13;

Se poate de asemenea crea un tablou adăugându-i valori. De exemplu, putem extinde tabloul $a ca în exemplul de mai jos:

$a[] = "hello";

// $a[2] == "hello"

$a[] = "world";

// $a[3] == "world"

Vectorii pot fi sortați utilizând funcții specializate: asort(), arsort(), ksort(), rsort(), sort(), uasort(), usort(), și uksort().

Puteți număra elementele tabloului utilizând funcția count().

Puteți parcurge un tablou utilizând funcțiile next(), prev() și each().

1.3.4.2 Tablouri multidimensionale

Tablourile multidimensionale sunt în realitate tablouri simple. Pentru fiecare dimensiune a tabloului trebuie adăugată o altă dimensiune [dim] la final.

<?php

$a[1] = $f; // Tablou unidimensional

$a["aaa"] = $f; // Tablou unidimensional

$a[1][0] = $f; // Tablou bidimensional

$a["aaa"][2] = $f; // Indicii asociativi și numerici se pot combina

$3[3]["bar"] = $f; // Indicii numerici și asociativi se pot combina

$a["aaa"][4]["bar"][0] = $f; // Tablou cu patru dimensiuni

?>

În PHP nu este posibilă referirea tablourilor multidimensionale direct într-un șir.

1.3.5 Obiecte

Pentru a crea o variabilă de tipul obiect dorit, și eventual pentru a o inițializa, se folosește operatorul new:

class aaa

{

function do_aaa()

{

echo "Doing aaa.";

}

}

$bar = new aaa;

$bar->do_aaa();

1.3.6 Conversia automată a tipurilor

PHP nu acceptă definirea explicită a tipului în definirea variabilelor, tipul unei variabile fiind determinat de contextul în care acea variabilă este utilizată. Acesta înseamnă că dacă atribuiți variabilei var un șir de caractere, var va deveni șir. Dacă îi atribuiți o valoare întregă, var va deveni un întreg.

Un exemplu de conversie automată a tipului apare la utilizarea operatorului '+'. Dacă vre-un operand este double, atunci toți operanzii sunt evaluați la double, și rezultatul va fi un double. Altfel, operanzii vor fi interpretați ca întregi și rezultatul va fi tot un întreg. Rețineți că acest mod de evaluare nu modifică tipul operanzilor care intervin în expresie, ci numai modul în care ei sunt evaluați.

Exemplu:

$bbb = "0"; // $bbb este șir de caractere (ASCII 48)

$bbb++; // $bbb este șirul de caractere "1" (ASCII 49)

$bbb += 1; // $bbb este acum de tip întreg (2)

$bbb = $bbb + 1.3; // $bbb este acum de tip double (3.3)

$bbb = 5 + "10 Little Piggies"; // $bbb este de tip înreg (15)

$bbb = 5 + "10 Small Pigs"; // $bbb este de tip întreg (15)

Observație: conversia automată de la un tip simplu la tipul tablou este uzual nedefinită.

1.3.7 Conversia explicită a tipurilor

Conversia explicită a tipurilor (cast) se face în același mod ca în C: numele tipului dorit este scris în paranteze înaite de numele variabilei.

$a = 10; // $a este un întreg

$bar = (double) $a; // $bar este un double

Conversiile permise sunt:

(int), (integer) – conversia la întreg

(real), (double), (float) – conversie la double

(string) – conversie la șir

(array) – conversie la tablou

(object) – conversie la obiect

Observați că eticheta și spațiile sunt permise între paranteze, deci liniile următoare sunt echivalente:

$a = (int) $bar;

$a = ( int ) $bar;

$a = (int)$bar;

Este posibil ca rezultatul conversiei explicite între două tipuri să nu fie evident.

De exemplu convertind un scalar sau un șir de caractere la tipul array, respectiva variabilă va deveni primul element al tabloului ca în exemplul de mai jos:

$var = 'ciao';

$arr = (array) $var;

echo $arr[0]; // Afișează ciao

Când convertiți un scalar sau o variabilă de tip șir de caractere la un obiect, respectiva variabilă va deveni un atribut al obiectului, atribut numit scalar.

Exemplu:

$var = 'ciao';

$obj = (object) $var;

echo $obj->scalar; // Afișează ciao

1.4 Variabile

1.4.1 Reprezentarea varibilelor

Variabilele în PHP sunt reprezentate de semnul dolar, '$', în fața numelui variabilei. Numele variabilelor sunt formate după aceleași reguli ca alte etichete din PHP. Un nume de variabilă valid trebuie să înceapă printr-o literă sau liniuță de subliniere, '_', urmată de un șir de litere, cifre sau liniuțe de subliniere.

PHP este un limbaj case-senzitiv.

Exemplu:

$var = "Jean";

$Var = "Paul";

echo "$var, $Var"; // Afișează Jean, Paul

$4site = 'nu încă'; // Incorect: începe printr-o cifră

$_4site = 'nu încă'; // Corect: începe printr-o liniuță de subliniere

$maïs = 'jaune'; // Corect: 'ï' este ASCII 239

În PHP 3, variabilele sunt asignate întotdeauna prin valoare. Astfel, când atribuim unei variabile o expresie, întreaga valoare a expresiei este copiată în variabila destinație. Aceasta înseamnă, de exemplu, că atribuind unei variabile valoarea altei variabile, modificarea unei variabile nu va avea efect asupra celeilalte.

PHP 4 aferă și un alt mod pentru atribuirea de valori variabilelor: prin referință. Aceasta înseamnă că noua variabilă nu face decât să refere variabila originală (cu alte cuvinte, "devine un alias pentru" sau "pointeză la" variabila originală). În acest caz, cele două variabile sunt interdependente, modificarea uneia determinând modificarea celeilalte. Deoarece nu are loc copierea și actualizarea valorilor, asignarea prin referință este mai rapidă. Diferența devine notabilă în cazul execuțiilor repetate sau la asignarea tablourilor mari, respectiv a abiectelor.

Pentru a atribui prin referință, se introduce un ampersand, '&', în fața variabilei care este atribuită (variabila sursă). În exemplul următor, Numele meu este Pierre se va afișa de două ori:

$aaa = 'Pierre'; // Atribui valoarea Pierre lui $aaa

$bar = &$aaa; /* Atribuire prin referință;

$aaa și $bar referă aceeași locație de memorie */

$bar = "Numele meu este $bar"; // Modific $bar , deci inmplicit și $aaa

echo $aaa;

echo $bar;

Observație: numai variabilele pot fi asigante prin referință.

Exemplu:

$a = 25;

$bar = &$a; // Atribuire posibilă

$bar = &( 24 * 7); // Atribuire eronată: referința unei expresii fără nume

function test()

{

return 25;

}

$bar = &test(); // Incorect: funcția returnează o valoare, nu o variabilă

1.4.2 Variabile predefinite

PHP furnizează un mare număr de variabile predefinite pentru fiecare script pe care îl rulează. Cele mai multe variabile predefinite depind de serverul pe care se lucrează, de versiunea și configurarea serverului sau de alți factori. Unele dintre aceste variabile nu vor fi disponibile când PHP rulează într-o linie de comandă.

1.4.3 Domeniul variabilelor

Domeniul variabilelor este contextul în care variabila este definită. Pentru marea parte a variabilelor, domeniul lor este unic. Acest domeniu se referă și la fișierele incluse într-un script.

Este o diferență între modul de stabilire a domeniului variabilelor globale în C și PHP: în absența unei referiri locale, variabilele globale din C sunt valabile în orice funcție a programului. Acest lucru nu este valabil și în PHP.

A doua modalitate de a accesa variabilele din domeniul global este prin utilizarea variabilei tablou din PHP, numită $GLOBALS.

Variabila $GLOBALS este un tablou asociativ care are drept indice numele variabilelor globale și conținutul respectivelor variabile drept elemente.

Un alt aspect important legat de domeniul variabilelor se referă la variabilele statice.

O variabilă statică există numai în domeniul unei funcții dar nu își pierde valoarea când execuția programului părăsește acest domeniu.

Variabilele statice oferă de asemeni posibilitatea de a implementa și funcțiile recursive. O funcție este recursivă dacă se autoapelează. Proiectarea funcțiilor recursive trebuie făcută cu atenție pentru a evita recursia infinită. Trebuie asigurată o modalitate adecvată de încheiere a apelurilor recursive.

1.4.4 Variabile variabile

Uneori este convenabil să lucrăm cu nume de variabile ce pot fi tratate în mod dinamic. O variabilă variabilă este un nume de variabilă care poate fi inițializată și utilizată în mod dinamic. O variabilă normală este setată printr-o instrucțiune de forma:

$a = "hello";

O variabilă variabilă primește valoarea unei alte variabile și o tratează ca și cum ar fi un nume de variabilă. În exemplul următor valoarea hello atribuită anterior poate fi tratată ca un nume de variabilă utilizând de două ori semnul dolar:

$$a = "world";

În acest moment două variabile au fost definite și memorate în tabela de simboluri PHP: $a conținând "hello" și $hello conținând șirul "world". Astfel instrucțiunea:

echo "$a $($a)";

produce aceeași ieșire ca și instrucțiunea:

echo "$a $hello";

adică șirul hello world.

Pentru a utiliza variabilele variabile cu tablouri, trebuie rezolvată o problemă de ambiguitate. Astfel, dacă scriem $$a[1], trebuie să precizăm dacă dorim să utilizăm $a[1] ca variabilă sau $$a și apoi să indexăm cu [1] această variabilă. Pentru a rezolva această ambiguitate vom folosi sintaxa ${$a[1]} pentru primul caz și ${$a}[1] pentru al doilea caz.

1.5. Constante

PHP definește o serie de constante și oferă un mecanism pentru definirea altora în timpul execuției. Constantele seamănă mult cu variabilele; sunt definite cu jutorul funcției define() și valoarea lor nu poate fi modificată ulterior. Constantele predefinite (disponibile întotdeauna) sunt :

__FILE__

Se utilizează cu un fișier care a fost inclus sau solicitat, când numele fișierului inclus este dat;

__LINE__

Numărul liniei din scriptul curent care este analizat. Se utilizează împreună cu un fișier care a fost inclus sau solicitat, când poziția în fișierul inclus este dată;

PHP_VERSION

Un șir de caractere reprezentând versiunea PHP utilizată;

PHP_OS

Numele sistemului de operare în care rulează PHP;

TRUE

O valoare adevărată;

FALSE

O valoare falsă;

E_ERROR

Indică o eroare, alta decât o eroare de analizare, pentru care corectarea nu este posibilă;

E_WARNING

Indică o situație în care PHP știe că ceva este greșit, dar continuă oricum;

E_PARSE

Semnalează o sintaxă invalidă în fișierul script; corectarea nu este posibilă;

E_NOTICE

S-a întâmplat ceva care poate fi sau nu o eroare; execuția continuă. Spre exemplu am accesat o variabilă care nu a fost inițializată sau am folosit un șir neîncadrat între ghilimele ca index asociativ.

Puteți defini constante suplimentare utilizând funcția define(). Rețineți că aceste constante nu se comportă ca macro-urile C; numai datele scalare valide pot fi reprezentate printr-o constantă.

1.6. Expresii

Expresiile sunt cele mai importante construcții ale PHP; în PHP aproape orice scrieți este o expresie. Cea mai simplă și corectă modalitate de a defini o expresie este orice are o valoare. Cele mai simple expresii sunt constantele și variabilele.

PHP acceptă 3 tipuri de valori scalare: valori întregi, valori în virgulă mobilă și valori tip șir de caractere (valorile scalare sunt acele valori indivizibile spre deosebire de valorile array, de exemplu). PHP acceptă de asemeni două tipuri compuse: array și object (tablouri și obiecte). Valorile de acest tip pot fi atribuite variabilelor sau returnate de către funcție.

PHP este un limbaj orientat pe expresii în sensul că aproape orice este o expresie. Operatorii de pre și postincrementare funcționează analog cu cei din C. Un tip uzual de expresii îl reprezintă expresiile de comparare. Aceste expresii sunt evaluate la 0 sau 1 reprezentând FALSE, respectiv TRUE.

PHP acceptă operatorii de comparație >, >=, ==, != (diferit), <, <=. Aceste expresii sunt utilizate uzual în construirea condițiilor. Ca și în C se pot folosi operatorii de atribuire compuși. În afară de faptul că utilizarea acestor operatori compuși duce la scurtarea codului, și execuția este mai rapidă. De asemeni, PHP acceptă operatorul ternar condițional '?', cu aceeași semnificație ca și în C.

Limbajul PHP nu dispune de un tip logic predefinit. Evaluarea valorii de adevăr a expresiilor PHP se face la fel ca în C și Perl: orice valoare numerică nenulă este TRUE, zero este FALSE. Un șir vid este FALSE, orice alt șir este TRUE. În cazul tablourilor și obiectelor orice valoare care nu conține elemente este considerată FALSE, altfel este considerată TRUE.

1.7. Operatori

1.7.1 Operatori aritmetici

Operatorul de împărțire ('/') întoarce o valoare întreagă (rezultatul împărțirii întregi) dacă cei doi operatori sunt întregi (sau dacă șirurile sunt convertite la întregi). Dacă unul din operatori este număr cu virgulă mobilă, sau rezultatul unei operații returnează o valoare care nu este întreagă, va fi returnată o valoare în virgulă mobilă.

1.7.2 Operatori de atribuire

Operatorul de atribuire simplă este '='. Are semnificația: valoarea expresiei din dreapta se atribuie variabilei din stânga (variabilă simplă sau structurată).

Putem spune că instrucțiunea de atribuire este formată din trei elemente: expresia care urmează să fie atribuită, operatorul de atribuire '=' și variabila destinatară.

Când este executată instrucțiunea de atribuire, este evaluată expresia și valoarea rezultată este depusă la destinația specificată.

În operațiile aritmetice și pe șiruri de caractere se pot folosi și operatorii compuși.

De remarcat că atribuirea se face prin copiere, adică expresia din dreapta nu se modifică în urma atribuirii. PHP4 acceptă și atribuirea prin referință, utilizând sintaxa $var = &$othervar;, dar acest lucru nu este posibil în PHP3. Atribuirea prin referință înseamnă că cele două variabile referă aceeași locație de memorie și că modificarea uneia dintre ele o afectează și pe cealaltă.

1.7.3 Operatori pe biți

Operatorii pe biți vă permit să manipulați numerele întregi în reprezentare binară.

1.7.4 Operatori de comparație

Operatorii de comparație permit compararea a două valori.

Un alt operator condițional este operatorul ternar ('?:'), care funcționează ca în C.

( expr1) ? ( expr2) : ( expr3);

Această expresie returnează expresia expr2 dacă expr1 este adevarată și expresia expr3 dacă expresia expr1 este falsă.

1.7.5 Operatori de control al erorilor

PHP are un operator de control al erorilor și anume '@'. Când acest operator precede o expresie în PHP, orice eroare care poate fi generată va fi ignorată. Dacă opțiunea track_errors este activată, mesajele de eroare generate de expresie vor fi salvate în variabila globală $php_errormsg. Această variabilă va fi rescrisă la fiecare eroare, deci verificați-o la timp dacă doriți să o utilizați.

Exemplu:

/* Eroare SQL intenționată (apostrofuri suplimentare) */

$Query_nume_prenume = @ mysql_query ("select CNP, Nume,Prenume from clienti") or

die( "Query failed: error was '$php_errormsg'.");

1.7.6. Operatori de execuție

PHP are un operator de execuție '„' (backticks). Este diferit de ghilimelele simple.

PHP va încerca să execute conținutul dintre aceste ghilimele oblice ca o comandă shell. Rezultatul va fi returnat (nu va fi descărcat pur și simplu, ci va putea fi atribuit unei variabile).

1.7.7. Operatori de incrementare/decrementare

PHP dispune de operatori de incrementare/decrementare ca și limbajul C.

1.7.8 Operatori logici

Operatorii logici sunt:

Motivul pentru care există două tipuri de 'ȘI' și 'SAU' este că ele au priorități diferite.

1.7.9 Precedența operatorilor

Precedența operatorilor specifică ordinea în care se aplică operatorii. De exemplu, în expresia 1 + 5 * 3 rezultatul este 16 și nu 18, căci înmulțirea ('*') are prioritate superioară în raport cu adunarea ('+').

Tabelul următor conține operatorii disponibili în PHP în ordinea crescătoare a priorităților.

1.7.10 Operatori pentru șiruri de caractere

Există doi operatori de șir. Primul este operatorul de concatenare ('.'), care are ca rezultat concatenarea celor două argumente. Cel de-al doilea operator este operatorul de atribuire ('.='), care concatenează argumentul din partea dreaptă la argumentul din partea stângă.

1.8 Crearea formularelor HTML

Majoritatea programelor PHP folosesc formulare HTML pentru a prelua datele de la utilizator și pentru a afișa rezultatele calculelor, în cadrul acestui modul, veți învăța să creați formulare HTML care permit programelor dumneavoastră HTML să interacționeze cu utilizatorul.

1.8.1 Crearea structurii HTML

Structura HTML pe care o folosiți pentru a include un formular nu este deloc diferită, de fapt, de cea folosită pentru includerea unei pagini HTML obișnuite. De exemplu, iată o structură caracteristică:

<HTML>

<HEAD>

<TITLE>Gestiunea camerelor unui hotel</TITLE>

</HEAD>

<BODY>

Conținutul paginii sau al formularului este inserat aici

</BODY>

</HTML>

In interiorul corpului unei pagini HTML care conține un formular puteți folosi orice etichetă HTML obișnuită. Pentru a descrie formularul în sine, folosiți eticheta FORM, care are următoarea formă elementară:

<FORM METHOD="metoda" ACTION="url">

Atributul METHOD al etichetei FORM poate lua una din valorile GET sau POST. Pentru moment, specificați întotdeauna valoarea POST. Atributul ACTION specifică adresa URL a scriptului PHP care prelucrează datele adunate prin intermediul formularului. Adresa URL poate fi o adresă completă, care include protocolul, numele gazdei și calea de acces, respectiv o adresă parțială, care specifică o locație relativă la locația paginii curente, între eticheta FORM si eticheta sa /FORM corespunzătoare, plasați controalele formularului.

1.8.2. Încorporarea controalelor

Această sub-secțiune descrie două controale elementare pe care le veți folosi frecvent: caseta cu text și butonul de expediere.

O casetă cu text permite utilizatorului să tasteze informații care pot fi apoi trimise unui script PHP. Casetele cu text sunt frecvent folosite pentru a obține date precum numele utilizatorului, adresa sa poștală sau adresa de e-mail. Pentru a crea o casetă cu text, scrieți o etichetă HTML care are următoarea formă elementară:

<INPUT TYPE="TEXT" NAME="text">

Atributul NAME atribuie casetei cu text un nume, astfel încât conținutul său să fie accesibil unui script PHP. Numele pe care îl atribuiți unui control trebuie să fie unic în cadrul formularului și trebuie să respecte regulile pentru denumirea variabilelor PHP, cu excepția faptului că numele nu trebuie să înceapă cu simbolul dolarului. Cu alte cuvinte, numele trebuie să înceapă cu o literă si nu trebuie să conțină alte caractere în afara literelor, a cifrelor și a caracterelor de subliniere; în particular, numele nu trebuie să conțină spații. HTML nu are o etichetă /INPUT, deci nu încercați să combinați o etichetă INPUT cu o asemenea etichetă.

Un buton de expediere permite utilizatorului să trimită serverului conținutul unui formular. Fiecare formular HTML trebuie să aibă un buton de expediere. Pentru a crea un buton de expediere, scrieți o etichetă HTML care are următoarea formă elementară:

<INPUT TYPE="SUBMIT" VALUE="text">

Atributul VALUE specifică textul care trebuie să apară pe suprafața butonului de expediere.

Iată un formular HTML complet, care include casete cu text ce preiau numele și prenumele utilizatorului:

<html>

<head>

<title>Gestiune camere hotel</title>

</head>

<body>

<form method=post action=login.php>

<table width="18%" border="1" cellspacing="0" cellpadding="0" align="center" >

<tr>

<td><strong>Utilizator </strong></td>

<td><input name="utilizator" type="text"></td>

</tr>

<tr>

<td><strong>Parola</strong></td>

<td><input name="parola" type="password"></td>

</tr>

<tr>

<td><input type="submit" name="Submit" value="Intra"></td>

<td>&nbsp;</td>

</tr>

</table>

Când utilizatorul execută clic pe butonul de expediere, datele introduse de utilizator sunt trimise scriptului login.php. Ilustrația alăturată prezintă aspectul formularului.

1.8.3 Crearea controalelor formularului

Crearea casetelor cu text personalizate

Secțiunea precedentă a prezentat sintaxa elementară pentru crearea unei casete cu text. Cu toate acestea, HTML furnizează numeroase atribute suplimentare care vă permit să modificați aspectul și comportamentul unei casete cu text. Iată sintaxa completă pentru crearea unei casete cu text:

<INPUT TYPE=”TEXT” NAME=”text” SIZE=”numar” MAXLENGTH=”numar” value=”text”>

Atributele TYPE și NAME sunt obligatorii; celelalte atribute sunt opționale. Atributul SIZE, care este dat sub forma unui număr de caractere, stabilește dimensiunea vizibilă a casetei cu text; atributul MAXLENGTH specifică numărul maxim de caractere pe care utilizatorul are permisiunea de a le tasta. Valoarea atributului MAXLENGTH o poate depăși pe aceea a atributului SIZE, în care caz conținutul controlului defilează spre dreapta atunci când utilizatorul a introdus SIZE caractere. Atributul VALUE constituie o valoare care este afișată inițial în caseta cu text.

Crearea de suprafețe cu text

O casetă cu text permite utilizatorului să introducă o singură linie. Iată sintaxa pentru crearea unei suprafețe cu text:

<TEXTAREA NAME=”text” ROWS=”numar” COLS=”numar” WRAP=”wrap”>

Atributele NAME și ROWS sunt obligatorii; atributele COLS și WRAP sunt opționale. Atributul ROWS specifică numărul liniilor de text vizibile în suprafața cu text; deoarece suprafața de text defilează după ce a fost umplută, utilizatorul poate introduce linii suplimentare. Atributul COLS specifică numărul coloanelor de text vizibile în suprafața cu text; deoarece suprafața cu text se derulează sau se înfășoară după ce s-a umplut, utilizatorul poate introduce linii mai lungi. Atributul WRAP specifică maniera de înfășurare a textului în interiorul suprafeței cu text.

Crearea casetelor cu parolă

Dacă o aplicație impune unui utilizator să introducă o parolă, puteți crea o casetă cu text în acest scop. Totuși, când utilizatorul introduce parola, orice persoană aflată în apropiere poate vizualiza parola, situație care duce la o posibilă breșă de securitate, în loc de a se folosi o casetă cu text pentru introducerea de informații confidențiale, trebuie să folosiți o casetă cu parolă. Pentru a crea o casetă cu parolă, folosiți aceeași sintaxă ca și cea utilizată pentru crearea unei casete cu text, cu excepția faptului că specificați PASSWORD (parolă) în loc de TEXT ca valoare a atributului TYPE:

<INPUT TYPE=”PASSWORD” NAME=”text” SIZE=”numar” MAXLENGTH=”numar” VALUE=”text”>

Atributele unei casete cu parolă au aceeași semnificație ca și acelea ale unei casete cu text.

Crearea casetelor de validare

Pentru date care pot avea numai una din două valori, cum ar fi „pornit" sau „oprit", caseta de validare este controlul ideal.

Pentru a crea o casetă de validare, folosiri următoarea sintaxă:

<INPUT TYPE=”CHECKBOX” NAME=”text” CHECKED VALUE=”text”>

Atributul TYPE este obligatoriu; atributele NAME, CHECKED și VALUE sunt opționale. Dacă atributul CHECKED apare, caseta de validare va fi selectată în mod prestabilit; în caz contrar, caseta de validare nu este selectată inițial. Atributul VALUE specifică valoarea care este trimisă serverului în cazul în care caseta de validare este selectată; dacă atributul nu este specificat, se va trimite valoarea on (activat).

Crearea butoanelor radio

Ca și casetele de validare, butoanele radio pot avea numai una din două valori. Cu toate acestea, butoanele radio sunt organizate în grupuri, iar la un moment dat poate fi activat un singur buton radio din cadrul unui grup; toate celelalte trebuie să fie dezactivate. Butoanele radio sunt utile pentru a permite unui utilizator să aleagă dintr-o serie de alternative mutual exclusive.

Pentru a crea un buton radio, folosiți următoarea sintaxă:

<INPUT TYPE=”RADIO” NAME=”text” CHECKED VALUE=”text”>

Rețineți că aceasta este aceeași sintaxă folosită pentru crearea unei casete de validare, cu deosebirea că atributul TYPE are valoarea RADIO în locul valorii CHECKBOX. Atributele unui buton radio au aceeași semnificație ca și acelea ale unei casete de validare. Totuși, atributul NAME este obligatoriu pentru butoanele radio, chiar dacă este opțional pentru casetele de validare. Toți membrii unui set de casete de validare prezintă aceeași valoare a atributului NAME.

Crearea de selecții

O selecție este un meniu care defilează, de unde utilizatorul poate alege una sau mai multe opțiuni.

Pentru a crea o selecție, folosiți următoarea sintaxă:

<SELECT NAME=”text” MULTIPLE SIZE=”numar”> etichetele OPTION se inserează aici</SELECT>

Eticheta SELECT este folosită în combinație cu eticheta /SELECT, între cele două etichete este inclusă o serie de etichete OPTION.

Într-o etichetă SELECT, numai atributul NAME este obligatoriu. Atributul MULTIPLE arată că utilizatorul poate alege mai multe opțiuni menținând apăsată tasta CTRL și executând clic pe acestea. În absența atributului MULTIPLE, utilizatorul poate selecta o singură opțiune. Dacă specificați atributul MULTIPLE, trebuie să specificați și un atribut NAME, care atribuie un nume de tablou ca nume al controlului.

Pentru a crea o opțiune care urmează a fi utilizată în cadrul unei selecții, folosiți următoarea sintaxă:

<OPTION SELECTED VALUE=”text”>conținutul opțiunii este inserat aici</OPTION>

Eticheta OPTION este combinată cu o etichetă /OPTION. Textul dintre aceste etichete este cunoscut sub numele de conținut al opțiunii. Conținutul opțiunii apare în controlul SELECT.

Crearea câmpurilor ascunse

Uneori este utilă crearea așa-numitelor câmpuri ascunse. Valorile câmpurilor ascunse sunt trimise la server alături de valorile altor controale; cu toate acestea, utilizatorul nu are posibilitatea de a vizualiza sau manipula valorile câmpurilor ascunse.

<INPUT TYPE=”HIDDEN” NAME=”text” VALUE=”text”>

Numai atributele TYPE și NAME sunt obligatorii; cu toate acestea, controlul este practic inutil în absența atributului VALUE, a cărui valoare este trimisă în mod automat la server în momentul expedierii formularului.

1.9 Structuri de control

Toate scripturile PHP sunt o suită de instrucțiuni. O instrucțiune poate fi o atribuire, un apel de funcție, o instrucțiune condițională sau chiar o instrucțiune vidă. O instrucțiune se termină de obicei prin punct și virgulă, ';'. Instrucțiunile pot fi grupate în blocuri delimitate de acolade, '{}'. Un bloc este considerat ca o instrucțiune. Diferitele tipuri de instrucțiuni sunt descrise în capitolul următor.

1.9.1 if

Instrucțiunea if este importantă în toate limbajele, inclusiv în PHP. Ea permite execuția condiționată a unei părți de cod. Sintaxa instrucțiunii if este aceeași ca și în C:

if( expresie)

{

listă de instrucțiuni

}

Cum am văzut în paragraful care se referă la expresii, expresie este evaluată la o valoare de adevăr. Dacă expresia expresie este TRUE, PHP va executa instrucțiunile din lista de instrucțiuni, iar dacă ea este FALSE, instrucțiunile vor fi ignorate.

Exemplu:

if ($data_valida)

echo "Data este valida";

Dacă dorim ca un grup de instrucțiuni să fie executate condiționat, este suficient să închidem aceste instrucțiuni între acolade pentru a forma un bloc.

Exemplu:

if (mysql_num_rows($rInchirieri) == 0)

{

$camereOcupate[]=0;

}

Instrucțiunile if pot fi imbricate pe oricâte niveluri dorim obținându-se o structură condițională extrem de flexibilă.

1.9.2 else

Dacă dorim să executăm două instrucțiuni diferite în funcție de valoarea de adevăr a unei expresii vom folosi o instrucțiune if-else ca în exemplul următor:

if (mysql_num_rows($result) >0)

return true;

else

return false;

Instrucțiunile de după else sunt executate doar dacă expresia condițională este evaluată la FALSE.

1.9.3 elseif

Așa cum sugerează numele, este o combinație a instrucțiunilor if și else. Ca și else, instrucțiunea elseif extinde o instrucțiune if pentru a executa alte instrucțiuni în cazul în care expresia condițională din if este FALSE. Spre deosebire de else, instrucțiunea alternativă va fi executată doar dacă expresia condițională din elseif este TRUE.

Instrucțiunile elseif se pot imbrica pe mai multe niveluri, după un if inițial. Primul elseif care va fi evaluat la TRUE va fi executat. În PHP, instrucțiunea poate fi scrisă și în două cuvinte: else if. Comportamentul său va fi același.

1.9.4 Sintaxa alternativă

PHP propune o sintaxa alternativă pentru instrucțiunile de control if, while, for și switch. În fiecare caz principiul este de a înlocui acolada deschisă cu două puncte (':') și acolada închisă prin, respectiv endif;, endwhile;, endfor;, sau endswitch;.

Această sintaxă funcționează de asemenea cu else și elseif.

1.9.5 while

Bucla while este cea mai simplă implementare a unei bucle în PHP. Această buclă se comportă la fel ca în C. Sintaxa instrucțiunii while este:

while( expresie)

{

listă de instrucțiuni

}

Execuția unei bucle while este foarte simplă. PHP execută instrucțiunile din lista de instrucțiuni atât timp cât expresia buclei while, expresie, este evaluată la TRUE. Valoarea expresiei este verificată la fiecare început al buclei și, dacă valoarea se schimbă pe durata execuției instrucțiunilor, execuția nu se va sfârși decât la următoarea iterație (de fiecare dată când PHP execută instrucțiunile are loc o iterație). Dacă expresia buclei while este FALSE înaintea primei interații, instrucțiunea nu va fi niciodată executată.

Mai multe instrucțiuni pot fi executate într-o buclă while grupându-le între acolade pentru a forma un bloc sau utilizând sintaxa alternativă după modelul de mai jos:

while( expresie):

listă de instrucțiuni

endwhile;

1.9.6 do..while

Buclele do..while seamănă mult cu buclele while, dar expresia condițională este testată la sfârșitul fiecarei iterații și nu la început. Principala diferență față de bucla while este că prima iterație a buclei do..while este întotdeauna executată (expresia nu este testată decât la sfârșitul iterației). Nu există decât o sintaxă posibilă pentru buclele do..while:

do

{

listă de instrucțiuni

}while( expresie);

Utilizatorii familiari cu C sunt obișnuiți să utilizeze în mod diferit buclele do..while, care permite oprirea execuției buclei, prin introducerea instrucțiunii break într-o buclă do..while.

1.9.6 for

Buclele for sunt cele mai complexe bucle în PHP. Ele funcționează la fel ca buclele for din limbajul C.

Instrucțiunea are următoarea sintaxă:

for( expr1; expr2; expr3)

{

listă de instrucțiuni

}

Prima expresie (expr1) este evaluată (executată) o singură dată, necondiționat, la începutul buclei.

La începutul fiecărei iterații, expresia expr2 este evaluată. Dacă evaluarea devine TRUE, bucla continuă și instrucțiunile din lista de intrucțiuni sunt executate. Dacă evaluarea devine FALSE, execuția buclei se oprește.

La sfârșitul fiecărei iterații, expresia expr3 este evaluată (executată).

Expresiile pot fi eventual vide. Dacă expresia expr2 este vidă, înseamnă că bucla este infinită (PHP consideră implicit că expresia expr2 este TRUE, ca în C). Acest lucru poate fi util, mai ales când dorim să terminăm bucla cu instrucțiunea break.

De asemeni, PHP folosește următoarea sintaxă alternativă pentru buclele for:

for( expr1; expr2; expr3):

listă de instrucțiuni

endfor;

1.9.7 foreach

PHP4 (nu și PHP3) dispune de comanda foreach, ca Perl sau alte limbaje. Instrucțiunea oferă un mod simplu de a trece în revistă un tablou. Există două sintaxe posibile, a doua este o mică, dar utilă, extensie a celei dintâi :

foreach( array_expresion as $value)

{

listă de instrucțiuni

}

foreach( array_expresion as $key => $value)

{

listă de instrucțiuni

}

Prima formă trece în revistă tabloul array_expression. La fiecare iterație, valoarea elementului curent este atribuită lui $value și pointerul intern al tabloului este avansat cu un element (astfel, la următoarea iterație aveți acces la următorul element).

A doua formă face același lucru, dar cheia (indicele) elementului curent va fi atribuită variabilei $key la ficare iterație.

Notă: când foreach începe să fie executat, pointerul intern al fișierului este automat repoziționat la primul element al tabloului. Acest lucru înseamnă că nu veți avea nevoie să faceți apel la reset() înainte de foreach. De asemeni, foreach lucrează cu o copie a tabloului astfel încât pointer-ul intern al tabloului nu este modificat ca în cazul utilizării constructorului each.

1.9.8 break

Instrucțiunea break permite ieșirea dintr-o instrucțiune if, for, while sau switch. Instrucțiunea break acceptă un argument numeric opțional care va indica numărul de instrucțiuni imbricate care trebuiesc întrerupte.

1.9.9 continue

Instrucțiunea continue este utilizată într-o buclă pentru a sări peste instrucțiunile de după continue și până la sfârșitul blocului; execuția iterației curente este întrerupă și se trece la execuția iterației următoare. Instrucțiunea continue acceptă un argument numeric opțional care va indica câte bucle imbricate vor fi ignorate.

1.9.10 switch

Instrucțiunea switch este echivalentă cu o serie de instrucțiuni if. Cu numeroase ocazii, veți avea nevoie să comparați aceeași variabilă (sau expresie) cu mai multe valori diferite și să executați diferite parți din cod în funcție de valoarea obținută. Acesta este modul de execuție al instrucțiunii switch.

Este important să înțelegem modul de execuție al instrucțiunii switch pentru a evita apariția erorilor. Instrucțiunea switch se execută secvențial, linie după linie. La început nu este executat nici un cod. Numai când se gasește o valoare a selectorului identică cu o constantă case, PHP execută instrucțiunile corespunzătoare respectivei constante case. PHP continuă să execute instrucțiunile pâna la sfârșitul blocului de instrucțiuni switch sau până când întâlnește instrucțiunea break. Dacă nu utilizați instrucțiunea break la sfârșitul unui bloc case, PHP va continua să execute instrucțiunile din următorul bloc case.

În comanda switch, condiția este evaluată o singură dată și rezultatul este comparat cu fiecare constantă case. Într-o instrucțiune elseif, condiția este reevaluată. Dacă condiția voastră este mai complicată decât o simplă comparație sau apare într-o buclă, instrucțiunea switch se poate dovedi mai rapidă.

Expresiile case pot fi orice expresie scalară de tip întreg, virgulă mobilă sau șir de caractere. Tablourile și obiectele pot fi folosite numai dacă sunt dereferențiate la un tip simplu.

1.9.11 include()

Funcția include() introduce și evaluează fișierul specificat în argument. Dacă URL fopen wrappers nu sunt disponibile în PHP (așa cum sunt în configurația implicită), puteți specifica fișierul care trebuie inclus utilizând un URL în locul unui pathname local. Pentru a evita utilizarea eronată a fișierului inclus, orice cod din fișierul destinație care trebuie executat ca un cod PHP trebuie încadrat de tag-uri de început și sfârșit valide în PHP. De asemeni, se poate folosi o instrucțiune include() într-o buclă pentru a include mai multe fișiere diferite, așa cum reiese din exemplul următor:

Instrucțiunea include() este reevaluată de fiecare dată când este întâlnită într-un cod PHP. Deoarece include() este o construcție specială a limbajului, trebuie să o includeți într-un bloc de instrucțiuni dacă ea apare într-un bloc condițional.

În PHP4, cât și în PHP3, se poate executa o instrucțiune return în interiorul unui fișier inclus cu include(), execuția determinând încheierea procesului în respectivul fișier și revenirea în scriptul care l-a solicitat. De asemeni, PHP4 permite să returnați valori din fișierele incluse cu include(). Puteți folosi aceste valori ca și cum ar fi returnate de o funcție normală.

Este important de notat că atunci când un fișier este inclus cu include() codul pe care îl conține moștenește domeniul variabilelor corespunzator liniei pe care apare instrucțiunea include() în cod. Orice variabilă disponibilă pe respectiva linie va fi disponibilă și în fișierul inclus.

1.9.12 include_once

Instrucțiunea include_once include și evaluează fișierul specificat în timpul execuției scriptului. Comportamentul este similar cu cel al instrucțiunii include(), deosebirea majoră fiind aceea că dacă codul din fișier a fost deja inclus în script operația nu va fi repetată. Vom folosi această instrucțiune când un fișier ar putea fi inclus și evaluat de mai multe ori în execuția unui anumit script și dorim să ne asigurăm că includerea sa se va efectua numai odată pentru a evita problemele care pot să apară la redefinirea funcțiilor, reinițializarea variabilelor etc.

1.10. Funcții

1.10.1 Funcțiile definite de utilizator

O funcție poate fi definită de utilizator conform sintaxei următoare:

function nume_functie( $arg1, $arg2, …, $argN)

{

echo "Exemplu de funcție.\n";

return $retval;

}

Într-o funcție poate să apară orice cod PHP valid, chiar alte funcții și definiții de clase.

În PHP3, funcțiile trebuie să fie definite înainte de a fi referențiate; în PHP4 nu există o asemenea restricție. PHP nu susține funcții de supraîncarcare, nu se poate anula definirea sau redefini o funcție declarată anterior.

PHP3 nu acceptă număr variabil de argumente în antetul funcțiilor, dar acceptă argumente implicite.

1.10.2 Argumentul funcțiilor

Informațiile pot fi transmise funcțiilor print-o listă de argumente. În această listă variabilele și/sau constantele sunt delimitate prin virgulă.

PHP acceptă transmiterea argumentelor prin valoare (implicit), prin referință și argumente cu valori implicite. Listele cu număr variabil de argumente sunt acceptate doar în versiunea PHP4. Un efect similar poate fi obținut în PHP3 transmițând funcției un tablou de argumente.

1.10.3 Functii recursive

Este posibil ca o funcție din PHP să se auto-apeleze. O funcțe care procedează astfel se numește funcție recursivă. Totuși, dacă nu ați studiat informatica, este recomandabil sa nu scrieti funcții recursive. Cu toate acestea, puteți scrie accidental o asemenea funcție, deci este util să știți unele noțiuni referitoare la aceasta.
Programul următor definește și invocă o funcție recursivă simplă:

Function recursor()
{
     return recursor();
}
$x = recursor();

La invocarea funcției recursor(), aceasta invocă imediat funcția recursor(), care se auto-invocă instantaneu. Astfel, funcția recursor() este invocată în mod repetat, până când se produce o eroare cunoscută sub numele de depășire în sens pozitiv a stivei, (stack overflow). Dacă programul dumneavoastră se incheie cu o depașire în sens pozitiv a stivei, o posibilă cauză poate consta într-o recursie incorectă.

1.10.4 Transmiterea argumentelor prin referință

Implicit, argumentele funcțiilor sunt transmise prin valoare (în sensul că schimbarea valorii argumentului în interiorul funcției nu se reflectă și în afara funcției). Dacă doriți să permiteți unei funcții să modifice argumentele sale, acestea trebuie transmise prin referință.

Dacă vreți ca un argument al unei funcții să fie transmis prin referință, trebuie să precedați cu un '&' numele argumentului în definiția funcției.

Dacă vreți să transmiteți o variabilă prin referință unei funcții care nu face acest lucru în mod implicit, trebuie să precedați cu un '&' numele argumentului în apelul funcției.

1.10.5 Valorile argumentelor implicite

O funcție poate defini valorile implicite ale argumentelor scalare în stilul C++.

Valoarea implicită trebuie să fie o expresie constantă, nu o variabilă sau un membru de clasă. Observați că atunci când folosiți argumente implicite, orice astfel de argument trebuie să fie în lista argumentelor în dreapta orcărui argument neimplicit, altfel nu vom obține rezultatul așteptat.

1.10.6 Liste cu număr variabil de argumente

PHP4 acceptă liste cu număr variabil de argumente în funcțiile definite de utilizator. Acest lucru se obține ușor, utilizând funcțiile funct_num_args, funct_get_arg și funct_get_args.

1.10.7 Valorile returnate de funcții

Valorile sunt returnate folosind opțional instrucțiunea return. Poate fi returnat orice tip de rezultat, inclusiv tablouri și obiecte.

Nu puteți returna valori multiple dintr-o funcție, dar rezultate asemănătoare pot fi obținute prin returnarea unui tablou:

Pentru a returna o referință dintr-o funcție, trebuie folosit operatorul '&' atât în declarația funcției dar și când atribuiți valoarea returnată unei variabile.

1.10.8 Funcții variabile

PHP susține conceptul de funcții variabile. Aceasta înseamnă că dacă numele unei variabile este urmat de paranteze, PHP va căuta o funcție cu același nume și va încerca să o execute.

1.11. Referințe

1.11.1 Ce sunt referințele?

În PHP referințele reprezintă posibilitatea de a referi conținutul unei variabile prin nume diferite. În PHP numele unei variabile diferă de conținutul variabilei, deci un anumit conținut poate fi identificat prin nume diferite, fară a se confunda însă cu pointerii din C.

1.11.2 Ce fac referințele?

Referințele PHP permit referirea aceluiași conținut prin două variabile diferite. Când scrieți:

$a = &$b;

înseamnă că $a și $b indică aceeași variabilă.

Al doilea lucru pe care îl realizează referințele este să transmită variabile prin referință. Acest lucru se realizează folosind variabila locală a funcției și variabila cu care se face apelul drept referințe către același conținut.

Al treilea lucru pe care îl pot face referințele este întoarcerea unei valori prin referință.

1.11.3 Ce nu sunt referințele?

Referințele nu sunt pointeri. Astfel, următoarea construcție nu va întoarce rezultatul așteptat:

function fct( &$var)

{

$var = &$GLOBALS[ "baz"];

}

fct( &bar);

În momentul apelului $var va intra în corespondența cu $bar din apelator, dar va fi redirectată către $GLOBALS[ "baz"].

1.11.4 Întoarcerea referințelor

Întoarcerea prin referință este utilă când doriți să utilizați funcții pentru a găsi variabile care ar trebui legate cu acestea.

A SE VEDEA Valorile returnate de functii

Observație: spre deosebire de transmiterea parametrilor, trebuie să utilizați '&' în ambele locuri pentru a indica ce întoarceți prin referințăa (și nu prin valoare cum este uzual) și pentru a spune cui i se atribuie respectiva referință.

1.11.5 Resetarea referințelor

Când resetați o referință rupeți practic legatura dintre numele și conținutul variabilei. Aceasta nu înseamnă ca acel conținut al variabilei va fi distrus.

Multe construcții sintactice în PHP sunt implementate prin mecanismul referințelor, deci modul lor de funcționare se poate aplica acestor construcții. Unele construcții, cum ar fi transmiterea și întoarcerea prin referință, au fost deja menționate. Alte construcții care folosesc referințele sunt referințele globale. Când declarați variabila $var ca variabilă globală creați defapt o referință la o variabilă globală. Semnificația este aceeași cu :

$var = &$GLOBALS[ "var"];

Aceasta înseamnă, spre exemplu, că, resetarea variabilei $var nu va reseta și variabila globală asociată.

Capitolul 2 – MySQL

2.1. Noțiuni fundamentale despre bazele de date și SQL

2.1.1. Structura unei baze de date relaționale

O bază de date relaționale stochează datele în tabele, care amintesc de foile de calcul tabelar, iar fiecare tabel stochează informații despre un anumit tip de entitate. Practic, un tabel poate fi asimilat cu un fișier.

Pentru a se putea face referire la un anumit rând al tabelului, se obișnuiește ca fiecare tabel să conțină o coloană care identifică în mod unic fiecare rând. Această coloană se numește cheia primară a tabelului. Dacă nici o coloană nu conține o valoare unică pentru fiecare rând, se pot combina valorile mai multor coloane pentru a crea o cheie primară compusă.

O bază de date relațională se numește astfel datorită capacității sale de a stabili relații între date din mai multe tabele.

Aplicația software care găzduiește o bază de date se numește sistem de gestiune a bazelor de date (SGBD). Există multe sisteme de gestiune a bazelor de date din surse deschise și comerciale. Printre cele mai populare asemenea sisteme se numără:

SGBD Tip

DB2 Comercial

Interbase În trecut comercial; în prezent din sursă deschisă

MySQL Sursă deschisă

Oracle Comercial

Postgresql Sursă deschisă

SQL Server Comercial

Sybase Comercial

MySQL este cel mai popular sistem de gestiune a bazelor de date destinat utilizării cu PHP, în mare măsură deoarece este gratuit. Totuși, prin intermediul PHP este posibil accesul la aproape orice SGBD modern.

2.1.2. Interogarea ad-hoc

Bazele de date relaționale înțeleg SQL (Structured Query Language*), un limbaj relativ simplu, folosit pentru solicitarea datelor. Totuși, în ciuda simplității sale, SQL este un limbaj foarte puternic, care poate obține accesul la date stocate în mai multe tabele, poate filtra datele dorite și poate sorta, rezuma și afișa rezultatele.

În general, nu se pot anticipa toate modalitățile în care utilizatorii pot dori să obțină acces la date și să le vizualizeze. Ca atare, nu se pot scrie programe de aplicație care să satisfacă fiecare potențială necesitate de informații. Este aproape sigur că vor apărea unele cereri de date neprevăzute (sau ad hoc).

Utilizând SQL, este posibil accesul la datele stocate într-o bază de date relațională fără a scrie un program de aplicație, permițând frecvent evitarea întârzierilor și a costurilor implicate de programarea personalizată. Astfel, bazele de date relaționale permit satisfacerea tuturor cererilor ad-hoc de informații, care ar rămâne fără răspuns în alte situații.

2.1.3. Organizarea și asigurarea datelor

În general, bazele de date relaționale își stochează datele într-un singur fișier sau catalog. Această caracteristică de organizare facilitează administrarea datelor, deoarece executarea copiei de siguranță, respectiv restaurarea unui singur fișier sau

catalog sunt mai simplă decât operațiile similare aplicate unui set de fișiere stocat în mai multe cataloage.

În general, bazele de date relaționale protejează datele împotriva accesului neautorizat. De exemplu, fișierele care stochează tabelele relaționale pot fi accesibile numai pentru administratorul de sistem și pentru un cont special de utilizator, creat pentru gestionarea bazei de date.

2.2. Crearea unei baze de date MySQL

Administratorul de sistem creează baze de date MySQL. La început, o bază de date nu conține tabele. Pentru a crea un tabel într-o bază de date, folosiți un sub-limbaj SQL special, cunoscut sub numele de Data Definition Language* (DDL). Această sub-secțiune este dedicată formelor pe care le pot lua comenzile DDL. Puteți emite comenzi DDL și alte comenzi SQL prin intermediul unui interpretor SQL sau prin intermediul PHP. Proiectele din acest modul prezintă modul de emitere a comenzilor SQL folosind un interpretor SQL. Modulul următor prezintă modul de emitere a comenzilor SQL utilizând PHP.

2.2.1. Crearea de tabele

Pentru a crea un tabel într-o bază de date, emiteți comanda CREATE TABLE, care are următoarea formă:

CREATE TABLE tabel (coloana tip, coloana tip, …);

unde tabel este numele tabelului, coloana este numele unei coloane, tip este tipul datelor incluse în coloană, iar … arată că se poate specifica un număr nedefinit de coloane și tipuri. De exemplu, comanda următoare creează un tabel numit inchirieri, care conține coloanele CNP (codul numeric personal al persoanei care face închirierea), Sosire, Plecare și NrCamera:

CREATE TABLE inchirieri (CNP BIGINT(13), sosire DATE, plecare DATE, NrCamera INT(3));

În general, SQL nu este sensibil la diferența între majuscule și minuscule. Deci, dacă preferați, puteți emite comanda următoare, care se comportă exact la fel ca și precedenta:

create table inchirieri (cnp bigint(13), sosire date, plecare date, nrcamera int(3));

2.2.2. Ștergerea unui tabel

Ștergerea unui tabel este o operație simplă. Prin ștergerea unui tabel, sunt eliminate toate rândurile incluse în tabel. Pentru a șterge un tabel, emiteți următoarea comandă:

DROP TABLE tabel;

unde tabel este numele tabelului care urmează a fi șters.

Ștergerea unui tabel este un act irevocabil; asigurați-vă că intenționați să ștergeți tabelul înainte de a emite o comandă DROP TABLE; de asemenea, asigurați-vă că ați scris corect comanda înainte de a apăsa pe tasta ENTER.

2.2.3. Modificarea unui tabel

După crearea unui tabel, îl puteți modifica prin emiterea unei comenzi ALTER TABLE. O formă a comenzii vă permite să ștergeți o coloană din tabel:

ALTER TABLE tabel DROP coloana;

unde tabel este numele tabelului care va fi modificat, iar coloana este numele coloanei care va fi ștearsă.

O altă formă a comenzii vă permite să adăugați o nouă coloană în tabel:

ALTER TABLE tabel ADD coloana tip [optiuni];

unde tabel este numele tabelului care va fi modificat, coloana este numele coloanei care va fi adăugată, tip este tipul noii coloane, iar [opțiuni] constituie toate opțiunile dorite, precum PRIMARY KEY. De exemplu, pentru a adăuga din nou coloana preț la tabelul carte, emiteți comanda:

2.3. Acordarea și revocarea privilegiilor de acces

Când un utilizator încearcă să obțină acces la o bază de date relațională, SGBD verifică dacă utilizatorul are permisiunea de a executa operația. Administratorul de sistem poate folosi comanda MySQL GRANT pentru a autoriza un utilizator să obțină accesul la un tabel din baza de date. Comanda are următoarea formă:

GRANT ALL ON tabel TO utilizator IDENTIFIED BY ’parola’;

unde tabel este numele tabelului, utilizator este numele contului de utilizator, iar parola este parola pe care o va furniza utilizatorul pentru a-și proba identitatea. Alternativ, administratorul de sistem poate autoriza un utilizator să obțină acces la orice tabel dintr-o bază de date specificată, folosind următoarea formă a comenzii GRANT:

GRANT ALL ON baza_de_date.* TO utilizator IDENTIFIED BY ’parola’;

De exemplu, comanda următoare autorizează pe utilizatorul php să obțină acces la toate tabelele din baza de date numită otel, ori de câte ori utilizatorul furnizează parola specificată:

GRANT ALL ON hotel.* TO php IDENTIFIED BY ’administrator’;

Comanda. REVOKE se poate folosi pentru retragerea privilegiilor acordate anterior. Comanda are următoarele forme:

REVOKE ALL ON tabel FROM utilizator;

REVOKE ALL ON baza_de_date.* FROM utilizator;

De exemplu, pentru a revoca toate privilegiile utilizatorului director, emiteți comanda:

REVOKE ALL ON baza_de_date.* FROM director;

Administratorul de sistem poate folosi o formă mai complexă comenzii GRANT pentru a autoriza accesul numai la coloanele specificate. Forma corespunzătoare a comenzii este:

GRANT privilegiu (coloane) ON tabel TO utilizator IDENTIFIED BY 'parola’;

sau

GRANT privilegiu (coloane) ON baza_de_date.* TO utilizator IDENTIFIED BY 'parola’;

unde privilegiu este privilegiul care urmează a fi extins, coloane sunt coloanele cărora li se aplică privilegiul, iar tabel, baza_de_date, utilizator și parola au semnificațiile cunoscute. Sunt permise și forme similare ale comenzii REVOKE:

REVOKE privilegiu (coloane) ON tabel FROM utilizator;

sau

REVOKE privilegiu (coloane) ON baza_de_date.* FROM utilizator;

Între privilegiile posibile se numără următoarele:

• INSERT, care permite inserția rândurilor care conțin coloana specificată

• SELECT, care permite accesul la rândurile care conțin coloana specificată

• UPDATE, care permite actualizarea rândurilor care conțin coloana specificată De exemplu, pentru a permite unui utilizator să obțină accesul la o coloană, fără a o modifica, puteți folosi o secvență de comenzi similară cu următoarea:

REVOKE ALL ON camere FROM php;

GRANT

SELECT(NrCamera, TipCamera),

INSERT(NrCamera, TipCamera),

UPDATE(NrCamera, TipCamera),

ON administrator TO php IDENTIFIED BY 'administrator';

REVOKE INSERT(NrCamera) ON camere FROM php;

REVOKE UPDATE(NrCamera) ON camere FROM php;

Rețineți că prima comandă revocă toate privilegiile de la nivelul tabelului; în caz contrar, aceste privilegii le vor elimina pe cele situate la nivel de coloană.

Caracteristica privilegiilor furnizată de MySQL este extrem de sofisticată și furnizează mult mai multe opțiuni. Pentru mai multe informații, consultați manualul SQL pe suport electronic, de la adresa www.mysql.com.

2.4. Accesul la datele dintr-o bază de date: interogările SQL

2.4.1. Comanda SELECT

Cea mai simplă interogare posibilă raportează toate coloanele din toate rândurile unui tabel. Interogarea are următoarea formă:

SELECT * FROM tabel;

unde tabel este numele tabelului la care se va obține accesul. Formatul datelor de ieșire plasează fiecare rând al tabelului pe o linie separată și prezintă coloanele într-o ordine arbitrară. Datele de ieșire includ numele coloanelor și caractere simulate de desenare a liniilor, care separă coloanele.

Dacă doriți să selectați numai anumite coloane sau să raportați coloanele într-o anumită ordine, puteți folosi următoarea formă alternativă a comenzii SELECT:

SELECT coloana1, coloana2 FROM tabel;

unde tabel este numele tabelului, iar coloana1 și coloana2 sunt coloanele la care se va obține accesul și al căror conținut va fi raportat. Puteți specifica una, două sau mai multe coloane; pur și simplu separați numele fiecărei coloane de vecinii săi prin intermediul unei virgule.

2.4.2. Clauza WHERE

Deseori, este necesară numai raportarea acelor rânduri care satisfac un anumit criteriu. Clauza WHERE vă permite să specificați o condiție; rândurile care nu satisfac condiția nu sunt raportate. De exemplu, iată o interogare care raportează un singur rând:

SELECT NrCamera, TipCamera FROM camere WHERE NrCamera=1;

Puteți compara valoarea unei coloane cu aceea a unei alte coloane, respectiv valoarea unei coloane cu o valoare literală. Valorile literale șir SQL trebuie să fie incluse între ghilimele simple, nu între ghilimelele duble permise de PHP.

Sub-limbajul folosit pentru specificarea modelelor asociate operatorului LIKE este diferit de cel folosit de PHP sau de shell-ul UNIX. Meta-caracterul % corespunde unui număr de zero sau mai multe caractere, iar meta-caracterul _ corespunde unui singur caracter. Modelele, ca și șirurile, sunt incluse între ghilimele simple. De exemplu, modelul '%ar%' corespunde oricărui șir care conține sub-șirul 'ar', inclusiv șiruri precum 'ar', 'arc' și 'un zar'.

De exemplu, următoarea interogare raportează rândurile care au un număr de camera mai mare decât unitatea sau tipul camerei include sub-șirul 'simpla':

SELECT NrCamera, TipCamera FROM Camere

WHERE NrCamera >1 OR PipCamera LIKE ’%simpla%’;

Pentru a compara o valoare cu o expresie regulată în MySQL, folosiți următoarea formă:

x REGEXP y

unde x este valoarea care va fi testată, iar y este o expresie regulată, delimitată prin ghilimele simple.

MySQL include multe alte extensii ale limbajului SQL.

Modificarea datelor dintr-o bază de date

Sub-limbajul SQL Data Manipulation Language include comenzi care vă permit să inserați rânduri noi într-un tabel, să actualizați una sau mai multe coloane ale rândurilor existente în tabele, respectiv să ștergeri rânduri dintr-un tabel. Pentru a insera un nou rând într-un tabel, folosiți comanda INSERT, care are următoarea formă:

INSERT INTO tabel VALUES (valoare1, valoare2);

unde tabel este numele tabelului la care se va adăuga rândul, valoare1 este valoarea pentru prima coloană din tabel, iar valoare2 este valoarea celei de-a doua coloane din tabel. Se pot da mai mult sau mai puțin de două valori; numărul valorilor date trebuie să fie egal cu acela al coloanelor din tabel. O coloană poate primi și valoarea NULL, cu excepția situațiilor când definiția coloanei conține specificații contrare.

O formă mai populară a comenzii INSERT specifică numele coloanelor cărora le sunt atribuite valorile:

INSERT INTO tabel (coloana1, coloana2) VALUES (valoare1, valoare2);

În această formă, coloana denumită coloana1 primește valoarea valoare1, iar coloana denumită coloana2 primește valoarea valoare2. Ca în cazul primei forme a comenzii INSERT, pot fi specificate mai mult, respectiv mai puțin de două coloane și valori. Numărul coloanelor specificate trebuie să fie egal cu numărul valorilor specificate. Coloanele care nu sunt denumite în comanda INSERT și care nu au o valoare prestabilită (DEFAULT) primesc valoarea NULL, cu excepția situațiilor când valoarea respectivă nu este permisă; în acest caz, comanda INSERT eșuează.

Pentru a modifica valoarea unui rând sau mai multor rânduri existente într-un tabel, emiteți o comandă UPDATE, care are următoarea formă:

UPDATE tabel SET coloana1=coloana1, coloana2=coloana2

WHERE conditie;

unde tabel este numele tabelului ale cărui rânduri urmează să se modifice, coloana1 este numele primei coloane care urmează a fi modificată, valoare1 este valoarea care va fi repartizată în coloana1, coloana2 este numele celei de-a doua coloane care urmează a fi modificată, valoare2 este valoarea care va fi repartizată în coloana2, iar condiție identifică rândul sau rândurile care urmează a fi actualizate. Poate fi actualizat un număr mai mare sau mai mic de coloane. Dacă urmează ca fiecare rând să fie actualizat, clauza WHERE poate fi omisă.

Pentru a șterge un rând dintr-un tabel, emiteți comanda DELETE, care are următoarea formă:

DELETE FROM tabel WHERE conditie;

Dacă vor fi șterse toate rândurile tabelului, clauza WHERE poate fi omisă.

2.4.3. Clauza ORDER BY(rezultate de sortare)

Deseori, este important ca datele să fie raportate într-o anumită secvență. Puteți specifica ordinea de raportare a rezultatelor interogării folosind clauza ORDER BY, care are următoarea formă:

ORDER BY valoare

Dacă se vor folosi mai multe câmpuri de sortare, fiecare câmp va fi separat de vecinii săi prin intermediul unei virgule. Dacă doriți să indicați o sortare descendentă, în locul uneia ascendente, specificați DESC după valoare.

De exemplu, pentru a ordona toate camerele în funcție de tipul camerei, puteți folosi următoarea interogare:

SELECT NrCamera, TipCamera FROM camere

ORDER BY NrCamera DESC, TipCamera;

Pentru a include numai camerele care au nr mai mare de 10, adăugați o clauză WHERE la comanda SELECT:

SELECT NrCamera, TipCamera FROM camere

WHERE NrCamera>10

ORDER BY NrCamera DESC, TipCamera;

SQL include funcții care vă permit să raportați valori agregate, precum un număr al rândurilor tabelului. Iată cele mai importante funcții de agregare:

count(*) Numărul rândurilor din tabel.

count(coloana) Numărul rândurilor din tabel care conțin o valoare diferită de NULL în coloana specificată.

count(distinct coloana) Numărul valorilor distincte diferite de NULL care apar în coloana specificată.

avg(coloana) Valoarea mijlocie (medie) a coloanei numerice specificate.

min(coloana) Valoarea minimă din coloana specificată.

max(coloana) Valoarea maximă din coloana specificată.

sum(coloana) Suma valorilor din coloana specificată.

Clauza SQL AS specifică un nume nou pentru o coloană sau expresie. Numele specificat este folosit ca titlu în rapoartele SQL. Clauza AS este utilă în lucrul cu funcțiile de agregare.

2.4.4. Clauza GROUP BY(rezultate de grupare)

Interogările sumare de mai sus sunt similare cu totalele de la sfârșitul raportului. Se condensează toate datele din raport într-o singură linie sumară de date. Totuși, este deseori folositor de a avea subtotale în raport. Pentru aceasta putem folosi clauza GROUP BY din declarația SELECT. O interogare care cuprinde clauza GROUP BY se numește interogare grupată, deoarece grupează datele din tabelele SELECT și crează o singură linie pentru fiecare grup. Coloanele numite în clauza GROUP BY se numesc coloane de grupare. Standardul ISO cere ca clauzele SELECT și GROUP BY să fie strâns integrate.Când se folosește GROUP BY, fiecare element din lista SELECT trebuie să aibă valoare unică pe grup. În plus, clauza SELECT poate să conțină numai:

nume de coloană,

funcții complexe,

constante,

o expresie cuprinzînd combinații ale elementelor de mai sus.

Toate numele de coloană din lista SELECT trebuie să apară în clauza GROUP BY, în afară de cazul când numele este folosit numai într-o funcție complexă. Reciproca nu este adevărată: pot să existe nume de coloane în clauza GROUP BY care nu apar în lista SELECT. Când clauza WHERE este folosită cu GROUP BY, prima dată este apelată clauza WHERE, apoi grupurile sunt formate din liniile rămase ceea ce satisface condiția de căutare.

2.4.5. Clauza HAVING(restrângerea grupurilor)

Clauza HAVING este folosită împreună cu clauza GROUP BY pentru a restrânge grupurile care apar la finalul tabelului rezultat. Deși sunt similare în sintaxă, HAVING și WHERE servesc scopuri diferite. Clauza WHERE strecoară linii individuale în finalul tabelului rezultat, iar HAVING strecoară grupuri în finalul tabelului rezultat. Standardul ISO cere ca numele coloană folosite în clauza HAVING să apară, deasemenea, în lista GROUP BY sau să fie conținute într-o funcție complexă. În practică, condiția de căutare din clauza HAVING include întotdeauna cel puțin o funcție complexă, altfel condiția de căutare ar putea fi mutată în clauza WHERE și aplicată pe linii individuale.

Clauza HAVING nu este parte importantă a SQL, orice interogare exprimată folosind clauza HAVING poate fi rescrisă întotdeauna fără clauza HAVING.

2.5. Uniri

SQL vă permite să obțineți accesul la mai multe tabele într-o singură interogare, în general, această operație se execută pentru a urma relația stabilită printr-o cheie externă, făcând ca datele din tabelul corelat să fie disponibile în interogare. De exemplu, să presupunem că baza de date este asemănătoare celei prezentate în figura 13-2, unde o relație cheie externă – cheie primară asociază tabelele camere și pretcamera. Să examinăm următoarea interogare:

SELECT TipCamera FROM camere, pretcamera

WHERE camere.TipCamera ‚ pretcamera.TipCamera;

Construcțiile camere.TipCamera și pretcamera.TipCamera se numesc nume definite, prima se referă la coloana TipCamera a tabelului camere, iar a doua se referă la coloana TipCamera a tabelului pretcamera. Clauza WHERE asigură o echivalență adecvată între valoarea cheii externe din tabelul pretcamera cu aceea a cheii primare din tabelul camre, în absenta clauzei WHERE, se va stabili o corespondență între fiecare rând din tabelul cu pretcamera și fiecare rând din tabelul cu camere. Un asemenea rezultat, numit produs cartezian, conține în general multe rânduri – majoritatea nedorite – și ca atare trebuie evitat.

2.6. Identificatorii SQL

Identificatorii SQL sunt folosiți pentru a identifica obiectele în baza de date, cum ar fi numele tabelelor, numele rapoartelor și coloanele. Caracterele care pot fi folosite într-un identificator SQL definit de utilizator trebuie să apara într-un set de caractere. Standardul ISO prevede următorul set de caractere, care conține literele mari A…Z, literele mici a…z, cifrele 0…9 și caracterele subliniate ( _ ). Este, de asemenea, posibilă specificarea unui set de caractere alternative. Următoarele restricții sunt impuse pe un identificator:

Un identificator nu poate fi mai lung decât 128 de caractere (multe dialecte au o limită mai mică decât aceasta).

Un identificator trebuie să înceapă cu o literă.

Un identificator nu poate conține spații.

2.7. Tipurile de date ISO SQL

Există 6 tipuri de date scalare SQL definite în standardul ISO, prezentate în tabelul care urmează:

Uneori pentru scopuri de manipulare și conversie, tipurile de date caracter și bit sunt atribuite tipurilor de date string, și exact numeric și aproximativ numerice sunt atribuite tipurilor de date numeric, deoarece ele împart proprietățisimilare.

2.7.1. Datele caracter

Datele caracter conțin o secvență de caractere dintr-un set de caractere definite de implementator, adică este definită de către distribuitorul dialectului particular SQL. Astfel, caracterele exacte care pot apărea ca valorile datelor într-o coloană tip caracter vor varia. ASCII este una din seturile utilizate în comun astăzi. Formatul pentru specificarea unui tip de dată caracter este:

CHARACTER [VARYING][length]

CHARACTER can be abbreviated to CHAR and

CHARACTER VARYING to VARCHAR.

Când o coloană caracter string este definită, o lungime poate fi specificată să indice maximul numărului de caractere conținute în coloane (lungimiea implicită este 1). Un caracter string poate fi definită ca avînd o lungime fixă sau variabilă. Dacă stringul este definit cu lungime fixă, și dacă introducem un string cu câteva caractere mai puțin decât această lungime, stringul este completat cu spații la dreapta pentru a obține lungimea cerută. Dacă stringul este definit cu lungime variabilă și introducem un string cu câteva caractere mai puțin decât această lungime, numai acele caractere introduse sunt rezervate, astfel folosindu-se mai puține spații. De exemplu, codul numeric personal din coloana CNP a tabelului clienti, care are o lungime fixă de 13 caractere, este declarat ca:

CNP BIGINT(13)

Coloana nume a tabelului clienti, care are un număr variabil de caractere până la maximum de 30, este declarată ca:

nume VARCHAR(30)

2.7.2. Datele bit

Tipul de date bit este folosit pentru definirea stringurile bit, adică o secvență de cifre binare, fiecare avînd sau valoarea 0 sau 1. Formatul pentru specificarea tipului de dată bit este similar cu cel al tipului de dată caracter:

BIT [VARYING][lenght]

De exemplu, pentru a ține lungimea fixă a stringului binar ‘0011’, declarăm o coloană bit_string, ca: bit_string BIT(4)

2.7.3. Datele exact numerice

Tipul de dată exact numeric este folosit pentru definirea numerelor cu reprezentare exactă. Numărul conține cifre, un punct zecimal opțional și un semn opțional. Un tip de dată exact numeric conține o precizie și o scală. Precizia dă numărul total a cifrelor zecimale semnificative: adică numărul total al cifrelor, incluzînd zecimalele dar excluzînd punctul. Scala dă numărul total al zecimalelor. De exemplu, valoarea exact numerică -12.345 are precizia 5 și scala 3. Un caz special survine în cazul datelor exact numerice întregi. Există mai multe moduri de a specifica un tip de dată exact numeric:

NUMERIC [precision [, scale]]

DECIMAL [precision [, scale]]

INTEGER

SMALLINT

INTEGER poate fi prescurtat prin INT și DECIMAL prin DEC.

NUMERIC și DECIMAL generează numere în scriere zecimală. Valoarea implicită a scalei este întotdeauna 0, iar precizia implicită este definită de limbaj. INTEGER este folosit pentru numere mari pozitive sau negative întregi. SMALLINT este folosit pentru numere mici pozitive sau negative întregi.

Specificînd acest tip de dată, pot fi rezervate mai puține spații de stocare pentru dată. De exemplu, valoarea absolută maximă care poate fi stocată în acest tip de dată poate fi 32767. Coloana NrCamera a tabelului inchirieri, care reprezintă numărul camerei , este evident un întreg mic și poate fi declarată ca:

NrCamera SMALLINT

Coloana pret a tabelului pretcamera poate fi declarată ca:

pret DECIMAL(9,2)

care poate manipula o valoare până la 9,999,999.99.

2.7.4. Datele aproximativ numerice

Tipul de dată aproximativ numeric este folosit pentru definirea numerelor care nu au o reprezentare exactă, ca de pildă numerele reale. Aproximativ numeric, sau punct float, este similar notației stiințifice în care un număr este scris ca o putere de zece. De exemplu, 10E3, +5.2E6, -0.2E-4. Există mai multe moduri de a specifica un tip de dată aproximativ numeric:

FLOAT [precision]

REAL

DOUBLE PRECISION

2.7.5. Datele dată-timp

Acest tip de dată este folosit pentru a defini puncte în timp la un anumit grad de precizie. Ca exemple putem da date calendaristice, intervale de timp și intervale ale unei zile. Standardul ISO folosește pentru acest tip de dată cuvintele rezervate: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, TIMEZONE_HOUR și TIMEZONE_MINUTE. Ultimele două câmpuri specifică ora și minutul pentru anumite zone geografice.

Trei tipuri ale acestui tip de date sunt acceptate:

DATE

TIME [time_precision][WITH TIME ZONE]

TIMESTAMP [time_precision][ WITH TIME ZONE]

DATE este folosit pentru a reprezenta datele calendaristice folosind cuvintele rezervate YEAR, MONTH și DAY.

TIME este folosit pentru a reprezenta timpul folosind cuvintele rezervate HOUR, MINUTE și SECOND.

TIMESTAMP reprezintă datele calendaristice și timpul.

Time_precision reprezintă unitatea de măsură a câmpului SECOND. Dacă nu este specificat acesta este implicit 0 în TIME fiind vorba de secunde, iar în TIMESTAMP valoarea implicită este 6 fiind vorba de microsecunde.

Cuvântul cheie WITH TIME ZONE controlează prezența câmpurilor TIMEZONE_HOUR și TIMEZONE_MINUTE.

Date interval

Tipul de dată interval este folosit pentru a reprezenta intervale de timp. Fiecare tip de dată interval este alcătuit dintr-un subset învecinat al câmpurilor: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND. Există două clase de date interval: intervale an-lună și intervale zi-timp. Clasa an-lună poate conține numai câmpurile YEAR și/sau MONTH, iar clasa zi-timp poate conține o selecție invecinată din DAY, HOUR, MINUTE, SECOND.

Formatul pentru specificarea tipului da dată interval este:

INTERVAL {{start_câmp TO sfârșit_câmp} | câmp_dată-timp}

start_câmp=YEAR|MONTH|DAY|HOUR|MINUTE

[(precizia câmpului principal al intervalului)]

sfârșit_câmp=YEAR| MONTH|DAY|HOUR|MINUTE|SECOND

[(precizia zecimalelor câmpului secundar al intervalului)]

câmp_dată-timp=start_câmp|SECOND

[(precizia câmpului principal al intervalului [,precizia zecimalelor câmpului secundar al intervalului])]

Capitolul 3 – Proiectarea logică a bazei de date

1. Crearea modelului conceptual local pentru utilizatori

Obiectiv : Identificarea tipurilor de entități principale in vederile utilizatorilor.

Evidenta clienților hotelului :

In baza de date vor fi memorați clienții hotelului. Informațiile cu privire la clienți sunt : CNP, nume, prenume, adresa, dataNastere, nrTelefon, locMunca. Clienții vor fi unic determinați de un atribut numit CNP (Cod Numeric Personal).

Evidenta camerelor din hotel :

In baza de date for fi reținute informații despre camerele din hotel. Datele despre o camera sunt : nrCamera, tipCamera. Camerele vor fi unic determinate prin nrCamera.

O camera va fi introdusa o singura data.

Evidenta închirierilor camerelor din hotel :

In baza de date vor fi memorate toate închirierile efectuate. Pentru fiecare închiriere se rețin : CNP, Sosire, Plecare, nrCamera. Închirierile sunt unic determinate prin: CNP, Sosire, nrCamera .

Evidenta rezervărilor :

In baza de date vor fi reținute de asemeni toate rezervările efectuate. Pentru fiecare rezervare se rețin : CNP, nume, prenume, tipCamera, Sosire, Plecare, dataRezervare. Rezervările sunt unic determinate prin: CNP, Sosire.

Evidenta Serviciilor :

In baza de date vor fi reținute toate serviciile oferite de hotel. Pentru fiecare serviciu se rețin : ServiciuId, Denumire, Preț. Serviciile sunt identificate unic prin ServiciuId.

Un serviciu va fi introdus o singură dată.

Evidenta Serviciilor prestate:

In baza de date vor fi reținute toate serviciile prestate de hotel unui anumit client : NrCamera, ServiciuId, Data, Cantitate. Serviciile sunt identificate unic prin : NrCamera, ServiciuId și Data.

Evidența prețului camerelor:

In baza de date vor fi reținute detalii referitoare la cameră: tipCameră (simplă, dublă, apartament), Cost. Prețul este identificat prin TipCameră

Tranzacții cerute:

Lista camerelor ocupate din hotel

Lista clienților cazați la hotel intr-o anumita perioada

Raport final cu serviciile prestate și costul total al camerei.

Lista serviciilor oferite de hotel

Total încasări la sfârșitul fiecărei zile

1.1 Identificarea tipurilor de entități

Obiectiv: Identificarea tipurilor de entități principale in vederile utilizatorilor.

Primul pas în proiectarea bazei de date este identificarea entităților din datele furnizate de utilizatori. La început identificam tipurile de entități din specificațiile de mai sus : Clienți, Camere, Închiriere, Rezervare, Servicii, Servicii Prestate, Preț Camera.

1.2 Identificarea tipurilor de relații

Obiectiv : Identificarea tipurilor de relații importante dintre entități.

După identificarea entităților, va trebui să identificăm și relațiile importante dintre aceste entități. Relațiile se descriu printr-un verb al relației. De exemplu:

Camerele au Preț

Clienții fac Închirieri

Determinarea cardinalității și a participării la tipurile de relații

După identificarea tipurilor de relații, trebuie să determinăm cardinalitatea lor, alegând dintre posibilitățile: unu-la-unu (1:1), unu-la-multe (1:M), sau multe-la-multe (M:N). Dacă se cunosc valori specifice ale cardinalităților, aceste valori se scriu la documentarea relațiilor. În continuare determinăm și participarea la relație, care poate fii total, sau parțial.

Daca consideram relația Clienți Fac Închirieri, se poate observa ca un client poate face mai multe închirieri, deci cardinalitatea relației este N : 1. Considerând relația Clienți închiriază Cameră se poate observa că un client poate închiria mai multe camere(1 : N), dar o cameră poate fi închiriată de mai mulți clienți (M : 1), în final cardinalitatea relației este M : N.

1.3 Identificarea și asocierea de atribute la tipurile de entități și tipurile de relații

Obiectiv: Asocierea de atribute la tipurile de entități și la tipurile de relații.

Atributele se identifica in același mod ca și entitățile. Pentru o mai ușoara identificare trebuie sa luam entitățile pe rând și sa ne punem întrebarea: Ce informații deținem despre aceasta entitate?

După cum se poate vedea in graficele de mai sus, tot aici am identificat și cheile primare ale fiecărei entități in parte.

1.4 Desenarea diagramei E-R

2 Crearea și validarea modelului logic local

Obiectiv: Crearea unui model logic local bazat pe modelul conceptual al utilizatorilor asupra hotelului și validarea lui prin procesul de normalizare și prin tehnica tranzacțiilor cerute.

În acest pas verificăm modelul conceptual creat în pasul anterior și eliminăm din el structurile care sunt dificil de realizat într-un SGBD. Vom valida modelul logic prin procesul de normalizare și a tranzacțiilor.

Normalizarea este un proces formal de analiză a relațiilor bazate pe chei primare (sau pe baza cheilor candidat în cazul BCNF). Normalizarea presupune urmarea unor reguli prin care baza de date se poate normaliza până la un anumit grad. Dacă o cerință nu este satisfăcută, relația trebuie descompusă în mai multe relații, care individual satisfac cerințele formei normale.

Normalizarea se execută trecând prin toate formele normale, până la forma normală cerută. La proiectarea unei baze de date trebuie să ajungem cel puțin la forma normală unu, dar ca să evităm toate anomaliile care pot apare, este recomandat aducerea bazei de date la BCNF.

Forma Normală Unu (1NF)

Definiție: Formă Nenormalizată (UNF): O tabelă care conține una sau mai multe grupuri repetitive.

Definiție: Forma Normală Unu (1NF): Relație în care la intersecția oricărei linii cu oricare coloană găsim un câmp care conține exact o valoare.

Forma Normală Doi (2NF)

Forma normală doi se bazează pe conceptul de dependență funcțională totală, ceea ce vom descrie în continuare.

Dependența funcțională totală

Definiție: Dependența funcțională totală: Dacă A și B sunt atributele unei relații, atunci B este total dependent funcțional de atributul A, dacă B este dependent funcțional de A, dar nu este dependent funcțional de nici un subset al lui A.

Definiție: Forma Normală Doi (2NF): O relație este în forma normală doi, dacă este în forma normală unu și fiecare atribut care nu aparține cheii primare, este total dependent funcțional de cheia primară.

Forma Normală Trei (3NF)

Forma normală doi chiar dacă nu conține atâta redundanță ca forma normală unu, totuși există cazuri în care pot apărea anomalii la actualizare. Aceste anomalii apar din cauza redundanței generate de dependența tranzitivă.

Dependența tranzitivă

Definiție: Dependență tranzitivă: Dacă atributele A, B, C sunt în relațiile AB și BC, atunci spunem că atributul C este dependent tranzitiv de atributul A, via B.

Definiție: Forma Normală Trei (3NF): O relație care este în formă normală doi și nu există nici un atribut care să nu aparțină cheii principale și care să fie tranzitiv dependentă de cheia principală.

În cazul existenței dependenței tranzitive, ștergem coloanele care sunt tranzitiv dependente de cheia primară și creăm o relație nouă cu aceste coloane, împreună cu determinantul lor, adică cheia primară.

Forma Normală Boyce-Codd (BCNF)

Baza de date trebuie proiectată astfel încât să nu conțină dependențe parțiale sau tranzitive, pentru că altfel ne putem confrunta cu anomaliile descrise în cap. 2.2.

Forma normală Boyce-Codd este bazată pe cheile candidat din relație. O relație cu o singură cheie candidat în formă normală trei este și în formă normală Boyce-Codd.

Definiție: Forma normală Boyce-Codd (BCNF): O relație este în forma normală Boyce-Codd dacă și numai dacă orice determinant din relație este cheie candidat

Prin normalizare trebuie să demonstrăm că modelul creat este consistent, conține redundanță minimală și are stabilitate maximă. Normalizarea este procesul prin care se decide dacă atributele pot sau nu să rămână împreună. Conceptul de bază a teoriei relațiilor este că atributele sunt grupate împreună pentru că există o relație logică între ele. Câteodată baza de date nu este cea mai eficientă. Acesta se argumentează prin următoarele:

Proiectarea normalizată organizează datele în funcție de dependențele funcționale. Deci acest proces este situat undeva între proiectarea conceptuală și cea fizică.

Proiectul logic nu este un proiect final. El ajută proiectantul să înțeleagă natura datelor în întreprindere. Proiectul fizic poate fi diferit. Există posibilitatea ca unele tipuri de entități să se denormalizeze. Totuși normalizarea nu este un timp pierdut.

Proiectul normalizat este robust și independent de anomaliile de actualizare prezentate mai înainte.

Calculatoarele moderne au mult mai multă putere de calcul, ca cele de acum câțiva ani. Din această cauză, câteodată este mai convenabil implementarea unei baze de date cu puțină redundanță, decât suportarea cheltuielilor pentru procedurile adiționale.

Normalizarea produce o bază de date care va fi ușor extensibil în viitor.

2.1 Proiectarea modelului conceptual local pe modelul logic local

Obiectiv: Verificarea modelului conceptual local pentru eliminarea structurilor care se pot implementa greu într-un SGBD și proiectarea modelului rezultat la modelul logic local.

În pasul întâi am pregătit un model conceptual bazat pe informațiile date de utilizator. Acest model trebuie prelucrat, pentru a putea fi ușor de prelucrat de sistemul de gestiune a bazelor de date. Obiectivele acestui pas sunt:

Eliminarea relațiilor M:N

– exemplu: relația Clienți închiriază Camere.

Se poate observa că un client poate rezerva mai multe camere, dar o cameră poate fi rezervată de mai mulți clienți. În acest caz se impune crearea unei noi entități numită Închirieri prin intermediul căreia relația de tip M:N se va sparge în două relații de tip M:1 și respectiv 1:N după modelul prezentat mai jos.

Eliminarea relațiilor complexe

– in modelul conceptual nu apar relații complexe

Eliminarea relațiilor recursive

– in modelul conceptual nu apar relații recursive

Eliminarea relațiilor cu atribute

– in modelul conceptual nu apar relații cu atribute

Reexaminarea relațiilor 1:1

– in modelul conceptual nu avem relații de tip 1:1

Eliminarea relațiilor redundante

– in modelul conceptual nu apar relații redundante

2.2 Crearea de relații peste modelul logic local

Obiectivul: Crearea de relații peste modelul logic.

Relația pe care un tip de entitate o are cu alt tip de entitate este reprezentată prin mecanismul cheie primară/cheie străină. Cheia străină pentru o entitate este reproducerea cheii primare altei entități. Pentru a decide entitățile unde vom include copia cheii primare a altei entități, trebuie înainte să identificăm entitățile “părinte” și “fiu”. Entitățile “părinte” se referă la acele entități ale căror chei primare se vor copia în entitățile “fiu”.

Pentru descrierea relațiilor vom folosii un limbaj de definire a bazei de date (Database Definition Language – DBDL). În acest limbaj, specificăm prima dată numele entității, urmat de atributele asociate între paranteze. După aceea identificăm cheia primară și toate cheile alternante, precum și/sau cheile străine.

Tipuri de entitate tari

Pentru tipurile de entități tari în modelul logic crearea unei relații include toate atributele entității. Pentru atributele compuse al unei entități, vom include numai atributele simple din compunerea atributului compus în descrierea entității.

Tipurile de entități slabe

Descrierea tipurilor de entități slabe se face la fel ca și tipurile de entități tari, cu o completare și anume, evidențierea cheii străine. De exemplu descrierea tipului de entitate de mai sus se descrie astfel:

Menționăm că în cazul acesta cheia străină este și în compunerea chei primare. Deci înainte de introducerea cheii străine, cheia primară nu identifica unic o entitate. La terminarea acestui pas, putem identifica cheile primare pentru toate tipurile de entități din modelul logic.

Tipurile de relații binare de tipul unu-la-unu (1:1)

Pentru fiecare tip de relație binară de tipul 1:1 între două tipuri de entitate E1 și E2 găsim o copie a cheii primare a tipului de entitate E1 în compunerea tipului de entitate E2, sub denumirea de cheie străină. Identificarea tipului de entitate “părinte” și a tipului de entitate “fiu” depinde de participarea entităților la relație. Tipul de entitate care participă parțial la relație este desemnat ca fiind “părinte” iar cel cu participare totală “fiu”. Dacă ambele tipuri de entitate participă parțial sau total la relație, atunci tipurile de entități se pot evidenția ca fiind “părinte” sau “fiu” arbitrar. În cazul în care participarea este totală, putem încerca să combinăm cele două tipuri de entități într-una singură. Această compunere poate să fie posibilă în cazul în care nici unul dintre cele două tipuri de entități nu mai ia parte la altă relație.

Tipurile de relații binare de tipul unu-la-multe 1:M

Pentru toate relațiile 1:M între două entități E1 și E2 în modelul logic de date, vom avea copia cheii primare a entității E1 în compunerea entității E2. Totdeauna entitatea de partea unu a relației este considerată entitate “părinte”, iar cealaltă entitate “fiu”.

Atributele cu mai multe valori

Pentru fiecare atribut A care permite mai multe valori din entitatea E1 în modelul logic de date, creăm o nouă relație care va conține atributul A împreună cu cheia primară a entității E1 pe post de cheie străină. Cheia primară a noii relații va fi atributul A, sau dacă este necesar, compunerea ei cu cheia primară al lui E1.

Relațiile superclasă/subclasă

Pentru fiecare relație superclasă/subclasă vom identifica superclasă ca fiind entitatea “părinte”, iar subclasa entitatea “fiu”. Există multe moduri de a reprezenta relația aceasta.

Documentarea relațiilor și a atributelor din cheile străine

Actualizăm dicționarul de date, introducând fiecare atribut nou introdus în compunerea unei chei la acest pas.

2.3 Validarea rezultatelor utilizând normalizarea

Obiectivul: Validarea modelului logic, utilizând tehnica normalizării.

Examinăm procesul de normalizare după cum am descris mai sus. Prin normalizare trebuie să demonstrăm că modelul creat este consistent, conține redundanță minimală și are stabilitate maximă.

Normalizarea este procesul prin care se decide dacă atributele pot sau nu să rămână împreună. Conceptul de bază a teoriei relațiilor este că atributele sunt grupate împreună pentru că există o relație logică între ele. Câteodată baza de date nu este cea mai eficientă. Acesta se argumentează prin următoarele:

Proiectarea normalizată organizează datele în funcție de dependențele funcționale. Deci acest proces este situat undeva între proiectarea conceptuală și cea fizică.

Proiectul logic nu este un proiect final. El ajută proiectantul să înțeleagă natura datelor în întreprindere. Proiectul fizic poate fi diferit. Există posibilitatea ca unele tipuri de entități să se denormalizeze. Totuși normalizarea nu este un timp pierdut.

Proiectul normalizat este robust și independent de anomaliile de actualizare prezentate.

Calculatoarele moderne au mult mai multă putere de calcul, ca cele de acum câțiva ani. Din această cauză, câteodată este mai convenabil implementarea unei baze de date cu puțină redundanță, decât suportarea cheltuielilor pentru procedurile adiționale.

Normalizarea produce o bază de date care va fi ușor extensibil în viitor.

Procesul de normalizare include următoarele etape mari:

Forma Normală Unu (1NF), eliminarea grupurilor repetitive;

Forma Normală Doi (2NF), eliminarea dependențelor parțiale de cheia primară;

Forma Normală Trei (3NF), eliminarea dependențelor tranzitive de cheia primară;

2.4 Validarea modelului prin tranzacții

Obiectivul: Verificarea ca modelul de date suporte toate tranzacțiile cerute de utilizator.

În acest pas se validează baza de date prin verificarea tranzacțiilor ce se cer de utilizator. Luând în considerare tipurile de entități, relațiile, cheile primare și străine, încercăm să rezolvăm manual cerințele utilizatorilor. Dacă reușim să rezolvăm fiecare tranzacție cerută, atunci înseamnă că modelul creat este valid. Dacă nu putem rezolva o tranzacție, atunci este foarte posibil să fi omis un atribut, o relație, sau o entitate din modelul de date.

Trebuie să examinăm în două posibilități, dacă baza de date suportă tranzacțiile cerute.

Lista camere ocupate din hotel:

"select * from inchirieri, clienti where inchirieri.sosire <= '$today' and

'$today' < inchirieri.plecare and inchirieri.cnp = clienti.cnp";

Lista clienți cazați la hotel într-o anumită perioadă

SELECT Nume, Prenume FROM Clienți, Închirieri WHERE Clienți.CNP = Închirieri.CNP AND Închirieri.Sosire < First AND Închirieri.Plecare > Second

Camerele rezervate din hotel

"select * from rezervari where sosire >= '$today'"

Clientii hotelului;

"select * from clienti"

Lista serviciilor oferite de hotel

SELECT * FROM Servicii;

Camerele inchiriate

"select * from inchirieri, clienti where inchirieri.sosire <= '$today' and '$today' <= inchirieri.plecare and inchirieri.cnp = clienti.cnp and clienti.nume='$Nume' and clienti.prenume='$Prenume' and inchirieri.nrCamera = '$Camera'";

Prețul unei camere

"select * from pretcamera,camere where camere.NrCamera = '$camera' and pretcamera.tipcamera = camere.tipcamera"

Servicii prestate

select * from serviciiprestate,servicii where '$sosire' <= data and data <= '$plecare' and nrcamera = '$camera' and serviciiprestate.serviciuid = servicii.serviciuid

2.5 Desenarea diagramei ER

2.6 Identificarea regulilor de integritate

Obiectivul: Identificarea regulilor de integritate pentru vederile utilizatorilor asupra hotelului.

Regulile de integritate sunt importante pentru a proteja baza de date împotriva posibilelor inconsistențe. Dacă este necesar, putem produce un proiect fizic de bază de date, pentru a putea vedea mai ușor ce reguli sunt necesare.

Vom considera cinci tipuri de reguli de integritate:

necesitatea datelor,

reguli asupra domeniului atributelor,

integritatea entităților,

integritatea referințelor,

regulile hotelului

Necesitatea datelor

Există atribute care nu pot conține valoarea nulă, ci trebuie să aibă totdeauna o valoare.

Reguli asupra domeniului atributelor.

Unele atribute au un domeniu de definiție bine definit. Aceste domenii trebuie respectate.

Integritatea entităților.

Cheia primară a entităților nu poate lua valori nule. De exemplu fiecare client trebuie să aibă un cod diferit de zero.

Cheile primare ale entitatilor sunt:

Integritatea relațiilor

Relațiile dintre entități sunt reprezentate prin copierea cheii primare a entității “părinte” in cheia străina a entității “fiu”. Integritatea relațiilor se refera la următorul fapt: daca cheia străina dintr-o entitate slaba conține o valoare, atunci aceasta valoare trebuie sa existe și in entitatea tare la care este asociata prin relație.

Exemplu:

Daca se înregistrează codul numeric personal al unui client in entitatea Închirieri atunci acesta trebuie sa existe și in entitatea Clienți.

2.7 Verificarea modelului logic local cu ajutorul utilizatorului.

Obiectivul: Convingerea că modelul creat reprezintă în totalitate realitatea care trebuie modelată în baza de date.

La acest pas modelul local logic este complet și este bine documentat. Înainte de a trece la pasul 3, trebuie verificat modelul, să fie conform cu realitatea. În cazul în care se găsesc diferențe, ne vom reîntoarce la pașii anteriori și modificăm cele necesare.

3 Crearea și validarea modelului global logic de date.

Obiectivul: Combinarea modelelor locale logice într-un model logic global care să reprezinte întreprinderea care este modelată.

A treia activitate majoră în proiectarea bazei de date logice este crearea modelului logic global, prin compunerea tuturor modelelor locale. După combinarea modelelor locale, trebuie validată modelul global prin tehnica de normalizare, după care prin tehnica tranzacțiilor. Acest proces utilizează aceleași tehnici pe care le-am descris la pașii 2.3. și 2.4.

Acest proces este foarte important în proiectarea bazei de date, pentru că el demonstrează că reprezentarea întreprinderii este independentă de orice utilizator, funcție sau aplicație. Activitățile din acest pas sunt:

Pasul 3.1. Compunerea modelelor logice locale într-un model logic global.

Pasul 3.2. Validarea modelului logic global.

Pasul 3.3. Verificarea posibilității de a completa baza de date în viitor.

Pasul 3.4. Desenarea diagramei ER finale.

Pasul 3.5. Verificarea modelului logic global cu ajutorul utilizatorului.

3.1 Compunerea modelelor logice locale într-un model logic global.

Obiectivul: Compunerea tuturor modelelor logice locale într-un model logic global al întreprinderii.

În cazul unui sistem mic, cu puține vederi ai utilizatorilor, este relativ ușor de a compune modelele logice locale. În cazul unui sistem mai mare însă, trebuie să urmăm un proces sistematic de realizare a modelului global. Pașii acestui proces sunt următoarele:

Verificarea numelor entităților și a cheilor lor primare.

Verificarea numelor relațiilor.

Compunerea entităților de pe view-urile locale.

Includerea (fără compunere) a entităților care apar pe doar una dintre view-uri.

Compunerea relațiilor de pe view-urile locale.

Includerea (fără compunere) a relațiilor care apar pe doar una dintre view-uri.

Căutarea entităților și a relațiilor care lipsesc (dacă există).

Căutarea cheilor străine.

Căutarea regulilor de integritate.

Desenarea modelului logic global.

Actualizarea documentației.

Cel mai ușor de compus mai multe modele locale este compunerea succesivă a două câte două dintre modele.

Verificarea numelor entităților și a cheilor lor primare.

Această verificare se face folosind și dicționarul creat în decursul pașilor de dinainte. Probleme apar doar atunci când:

Două entități au același nume, dar sunt de fapt diferiți.

Două entități sunt aceleași, dar nu au aceleași nume.

Probabil va fi necesară analizarea atributelor entităților, pentru a rezolva această problemă. În particular, putem utiliza cheia primară și numele entității, pentru a identifica entitățile echivalente.

1) Evidenta clienților hotelului :

In baza de date vor fi memorați clienții hotelului. Informațiile cu privire la clienți sunt : CNP, nume, prenume, adresa, sex, dataNastere, nrTelefon, locMunca. Clienții vor fi unic determinați de un atribut numit CNP (Cod Numeric Personal).

Evidenta camerelor din hotel :

In baza de date for fi reținute informații despre camerele din hotel. Datele despre o camera sunt : nrCamera, tipCamera. Camerele vor fi unic determinate prin nrCamera.

O camera va fi introdusa o singura data.

Evidenta închirierilor camerelor din hotel :

In baza de date vor fi memorate toate închirierile efectuate. Pentru fiecare închiriere se rețin : CNP, Sosire, Plecare, nrCamera, Npt. Închirierile sunt unic determinate prin: CNP, Sosire, nrCamera .

Evidenta rezervărilor :

In baza de date vor fi reținute de asemeni toate rezervările efectuate. Pentru fiecare rezervare se rețin : CNP, nume, prenume, tipCamera, Sosire, Plecare, Npt, dataRezervare. Rezervările sunt unic determinate prin: CNP, Sosire.

Evidenta Serviciilor :

In baza de date vor fi reținute toate serviciile oferite de hotel. Pentru fiecare serviciu se rețin : CodServiciu, Denumire, Preț. Serviciile sunt identificate unic prin CodServiciu.

Un serviciu va fi introdus o singură dată.

Evidenta Serviciilor prestate:

In baza de date vor fi reținute toate serviciile prestate de hotel unui anumit client : NrCamera, CodServiciu, Data, Cantitate. Serviciile sunt identificate unic prin : NrCamera, CodServiciu și Data.

Evidența prețului camerelor:

In baza de date vor fi reținute detalii referitoare la cameră: tipCameră (simplă, dublă, apartament), Cost. Prețul este identificat prin TipCameră

Verificarea numelor relațiilor.

Această activitate este asemănătoare celui descris la entități.

Compunerea entităților de pe view-urile locale.

Examinăm numele și atributele entităților ca vor fi compuse. Activitățile care se includ în acest pas sunt:

Compunerea entităților ce au aceleași nume și aceleași chei primare.

Compunerea entităților care au aceleași nume, dar cu chei primare diferite.

Compunerea entităților care au nume diferite, cu chei primare egale sau diferite.

Compunerea entităților care au aceleași nume și aceleași chei primare. În general entitățile cu aceleași chei primare reprezintă “lumea reală”, și deci pot fi compuse. Atributele care apar în entitățile de pe ambele view-uri, vor fi trecute doar o singură dată. Dacă într-un view apare un atribut compus, iar într-un alt view același atribut dar descompus în atribute simple, atunci vom întreba, dacă se poate, utilizatorii pentru a decide asupra formei de utilizare a atributului.

Compunerea entităților care au aceleași nume, dar au chei primare diferite. În astfel de situații, căutăm două entități care au aceleași nume și nu au aceleași chei primare, dar au aceleași chei candidat. Cele două entități pot fi compuse, urmând ca după compunere să alegem o cheie primară, restul rămânând chei alternante.

Compunerea entităților care nu au nume comune și nu au aceleași chei primare. Aceste entități se pot depista prin analiza atributelor celor două entități.

Includerea (fără compunere) a entităților care apar doar într-un view.

Pasul anterior identifică toate entitățile comune. Celelalte entități, se vor include în modelul logic global exact așa cum apar în view-ul respectiv.

Compunerea relațiilor de pe modelele locale.

În acest pas analizăm similitudinile dintre relații de pe diferite modele locale. În timpul compunerii relațiilor trebuie rezolvate și conflictele dintre relații, ca și regulile de cardinalitate și participare. Putem compune relații care au aceleași nume și același scop, sau același scop, dar nume diferite.

Includerea (fără compunere) a relațiilor care apar doar pe un view.

Relațiile care au rămas neincluse în modelul global după pasul anterior, se includ în modelul global fără modificare.

Căutarea entităților și relațiilor care lipsesc.

Este unul din cei mai grei pași din crearea modelului global. Trebuie căutate acele entități și relații, care s-au omis la pașii anteriori și n-au ajuns în modelul global.

Căutarea cheilor străine.

În decursul pașilor anterioare, s-au modificat entități, chei primare și chei străine. În acest pas verificăm dacă cheile străine sunt corecte în fiecare entitate fiu și efectuăm toate modificările necesare.

Căutarea regulilor de integritate

Verificăm dacă regulile de integritate a modelului global nu sunt în conflict cu regulile definite la modelele locale. Fiecare problemă de acest gen se rezolvă cu ajutorul utilizatorului sistemului.

Desenarea diagramei ER.

Acum desenăm diagrama ER pentru modelul global de date.

Actualizarea documentației.

Actualizăm documentația, ca să reflecte toate modificările aduse în acest pas modelului.

3.2 Validarea modelului logic global.

Obiectivul: Validarea modelului global logic de date, folosind normalizarea, după care folosind tranzacțiile cerute.

Acest pas este echivalent cu pașii 2.3. și 2.4., unde am validat modelul local de date.

3.3 Verificarea posibilităților de extindere a bazei de date în viitor.

Obiectivul: Determinarea ca dacă modelul se acomodează ușor la modificări oricât de mari ce pot intervenii în viitor.

Este important ca modelul creat să fie expansibil în viitor. Dacă modelul nu are această calitate, viața lui poate fi scurtă și pentru o mai mare modificare va trebui refăcută de la început.

3.4 Desenarea diagramei Entitz-Relationship finale.

Obiectivul: Desenarea unei diagrame ER, care să reprezinte modelul global de date al hotelului

.

3.5 Verificarea modelului global cu ajutorul utilizatorului.

Obiectivul: Verificarea că modelul global reprezintă în totalitate realitatea.

În acest moment modelul global este complet și documentat. Împreună cu utilizatorul sistemului se verifică acest model și se aduc eventualele corecturi prin întoarcerea la pasurile în cauză.

.

Capitolul 4 – Manual de utilizare

Introducere

Aplicația prezenta se utilizează pentru a gestiona închirierile și rezervările de camerei pentru un hotel, precum și introducerea informațiilor legate de clienții hotelului, a închirierilor, a rezervărilor, a datelor camerelor, a serviciilor și serviciilor prestate.

Înregistrarea

Utilizatori și parole

Pentru a putea accesa baza de date aveți nevoie de un utilizator și de o parola!

Aplicația are 3 tipuri de utilizatori:

• Administratorul — are drepturi depline asupra aplicației, în sensul ca poate adăuga informații noi, poate modifica informații deja existente, etc. (Loginare: User="Administrator", Parola=" Administrator")

• Recepționerul — poate doar sa adauge informații în baza de date, fără să poată modifica datele deja existente. Mai poate sa și vizualizeze rapoartele. Nu poate modifica aspectul ferestrelor sau relațiile dintre tabele. (Loginare: User="Recepționer", Parola="Recepționer")

• Director — poate doar sa vizualizeze informațiile și rapoartele. Nu poate adăuga sau modifica informații, sau relațiile dintre tabele. (Loginare: User="Director", Parola="Director")

După ce s-a introdus utilizatorul și parola se apasă pe butonul "Intra" și va apărea pagina principala.

Pagina principala

Despre pagina principala

O data introduse corect "Utilizator" și "Parola" se accesează pagina principala care conține un meniu din care se pot alege mai multe opțiuni. Aceasta pagina a fost făcută cu scopul măririi ușurinței de utilizare a aplicației.

Meniul conține următoarele câmpuri:

– Clienți. Meniul accesează baza de date pentru introducerea de clienți noi sau modificarea clienților deja existenți în baza de date.

Opțiunile sunt: – Introducere client;

– Caută client;

– Închirieri. Meniul accesează baza de date pentru a efectua închirieri și rezervări asupra camerelor hotelului.

Opțiunile sunt: – Închiriază camera;

– Rezervare camera;

– Camere. Meniul accesează baza de date pentru a efectua modificări asupra datelor camerei și a prețului acestora.

Opțiunile sunt: – Modificare date camera;

– Modificare preț camera;

– Servicii. Meniul accesează baza de date pentru a efectua prestări de servicii asupra camerelor hotelului și pentru adăugarea de noi servicii în baza de date.

Opțiunile sunt: – Prestări servicii;

– Adăugare servicii;

– Modificare servicii

– Rapoarte. Meniul conține mai multe opțiuni pentru vizualizarea unuia dintre rapoartele existente.

Opțiunile sunt: – Lichidare

– Afișează camere ocupate;

– Afișează camere rezervate;

– Afișează clienții hotelului;

– Procent ocupare camera zi/lună

Clienți

Despre meniul Clienți

Pe parcursul aplicației avem nevoie de a introduce un client nou în baza de date sau să căutam un anumit client existent, căruia sa ii modificam anumite date personale sau să îl ștergem din baza de date.

Toate aceste lucruri le putem realiza accesând meniul Clienți și alegând una din opțiunile: Introducere client sau Caută client.

Introducere clienți

In aceasta opțiune se poate introduce un client nou în baza de date.

Se completează toate câmpurile:

– Cod numeric personal – reprezintă un număr de 13 cifre din care prima cifra reprezintă sexul persoanei (1 – bărbat, 2 – femeie), următoarele 6 cifre reprezintă data nașterii, următoarele 2 cifre reprezintă codul localității în care s-a născut persoana respectiva, iar ultimele 4 sunt cifre date de autorități.

– Nume – se itroduce numele persoanei;

– Prenume – se introduce prenumele persoanei;

– Adresa – se introduce adresa completa a persoanei.

– Nr. telefon – numărul de telefon

– Loc munca – locul de munca al clientului.

După ce se completează aceste câmpuri, putem apasă pe butonul "Adăuga", iar daca toate câmpurile au fost introduse corect, în special CNP-ul, vom primi un mesaj de confirmare. Daca nu suntem siguri de ce am introdus, putem apasă pe butonul "Șterge" și atunci toate câmpurile pe care le-am completat se vor șterge.

Caută client

In aceasta opțiune putem modifica datele unui client sau sa îl ștergem definitiv din baza noastră de date.

După ce alegem o persoana, apăsam pe butonul "Modifica" și ne va apărea pagina următoare.

Când facem modificările trebuie sa avem grija ca datele pe care le modificam sa fie în standardele pe care le-am pus la introducerea unui client (in special la introducerea Codului numeric personal).

Daca se introduce greșit codul numeric personal va apărea o eroare .

Daca dorim sa ștergem clientul din baza noastră de date se va apasă pe butonul "Șterge".

Închirieri

Despre meniul Închirieri

In meniul Închirieri avem posibilitatea de a face închirieri și rezervări asupra camerelor hotelului prin alegerea uneia dintre opțiunile: Închiriază camera și Rezervare camera.

Închiriază camera

In aceasta opțiune se poate efectua o închiriere a unei camere.

Se alege o persoana existenta în baza de date și i se retine în memorie Codul numeric personal. Dacă persoana nu se află în baza de date, atunci va trebui mai întâi sa o introducem prin accesarea meniului Clienti>Introducere clienți .

Se retine în memorie data de sosire care este incrementata automat cu data curenta și data de plecare care trebuie sa fie neapărat mai mare ca data de sosire. În caz contrar va fi semnalizata o eroare când încercăm sa mergem mai departe.

După ce s-au completat aceste câmpuri căutam o camera libera pentru perioada pe care am selectat-o, prin apăsarea butonului "Caută".

Sunt afișate toate camerele care în momentul respectiv nu sunt închiriate sau sunt rezervate în perioada pentru care dorim sa facem închirierea.

Se bifează o camera în funcție de opțiunea clientului: simpla, dubla, garsoniera sau apartament.

După ce s-a făcut alegerea, se apasă butonul "Trimite" pentru a efectua închirierea.

Rezervare camera

In aceasta opțiune se poate face o rezervare asupra unei camere.

Trebuiesc completate toate câmpurile la fel ca și la introducerea unui client. Se mai completează câmpurile Sosire cu data de sosire și Plecare cu data de plecare pentru rezervarea în curs.

Daca nu suntem siguri de ce am introdus, putem apasă pe butonul "Șterge" și atunci toate câmpurile pe care le-am completat se vor șterge.

După ce s-au completat toate câmpurile se apasă butonul "Adăuga". Iar daca toate datele au fost introduse corect se va trece la alegerea camerei.

Sunt afișate toate camerele care în momentul respectiv nu sunt închiriate sau sunt rezervate în perioada pentru care dorim sa facem rezervarea.

Se bifează o camera în funcție de opțiunea clientului: simpla, dubla, garsoniera sau apartament.

După ce s-a făcut alegerea, se apasă butonul "Trimite" pentru a efectua rezervarea.

Camere

Despre meniul Camere

În meniul Camere se pot modifica anumite date asupra camerelor, cum ar fi: tipul camerei, prețul camerei.

Acestea se fac alegând una din opțiunile: Modificare date camere sau Modificare preț camera

Modificare date camere

Pe durata funcționării hotelului se mai pot produce unele modificări asupra camerelor, astfel se poate modifica tipul camerei.

Astfel putem transforma o cameră din simplă in dublă sau dublă în simplă, etc.

Pentru aceasta alegem camera careia dorim să îi facem modificarea și îi schimbam tipul prin alegerea din listă a unei opțiuni.

Pentru modificarea în baza de date se apasă pe butonul "Trimite."

Modificare preț cameră

Hotelul are diferite tarife la cazare în funcție de sezonul în care ne aflăm. Astfel prețurile trebuiesc modificate în baza de date. Acest lucru se poate face in aceasta secțiune

Ne sunt afisate toate tipurile de camere existente cu prețurile actuale.

Pentru a modifica un pret, se sterge cel existent si se adaugă noul preț, iar apoi se apasă pe butonul "Trimite".

Servicii

Despre meniul Servicii

Pe timpul șederii in hotel, clientul poate opta pentru anumite servicii pe care hotelul le pune la dispozitie.

Pentru adaugarea serviciilor asupra unei camere se alege opțiunea Prestări servicii.

Daca dorim sa adaugam servicii hoteliere noi, se alege obtiunea Adaugare servicii. (Aceasta este valabila doar pentru utilizatorul Administrator)

Daca dorim sa modificam un serviciu deja existent sau sa il eliminam din baza de date, se alege optiunea Modificare serviciu.

Obs. Nu se pot adauga servicii decat asupra unei camere inchiriate.

Prestari servicii

Se pot adăuga servicii suplimentare asupra unei camere închiriate ale caror prețuri se vor adăuga la costul total al camerei.

Pentru a adăuga un serviciu asupra unei camere se parcurg următorii pași:

Se alege o camera (Obs: apar doar camerele care sunt închiriate), se alege din lista un serviciu, data este incrementată automat cu data, ora și minutul din momentul solicitării, se mai alege cantitatea.

Pentru confirmarea tranzacției se apasă butonul "Trimite"

Adaugare servicii

În această secțiune se pot adauga servicii noi la baza de date.

Pentru a adauga un serviciu nou trebuiesc completate cele doua campuri:

Se introduce denumirea si pretul.

Pentru confirmare se apasă butonul "Trimite".

Modificare servicii

Daca dorim sa modificam pretul unui serviciu deja existent sau sa il eliminam din baza de date, putem sa o facem in aceasta sectiune.

Pentru aceasta alegem un serviciu din baza de date, bifăm una din cele două opțiuni, pentru optiunea "Modifica" se introduce noul preț al serviciului si se apasa butonul "Trimite", iar pentru "Sterge" se apasa direct butonul "Trimite" și se va elimia definitiv serviciul din baza de date.

Rapoarte

Despre meniul Rapoarte

Pe parcursul folosirii aplicatiei, este posibil ca utilizatorul sa necesite informatii despre datele aflate in baza de date. Rapoartele sunt creeate pentru vizualizarea facila a datelor necesare si scoaterea acestora la imprimanta. Astfel se pot vizualiza rapoartele:

– Se afiseaza totalul de plata pe o anumita camera in functie de perioada de sedere in hotel si de serviciile de care a beneficiat persoana respectiva.

– Lista tuturor camerelor ocupate;

– Lista tuturor camerelor rezervate;

– Lista cu toti clientii hotelului

– Procentul de ocupare al camerelor pe o anumita zi sau o anumita luna.

In viitor se vor implementa mai multe rapoarte in functie de cerintele pieței.

BIBLIOGRAFIE

[1] LUKE WELLING, LAURA THOMSON – Dezvoltarea aplicațiilor web cu PHP și MySQL, Editura Teora, Bucuresti, 2004

[2] BILL McCARTY – PHP4 – Editura Teora, București, 2002

[3] DUBOIS P. – MySQL, Editura Teora, București, 2001

[4] Curs PHP Intercer

http://www.sfu.ca/~yzhang/linux/webdb

http://www.mysql.com/doc.html

Similar Posts