Controlul iesirii in PHP – Output Buffering
0Utilizarea unei zone tampon pentru returnarea rezultatelor este o tehnica de programare care poate aduce avantaje aplicatiei in diverse cazuri. Controlul iesirii (sau Output Control ori Output Buffering) se refera la controlul informatiilor trimise de la server catre client. Este util de cele mai multe ori sa putem controla cum se vor trimite informatiile(de regula codul HTML generat) astfel incat pe parcursul generarii lui sa putem trimite alte diverse header-e.
Protocolul HTTP este un protocol de comunicare pe internet foarte des intalnit, mai ales in cadrul serverelor web. Apache este unul care implementeaza acest protocol la comunicarea cu clientii care fac diverse cereri acestuia. Anatomia sa presupune, atat la cerere cat si la raspuns, trimiterea unor header-e(prin care se vor specifica in ce fel sa fie interpretat mesajul ce urmeaza a fi trimis) si mesajul propriu-zis, care poate fi o cerere sau informatii formatate. Astfel, presupunand ca vrem accesarea site-ului google.com, browser-ul va trimite un mesaj de cerere catre webserver-ul respectiv cerand accesul la o pagina de pe server, in cazul nostru cea implicita. Serverul web va raspunde clientului cu un set de header-e prin care se va specifica ce tip de formatare va avea informatia ce urmeaza sa o primeasca, ce lungime are, ce codare de caractere trebuie sa foloseasca pentru a putea fi interpretata corect etc.
In cazul unui server pe care ruleaza PHP si in cazul in care serverul primeste o cerere pentru un fisier ce contine un script PHP, serverul va incepe sa trimita catre client informatiile odata cu:
- intalnirea unui tag HTML
- la orice apel al functiei echo, print, var_dump sau print_r
- chiar la o linie goala intalnita in orice fisier php, chiar si intre blocurile de cod php
echo "Serverul Apache va incepe trimiterea de informatii din acest moment."; ?>
Corpul fisierului HTML generat pentru IP-ul
In exemplul de mai sus interpretorul de PHP va transmite serverului Apache sa inceapa trimiterea datelor catre client chiar de la instructiunea echo, si nu de la intalnirea tagului de marcarea a inceputului de document HTML cum ar fi fost normal. Sa presupunem insa ca, pentru fiecare accesare a acestui fisier, dorim sa retinem continutul returnat utilizatorului intr-un fisier pe server, desi pentru exemplul furnizat, motivatia acestei operatiuni este nu mai mult decat didactica. Vom folosi asadar functiile PHP pentru controlul iesirii, functii fare pot fi recunoscute usor dupa prefixul ob_.
ob_start(); echo "Serverul Apache va incepe trimiterea de informatii din acest moment."; ?>
Corpul fisierului HTML pentru IP-ul
$html = ob_get_contents(); $f = fopen('log.txt', 'w'); fwrite($f, $html); fclose($f); ob_end_flush() ?>
Functia ob_start marcheaza inceperea memorarii informatiilor generate de scriptul PHP fara insa a le trimite catre client. In orice moment al scriptului, inainte de trimiterea codului HTML generat, se pot accesa informatiile din zona tampon folosind functia ob_get_contents, lucru pe care l-am facut si noi pentru a stoca informatiile pe server. La final functia ob_end_flush va trimite informatiile generate catre client si va opri stocarea lor in zona tampon.
Serverul web are totusi niste header-e standard pe care le trimite odata cu fiecare cerere pe care o primeste. Din PHP aceste header-e se pot modifica sau se pot adauga folosind functia header. Cum aceasta functie va trimite direct header-ul catre client, ea trebuie apelata inainte ca orice continut sa fie trimis catre client, nerespectarea acestei reguli va genera un avertisment. Pentru a evita acest lucru se foloseste controlul iesirii.
Iesirea comprimata
Un avantaj al stocarii unei pagini web la server pana aceasta a fost generata complet este acela ca, in cazul unui volum mare de date transferat, acestea pot fi comprimate pentru a facilita transportul lui peste internet catre clientul care a facut cererea, obtinand astfel un timp mai bun de raspuns. Functia ob_start poate primi ca prim parametru numele unei functii care va fi aplicata asupra codului generat dupa ce acesta a fost generat complet. Astfel, functia ob_gzhandler a fost special creata pentru a comprima datele generate folosind formatul gzip. Urmatorul exemplu va dispune trimiterea de date comprimate catre client:
ob_start("ob_gzhandler");
O alta utilitate a acestei functii o reprezinta faptul ca atunci cand suntem nevoiti sa trimitem headerele dupa ce am permis afisarea informatiilor catre client vom primi o eroare : „Headers allready sent….” .
Adaugand pe prima linie a fisierului :
< ?php ob_start(); ?>
iar pe ultima
< ?php ob_flush(); ?>
va rezolva aceasta problema, deoarece el va pastra in memorie tot ce trebuie afisat catre client, va trimite toate headerele si abia la sfarsit va elibera memoria afisand.
Autor: George Enciu
Daca acest articol contine o greseala, selecteaza cuvintele sau fraza gresita si tasteaza combinatia de taste Shift + Enter sau apasa click aici pentru a o raporta. Multumim!