Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Lucrul cu conexiuni persistente la baza de date

php



+ Font mai mare | - Font mai mic



Lucrul cu conexiuni persistente la baza de date

Conexiunile persistente la baza de date reprezintǎ o facilitate principalǎ a PHP-ului. Avantajul principal al conexiunilor persistente la baza de date constǎ in faptul cǎ timpul necesar pentru autentificare este redus semnificativ. Aceastǎ sarcinǎ poate fi realizatǎ prin "reutilizarea conexiunii". PHP pǎstreazǎ o rezervǎ internǎ a conexiunilor deschise la o anumitǎ bazǎ de date, a utilizatorului si a sistemului gazdǎ. De fiecare datǎ cand utilizatorul doreste sǎ se conecteze la baza de date, PHP verificǎ dacǎ existǎ o conexiune internǎ liberǎ si o atribuie noului utilizator. Dacǎ nu existǎ o conexiune liberǎ, PHP incearcǎ sǎ stabileascǎ o nouǎ conexiune la baza de date. Imediat cum utilizatorul se deconecteazǎ, conexiunea nu va fi terminatǎ, ea fiind disponibilǎ din nou in rezerva de conexiuni libere. Cu ajutorul acestui algoritm, sunt salvate multe procese de autentificare a utilizatorilor, fiind obtinutǎ o performantǎ sporitǎ.



Exemplu

Dacǎ utilizǎm PostgreSQL 7.2, putem observa douǎ procese care ruleazǎ la initializarea sistemului. Putem verifica acest lucru prin redirectarea tabelului de procese cǎtre grep:

salexis@b2-1$ ps ax | grep postgres

21647 pts/4 S 0:00 postgres: stats buffer process

21649 pts/4 S 0:00 postgres: stats collector process

4338 pts/4 S 0:00 grep postgres

Vom scrie un script care doar se conecteazǎ la baza de date si afiseazǎ un mesaj:

<?php

$dbh = pg_connect('host=localhost user=postgres dbname=phpdb');

if (!$dbh)

else

?>

Dupǎ cum putem observa, mumǎrul de procese care ruleazǎ nu s-a schimbat, desi conexiunea la baza de date nu a fost inchisǎ explicit.

salexis@b2-1$ ps ax | grep postgres

21647 pts/4 SW 0:00 postgres: stats buffer process

21649 pts/4 SW 0:00 postgres: stats collector process

4344 pts/4 S 0:00 grep postgres

Toate procesele pornite de PHP au fost eliminate fǎrǎ nici o problemǎ. In continuare vom scriptul PHP anterior prin utilizarea comenzii de conectare la baza de date pg_pconnect:

<?php

$dbh = pg_pconnect('host=localhost user=postgres dbname=phpdb');

if (!$dbh)

else

?>

Scriptul realizeazǎ acelasi lucru, dar a fost stabilitǎ o conexiune persistentǎ la baza de date. Vom verifica acum toate procesele PostgreSQL active:

salexis@b2-1$ ps ax | grep postgres

21647 pts/4 S 0:00 postgres: stats buffer process

21649 pts/4 S 0:00 postgres: stats collector process

4347 pts/4 S 0:00 postgres: postgres phpdb 127.0.0.1 idle

4349 pts/4 S 0:00 grep postgres

O conexiune activǎ este incǎ in memorie deoarece nu a fost inchisǎ la sfarsitul scriptului PHP. Dacǎ executǎm scriptul PHP mai mult de o datǎ, PostgreSQL nu va crea un nou proces backend deoarece backend-urile care ruleazǎ pot fi reutilizate, aceasta salvand timp si reducand incǎrcarea bazei de date.

Conexiunile persistente si performanta

In continuare vom studia efectele conexiunilor persistente asupra vitezei. Vom crea un script care se conecteazǎ si deconecteazǎ la baza de date de 25000 de ori. In plus, este calculat timpul mediu necesar de conectare la baza de date.

<?php

$number = 25000; # numarul de conexiuni

$begin = time(); # Timp de start

for ($i = 0; $i < $number; $i++)

pg_close($dbh);

}

$end = time(); # Timp de sfarsit

$diff = $end - $begin; # Timp total

$tpconn = $diff / $number; # Timp pe conexiune

# afiseaza rezultatul

echo 'Inceput: $begin<br>n';

echo 'Sfarsit: $end<br>n';

echo 'Timp total: $diff<br>n';

printf('Timp pe conexiune: %9.8f<br>n', $tpconn);

?>

La inceputul scriptului este calculat timpul de inainte de conectare. Timpul este returnat in secunde de la 1 ianuarie 1970. In continuare sunt stabilite conexiunile persistente la baza de date. Dupǎ aceasta, timpul este extras din nou si sunt realizate calcule. Valorile afisate sunt:

Inceput: 1132163153
Sfarsit: 1132163166
Timp total: 13
Timp pe conexiune: 0.00052000

Dupǎ cum se poate observa, au fost stabilite 25000 de conexiuni in 13 secunde dacǎ o rezervǎ de conexiune este deja in memorie. Timpul necesar pentru stabilirea unei conexiuni este foarte mic deoarece PHP nu a trebuit sǎ cearǎ PostgreSQL-ului autentificarea utilizatorului. Cu conexiuni nonpersistente situatia este diferitǎ; de fiecare datǎ cand este stabilitǎ o conexiune, un proces backend trebuie pornit si PostgreSQL trebuie sǎ verifice baza de date, utilizatorul si parola.

In urmǎtorul exemplu ne vom conecta la aceeasi bazǎ de date utilizand acelasi script, utilizand conexiuni nonpersistente. Vom utiliza 250 de conexiuni in loc de 25000. Rezultatul va fi:

Inceput: 1132164436
Sfarsit: 1132164444
Timp total: 8
Timp pe conexiune: 0.03200000

Au fost necesare 8 secunde pentru a stabili 250 de conexiuni (0.03 secunde pentru a stabili o conexiune). De retinut cǎ conexiunea este stabilitǎ la masina localǎ unde toti utilizatorii sunt trusted.

Vom modifica pg_hba.conf si vom rula scriptul utilizand IP-ul oficial al masinii:

local all trust

host  all 127.0.0.1 255.255.255.255 trust

hostssl phpdb 194.176.165.12 255.255.255.255 crypt

Pentru a activa modificǎrile vom restarta PostgreSQL (vom activa SSL utilizand flag-ul -l cand pornim postmaster-ul). Vom crea si un nou utilizator:

phpdb=# CREATE USER testuser WITH PASSWORD 'mypasswd';

CREATE USER

Vom utiliza scriptul de conectare la baza de date:

<?php

$number = 250; # numarul de conexiuni

$begin = time(); # Timp de start

for ($i = 0; $i < $number; $i++)

pg_close($dbh);

}

$end = time(); # Timp de sfarsit

$diff = $end - $begin; # Timp total

$tpconn = $diff / $number; # Timp pe conexiune

# afiseaza rezultatul

echo 'Inceput: $begin<br>n';

echo 'Sfarsit: $end<br>n';

echo 'Timp total: $diff<br>n';

printf('Timp pe conexiune: %9.8f<br>n', $tpconn);

?>

De aceastǎ datǎ procesul de autentificare necesitǎ mai mult timp deoarece ne-am conectat la baza de date utilizand SSL:

Inceput: 1132165428
Sfarsit: 1132165436
Timp total: 26
Timp pe conexiune: 0.03200000

In scenariul anterior, lucrul cu conexiuni persistente la baza de date este de 2600 de ori mai rapid decat lucrul cu conexiuni SSL nonpersistente (desigur este greu de comparat conexiunile persistente cu cele SSL nonpersistente). Cand lucrǎm cu baze de date pentru a cosntrui un sit Web dinamic, timpul necesar pentru conectarea la baza de date este adesea subestimat.

Pericole si probleme hardware

Conexiunile persistente la baza de date pot fi periculoase in privinta consumului de memorie si configurǎrii sistemului.

Tranzactii

Conexiunile persistente la baza de date si tranzactiile sunt elemente critice. Dacǎ nu asigurǎm un debug la aplicatie putem avea probleme grave dificil de rezolvat.

Exemplu:

Vom vrea o tabelǎ:

phpdb=# CREATE TABLE course (id int4, name text, description text);

CREATE TABLE

Vom testa un script care foloseste tranzactii explicite:

<?php

$dbh = pg_pconnect('user=postgres dbname=phpdb');

if (!$dbh)

$stat = pg_exec($dbh, 'BEGIN');

if (!$stat)

echo 'incerc sa introduc date <br>n';

$sql = 'INSERT INTO course VALUES (9, 'Programare C', NULL)';

$stat = pg_exec($dbh, $sql);

if (!$stat)

echo '<a href='data2.php'>continua</a>';

pg_close($dbh);

?>

Tranzactia a fost pornitǎ si o inregistrare a fost adǎugatǎ in tabelǎ. La prima executia a scriptului, nu apare nici o problemǎ:

incerc sa introduc date
continua

Tranzactia nu poate fi pornitǎ deoarece o tranzactie este deja in curs. Sǎ vedem continutul tabelei:

phpdb=# SELECT * FROM course;

id | name | description

(0 rows)

Nu a fost introdusǎ nici o inregistrare in tabelǎ, dar problema este cǎ sistemul este blocat intr-un anumit mod. Cauza este cǎ nu existǎ un script care sǎ comitǎ tranzactia si procesul backend nu este distrus automat. Problema se poate rezolva doar restartand baza de date.

Managementul sesiunilor

Pentru aplicatii de tipul Web shop, este necesar sǎ trecem informatia de pe un ecran pe altul. Dacǎ cantitatea de informatie care trebuie trimisǎ pe mai multe ecrane creste, formularele si campurile ascuse nu sunt necesare pentru a ne satisface cerintele. Managementul sesiunilor cu Cookies

O modalitate de a identifica utlizatorii si de a stoca date este utlizarea de cookie. HTTP nu este un protocol orientat pe conexiune, cookie putand fi utilizat pentru a simula un anumit tip de interactiune permanentǎ cu serverul. Idea principalǎ este de a stoca informatia direct pe sistemul clientului. Cand un sit este solicitat, informatia dintr-un cookie adecvat este trimisǎ cǎtre server automat. Serverul nu se uitǎ dupǎ cookie: informatia este trimisǎ cǎtre server de cǎtre browser automat. Exemplu:

<?php

setcookie ('YourName', 'John & Vangelis');

header('Content-type: text/html');

echo 'Numele tau a fost adaugat in cookie <br>n';

?>

<a href='checkcookie.php'>Treci pe pagina urmatoare</a>

Scriptul seteazǎ un cookie numit YourName. Valoarea cookie-ului este John & Vangelis. Acest cookie a fost setat inainte de a trimite header-ul clientului. Dupǎ aceasta este afisat un sir si o legǎturǎ. Dacǎ executǎm clic pe legǎturǎ, va fi apelat scriptul checkcookie.php:

<?php

echo 'Afisare informatie stocata in cookie:<br>n';

if ($YourName)

else

?>

Scriptul verificǎ dacǎ $YourName existǎ. Dacǎ variabila existǎ, continutul acesteia va fi afisat pe ecran. De remarcat cǎ nu existǎ un buton submitm datele din cookie fiind disponibile pe ecranul urmǎtor. La un clic pe legǎturǎ vor fi afisate douǎ linii:

Afisare informatie stocata in cookie

Date stocate in cookie: John & Vangelis

A doua linie contine datele stocate in cookie. Componentele unui cookie pot fi:

- name - defineste numele unui cookie;

- value - contine valoarea unui cookie;

- expires - defineste timpul dupǎ care un cookie va expira;

- domain - defineste domeniile pentru care cookie este valid;

- path - defineste calea pentru care cookie este valid;

- secure - restrictioneazǎ transmiterea de cookie cǎtre un canal sigur;

In exemplu anterior, am vǎzut cum un cookie poate fi generat sǎ dureze mereu. In anumite cazuri nu este util; dacǎ dorim sǎ utilizǎm un cookie doar pentru stocarea continutului unui shopping cart, nu dorim ca datele sǎ rǎmanǎ in cookie pentru totdeauna. Putem defini perioada de timp pentru care un cookie este valid. Ex:

<?php

$t = time()+3600*24;

setcookie('yourname','Shelley',$t,'/','postgresql.org');

header('Content-type: text/html');

echo 'Numele tau a fost adaugat in cookie<br>n';

?>

<a href='checkcookie.php'>Treci pe pagina urmatoare</a>

Ora curentǎ este calculatǎ prin apelarea functie PHP time. Dupǎ aceasta sunt adǎugate 24 ore la acest etalon de timp (timestamp) si valoarea acesuia este preluatǎ pentru a spune cookie-ului cǎ este valid pentru intregul domeniu numit postgresql.org.

Masina din exemplu pe care a fost testat nu apartine domeniului postgresql.org, si nu va fi disponibilǎ nici un fel de datǎ cand executǎm clic pe legǎturǎ:

Afisare informatie stocata in cookie:
nici o data nu a fost stocata in cookie

In urmǎtorul exemplu, vom vedea cum stergem valoarea unui cookie:

<?php

if ($yourname)

else

echo '<a href='main.php'>Reincarca pagina</a>';

?>

Scriptul genereazǎ un cookie dacǎ nu a fost setat nici un cookie si sterge cookie dacǎ cookie a fost deja setat deja. Dupǎ cum putem observa, un cookie poate fi sters prin setarea celui de-al treilea parametru la data anterioarǎ. In acest mod, un cookie este marcat ca fiind expirat si este sters automat. Dacǎ executǎm scriptul de douǎ ori, rezultatul va fi:

stergem cookie .

valoarea cookie a fost: Shelley

Reincarca pagina

Cookie sunt usor de utilizat, dar pot apare anumite probleme:

- utilizatorii au dezactivat cookie din motive de securitate;

- utilizarea acestora in combinatie cu conexiuni HTTP sigure si nesigure.

Managementul sesiunilor

Concepul de managemnt al sesiunilor este mai sofisticat decat lucrul cu cookie. Cu ajutorul sesiunilor, este posibil sǎ urmǎrim un utilizator fǎrǎ a lucra cu campuri ascunse sau cookie explicit. Aceasta este un mare avantaj; se castigǎ flexibilitate si lucrul cu sesiuni ne ajutǎ sǎ implementǎm componente mult mai eficient.

Cand un utilizator viziteazǎ un sit Web, un id unic este atribuit acestuia. Id-ul sesiunii este de asemena stocat intr-un cookie sau este trecut cǎtre urmǎtorul script via URL.

Pe langǎ utilizarea id-ului de sesiunii, purem inregistra variabilele. Aceste variabile pot fi usor extrase si este o sarcinǎ usoarǎ sǎ trecem informatia dintr-un formular in altul.

Id-urile sesiunii

Inainte de a lucra cu variabilele inregistrate, vom vedea un exemplu in care sesiunile sunt utilizate.

<?php

@session_start();

$sid = session_id();

echo 'Apel de la a.php<br>n';

echo 'Acesta este id-ul sesiunii: $sid<br>n';

?>

Primul lucru a fost inceperea sesiunii (pate fi ca un tip de inregistrare). In continuare este generat id-ul sesiunii. Scriptul va afisa informatia pe ecran:

Apel de la a.php
Acesta este id-ul sesiunii: d11b6df32697826c6b784754fdfd45a9

Este afisat id-ul sesiunii. Dacǎ executǎm scriptul incǎ o datǎ, id-ul sesiunii va fi acelasi.

Fisierul a.php este punctul de pornire. Fisierul b.php este al doilea fisier din exemplu. Vom incepe cu a.php:

<?php

@session_start();

$sid = session_id();

echo 'Apel de la a.php<br>n';

echo 'Acesta este id-ul sesiunii: $sid<br><br>n';

echo 'Mergem la b.php: ';

echo '<a href='b.php'>b.php</a>';

?>

Codul pentru b.php este:

<?php

@session_start();

$sid = session_id();

echo 'Apel de la b.php<br>n';

echo 'Aceasta este id-ul sesiunii: $sid<br><br>n';

echo 'Mergem la a.php: ';

echo '<a href='a.php'>a.php</a>';

?>

Dacǎ mergem la a.php, vom vedea id-ul sesiunii. Dacǎ mergem la b.php, acelasi id de sesiune va fi afisat. Dacǎ inchidem brwser-ul si incepem din nou, id-ul sesiunii va fi diferit. Acest lucru este important deoarece ne ajutǎ sǎ aflǎm cand o sesiune este terminatǎ.

Vom modifica b.php din nou:

<?php

setcookie(session_name(),'','','/');

@session_start();

$sid = session_id();

echo 'Apel de la b.php<br>n';

echo 'Acesta este id-ul sesiunii: $sid<br><br>n';

echo 'Mergem la a.php: ';

echo '<a href='a.php'>a.php</a>';

echo '<br>numele sesiunii: '.session_name().'<br>n';

?>

Dupǎ cum putem observa, sesiunile pot fi manipulate folosind cookie. In acest caz este setat un cookie. Cookie are acelasi nume cu sesiunea curentǎ. O sesiuen poate fi usor stearsǎ prin setarea unui cookie la o valoare invalidǎ ca in acest exemplu. Cand rulǎm scriptul putem observa cǎ id-ul sesiunii se schimbǎ cand apelǎm a.php.

PHP oferǎ si o functie numitǎ session_destroy().

Inregistrarea variabilelor

Trecerea datelor de pe un ecran pe altul este o sarcinǎ importantǎ. Librǎriile de sesiuni PHP oferǎ o modalitate usoarǎ pentru a stoca variabilele pe mai multe ecrane. Variabilele pot fi inregistrate intr-o sesiune. Aceste variabile vor fi disponibile automat si pot fi utilizate de utilizator in sigurantǎ.

Vom crea din nou un scenariu din douǎ fisiere. Fisierul a.php este:

<?php

@session_start();

$sid = session_id();

echo 'Apel de la a.php<br>n';

echo 'Acesta este id-ul sesiunii: $sid<br><br>n';

echo 'mesaj: $message<br>n';

$message = 'Inregistrat in a.php<br>n';

session_register('message');

echo 'Mergem la to b.php: ';

echo '<a href='b.php'>b.php</a>';

?>

Dupǎ ce sesiunea porneste, id-ul sesiunii este afisat. In plus, o variabilǎ numitǎ $message va fi afisatǎ pe ecran. In continuare, $message este inregistrat in sesiune. Fisierul b.php este:

<?php

@session_start();

$sid = session_id();

echo 'Apel de la b.php<br>n';

echo 'Acesta este id-ul sesiunii: $sid<br><br>n';

echo 'mesaj: $message<br>n';

$message = 'Inregistrat in b.php<br>n';

session_register('message');

echo 'Mergem la a.php: ';

echo '<a href='a.php'>a.php</a>';

?>

A.php afiseazǎ @message si il inregistreazǎ din nou. Cand rulǎ scriptul, putem observa cǎ o variabilǎ va fi disponibilǎ in urmǎtorul script cand executǎm clic pe legǎturǎ. In a.php, $message, care a fost inregistrat in b.php, va fi afisat. In b.php, variabila definitǎ in a.php va fi afisatǎ. Rezultatul lui b.php va fi:

Apel de la b.php

Acesta este id-ul sesiunii: 963d468e5e21042a6175af7a53f0cc95

message: Inregistrat in a.php

Mergem la a.php:a.php

Singurul lucru care trebuie sǎ-l facem este sǎ-i spunem PHP-ului ce variabile trebuie trecute in urmǎtoare paginǎ. Vom modifica din nou b.php:

<?php

@session_start();

$sid = session_id();

echo 'Apel de la b.php<br>n';

echo 'Acesta este id-ul sesiunii: $sid<br><br>n';

echo 'mesaj: $message<br>n';

echo 'Mergem la a.php: ';

echo '<a href='a.php'>a.php</a>';

?>

De aceastǎ datǎ nu este inregistratǎ nici o variabilǎ in b.php. In acest caz continutul lui $message va fi afisat in "Inregistrat in a.php". Acest lucru este important deoarece datele nu pot fi pierdute cand inregistrǎm variabilele pe mai multe ecrane.

In continuare vom vedea ce se intamplǎ cu array-urile si obiectele:

<?php

@session_start();

$sid = session_id();

$message = unserialize($x);

echo 'mesaj 0: '.$message[0].'<br>';

echo 'mesaj 1: '.$message[1].'<br>';

$message[0] = 'campul numarul unu n';

$message[1] = ' campul numarul doi n';

$x = serialize($message);

echo 'versiune dispusa in serie: <br> $x<br>n';

session_register('x');

echo '<br>Repornim a.php: <br>';

echo '<a href='a.php'>a.php</a>';

?>

Cand lucrǎm cu array-uri este foarte important sǎ le dispunem in serie inainte de a apela session_register; altfel, sistemul nu va merge. Dispunerea in serie inseamnǎ cǎ un obiect sau un array este transformat intr-un sir. In acest mod, poate fi procesat la fel ca alt sir. Aceasta este modalitatea cea mai rapidǎ de a trece obiecte de pe un ecran pe altul. Pentru a elimina un obiect dintr-un sir dispus in serie, putem folosi unserialize.

Rezulatul este:

mesaj 0: campul numarul unu
mesaj 1: campul numarul doi
versiune trimisa in serie:
a:2:

Repornim a.php:
a.php

Dupǎ cum putem observa, valorile sunt disponibile si este afisat sirul dispus in serie. Dacǎ dorim sǎ vedem dacǎ o variabilǎ a fost deja inregistratǎ, putem utiliza comanda session_is_registered. Ex:

<?php

@session_start();

$sid = session_id();

$message = unserialize($x);

$message[0] = ' campul numarul unu n';

$message[1] = ' campul numarul doi n';

$x = serialize($message);

session_register('x');

$val = session_is_registered('x');

echo 'val: $val<br>n';

session_unregister('x');

$val = session_is_registered('x');

echo 'val: $val<br>n';

echo '<br>Repornim a.php: <br>';

echo '<a href='a.php'>a.php</a>';

?>

Rezultatul afiseazǎ ce se intamplǎ dacǎ executǎm scriptul de douǎ ori:

val: 1
val:

Repornim a.php:
a.php

Prima datǎ, session_is_registered returneazǎ 1 deoarece $x a fost inregistrat in linia anterioarǎ. In continuare, $x este neinregistrat, session_is_registered nemaireturnand 1.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1216
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved