... Programare Multimedia ...

Cap 5. Limbaje Server Side Script.

Tehnologiile Server Side Scripting permit crearea de aplicatii Web complexe prin procesarea datelor pe server si generarea unor pagini in mod dinamic. In felul acesta se pot interfata aplicatiile Web cu servere de baze de date sau servere de posta electronica. Limbajele Server Side Script au posibilitatea de a accesa datele citite in formulare HTML si implementeaza biblioteci de acces la resurse externe cum ar fi o baza de date. Spre deosebire de tehnologii mai vechi care realizau acelasi deziderat (Ex. CGI) server side scripting asigura o viteza si o securiatate sporite. In general interpretoarele limbajelor SSS sunt integrate sub forma de module chiar in serverul de Web. Exemple de limbaje SSS: ASP, ColdFusion Markup Language, JSP, PHP, Perl, Phyton, Rubi etc.

5.1. Limbajul PHP 

Limbajul PHP este un un limbaj de tip server side script creat special pentru Web. Liniile de cod PHP trebuie incluse in interiorul unei pagini Web scrisa in HTML. Utilizand PHP pot fi construite usor:

    • mecanisme de autentificatre utilizatori
    • sisteme de gestiune a continutului
    • sisteme de tip "web based e-mail"
    • gestionare de liste de mesaje
    • forumuri Web
    • generarea automata de documente pdf
Serverul Web incarca pagina din sitemul de fisiere propriu si, constatand ca este vorba de o pagina PHP o trimite interpretorului PHP. Interpretorul PHP parcurge pagina si executa instructiunile PHP intalnite. Instructiunile PHP au ca si scop pricipal acela de a genera cod HTML. De asemenea, codul HTML din fisierul original este copiat pur si simplu la iesire. Interpretorul PHP transmite inapoi catre server fisierul transformat prin interpretarea codul PHP. Acest fisier va contine doar cod HTML (eventual si Client Side Script etc.) dar nu si cod PHP.
Fata de aceste limbaje SSS, PHP are cateva avantaje importante:
    • performanta buna
    • interfete cu o mare variatate sisteme de gestiune a bazelor de date
    • biblioteci puternice care acopera toate operatiilor Web uzuale
    • gratuit (http://www.php.net) /cost scazut (http://www.zend.com)
    • usor de invatat si utilizat
    • portabil
    • disponibil ca si cod sursa
Pentru includerea codului PHP intr-o pagina HTML se prefera de obicei stilul XML:
<?php ... ?>

Tipuri de date PHP
Integer - utilizat pentru numere intregi
Double - utilizat pentru numere reale
String - utilizat pentru siruri de caractere
Array - utilizat pentru a stoca serii de date 
Object - utilizat pentru a retine obiecte
Pdfdoc, Pdfinfo - vezi sectiunea 5.2
Specific: numele variabilelor PHP sunt prefixate de semnul $ ( $var1 = "sirul 1"; ).
Ca si in C, identificatorii PHP sunt "case sensitive".
Pentru definirea constantelor se poate folosi instructiunea define
(define("PI",3.14); $alfa = 2*PI;).
La PHP domeniul de vizibilitate pentru variabile poate fi:
    • Global - varibilele globale, definite in afara functiilor sunt vizibile in tot fisierul curent, mai putin in interiorul functiilor.
    • Local unei functii - variabilele create in functii sunt vizibile doar in interiorul acestora.
    • Global in interiorul unei functii - acest tip de varibile sunt folosite pentru a accesa variabilele globale cu acelasi nume.

    Accesarea datelor din formularele HTML
Accesarea varibilelor din formularele HTML se face prin intermediul tablourilor predefinite $_POST si  $_GET (dependent de metoda declarata de formular). Exemplul 5.1: citire din formular.

Operatori PHP

Operatorii PHP sunt in general identici cu cei din limbajul C cu cateva exceptii:
Operatorul de concatenare siruri "." ($sir1." abc").
Substitutia de variabile in sir "" ("$var" fata de '$var').
Operatorul de referire "&" ($b = &$a;).
Operatorul de testare a identitatii "===" ($a===123).
Operatorul de suprimare a erorilor "@" ($a = @($b / 0 );).
Operatorul de executie "`" (`dir c:\`).

Instructiuni PHP
Instructiunea if:
if (expr)
     instructiuneAdevarat;
else
     instructiuneFals;

Instructiunea elseif:
if (expr1)
     instructiune1
elseif (expr2)
     instructiune2
...
else
    instructiuneN

Instructiunea switch:
switch (expr) {
    case valoare_1:
         instructiune_1;
         break;
    case valoare_2:
         instructiune_2;
         break;
       ...
    case valoare_n:
         instructiune_n;
         break;
    defaut:
         instructiune_default;
}

Instructiunea while:
while (expr)
     instructiune;

Instructiunea do-while:
do
   instructiune
while (expr);

Instructiunea for:
for (expr1; expr2; expr3) 
                  instructiune;

Instructiunea foreach:
$tablou = array (el0, el1, ... el_n);
foreach (tablou as val_el_crt)
                     instructiune;
$tablou = array( "cheie1" => el1, "cheie2" => el2, ... "cheie_n" => el_n);
foreach (tablou as cheie=>val_el_crt)
                     instructiune;

Exemplul 5.2: utilizare tablouri.
Instructiuni control repetitii: continue, break si return.

Functii PHP
Functiile sunt utilizate pentru a grupa instructiunile care executa un anumit algoritm. Ele permit refolosirea codului ori de cate ori este nevoie.
O functie este un modul de cod care ofera o interfata de apel, rezolva un anumit algoritm si optional, returneaza o valoare.
Declararea unei functii se face in felul urmator:
function nume_functie(lista_par) {
   // secventa instructiuni
   // (corpul functiei)
   // daca este cazul: return exp; 
}

Exemplu:
function afis_tablou( $t, $nume)
{
   echo "Continut tablou $nume<BR>";
   echo "<UL>";
   foreach ( $t as $ind => $el )
         echo "<LI> $ind - $el</LI>";
   echo "</UL>";
}
// apel functie
$tPers = array( "Ionescu" => 1962, "Popescu" => 1967, "Vasilescu" => 1978);
afis_tablou("anul nasterii", $tPers);

Se pot declara si functii cu parametrii de apel optionali:
function afiseaza_titlu( $titlu, $marime = "H1", $culoare = "#000000")
{
   echo "<$marime> <FONT color=\" $culoare\">".$titlu."</FONT></$marime><P>";
}

Implicit parametrii sunt transmisi prin valoare. Daca se doreste transmiterea prin adresa se va utiliza referinte:
function schimba( &$a, &$b )
{
   echo "Apel schimba(a=$a, b=$b)";
   $c = $b;
   $b = $a;
   $a = $c;
}
Limbajul PHP suporta si functii recursive:
function afis_inversat($sir)
{
   if (strlen($sir)>0)
     afis_inversat(substr($sir,1)); 
   echo substr($sir, 0, 1);
}


Reutilizarea codului
Pentru a creste eficienta dezvoltarii aplicatiilor se prefera reutilizarea codului gata scris.
O prima modalitate o reprezinta crearea si utilizarea de biblioteci de functii.
Aceste bibilioteci sunt scrise in fisiere externe care pot fi incluse in aplicatia curenta prin instructiunile include sau require. Spre deosebire de include, instructiunea require este inlocuita cu fisierul referit la incarcarea paginii, indiferent daca executia codului va ajunge sau nu la aceasta instructiune.
O a doua modalitate este reprezentata de posibilitatea crearii ierarhiilor de clase (incepand cu PHP 5.0). Pentru mai multe informatii accesati PHP: Classes and Objects.

Controlul Sesiunilor
Protocolul HTTP este un protocol lipsit de informatii de stare. Acest lucru se traduce prin faptul ca acest protocol nu are nici un mecanism propriu prin care sa trasmita datele intre doua tranzactii (pagini). La cererea succesiva a doua pagini de catre un utilizator catre un server de Web, nu exista nici o posibilitate de a transmite spre cea de a doua pagina faptul ca este vorba de catre acelasi utilizator. Ideea de la care pleaca controlul sesiunilor este tocmai acela de a permite urmarirea actiunilor unui utilizator pe parcursul unei sesiuni de accese catre respectivul server de Web.
Sesiunile PHP sunt gestionate prin intermediul unui numar unic (session ID) generat aleator pe baza unui algoritm criptografic. Acest numar este generat de catre PHP si mentinut de catre clientul de Web care a acceseaza pagini pe tot parcursul sesiunii de lucru.
Pasii care se fac la utilizarea unei sesiuni sunt urmatorii:
    • crearea unei sesiuni (session_start();)
    • inregistrarea variabilelor sesiune (session_register( "var");)
    • utilizarea variabilelor sesiune pentru controlul accesului sau personalizarea paginii ($_SESSION["var"];)
    • stergerea variabilelor sesiune si distrugerea sesiunii (session_destroy();).

O alternativa la utilizarea sesiunilor o reprezinta tehnologia coockies, caz in care datele specifice utilizatorului sunt pastrate pe calculatorul acestuia (in fisiere cookies gestionate de browser).

5.2. GD

Biblioteca GD este folosite pentru crearea dinamica a imaginilor (GIF, JPG, PNG). Este disponibila pe mai multe platforme (http://www.libgd.org/) dar in continuare ne vom referi la implementarea PHP.
Pentru instalarea bibliotecii modulul PHP trebuie compilat cu optiunea --with-gd. La versiunea de Windows se poate folosi biblioteca php_gd2.dll (se va modifica corespunzator php.ini). In php.ini trebuie facuta si modificarea:
gd.jpeg_ignore_warning PHP_INI_ALL
Includerea unei imagini GD in pagina se va face prin:
<img src="img.php" alt="Imagine prin PHP GD ">
Pentru a crea imaginea fisierul img.php va contine:
<?php
header ("Content-type: image/jpeg");
$img = ImageCreate (250,150);
$fond = ImageColorAllocate ($img, 0, 0, 240);
$col = ImageColorAllocate ($img, 255, 255, 255);
ImageEllipse($img, 125, 75, 220, 100, $col);
ImageJPEG ($img, '', 100);
?>

Acest exemplu va crea o elipsa pe un fundal albastru.

Functii GD
> array gd_info(void);
array(9) {
  ["GD Version"]=>
  string(24) "bundled (2.0 compatible)"
  ["FreeType Support"]=> bool(false)
  ["T1Lib Support"]=> bool(false)
  ["GIF Read Support"]=> bool(true)
  ["GIF Create Support"]=> bool(false)
  ["JPEG Support"]=> bool(false)
  ["PNG Support"]=> bool(true)
  ["WBMP Support"]=> bool(true)
  ["XBM Support"]=> bool(false)
}
> list($width,$height,$type,$attr) = getimagesize("img/flag.jpg");
> int imagecolorallocate($image, $red, $green, $blue);
Obs: primul apel va modifica culoarea de background.
> int imagecolorat($image, $x, $y);
Obs: Returneaza indexul culorii din punctul (x,y).
void imagecolorset($image, $index,  $red, $green, $blue);
Obs: seteaza culoarea pentru indexul respectiv.
> array imagecolorsforindex($image,  $index);
Obs: obtine culoarea (RGBA) de la indexul specificat.
> bool imagecopy($dst_im, $src_im,  $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
> bool imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x,  $src_y, $dst_w, $dst_h, $src_w, $src_h);
> resource imagecreate($width, $height);
> resource imagecreatefromjpeg($filename);
Obs: creaza o imagine pornind de la fisierul specificat.
> bool imageellipse($image, $cx, $cy, $width, $height, $color);
> bool imagefill($image, $x, $y, $color)
> bool imagejpeg( $image [, $filename [,$quality]]);

Obs: Insereaza imaginea in pagina HTML.
> bool imageline($image, $x1, $y1, $x2, $y2, $color);
> bool imagerectangle($image, $x1, $y1, $x2, $y2, $color);
> bool imagesetpixel($image, $x, $y, $color);
> bool imagestring($image, $font, $x, $y, $string, $color);
> int imagesx($image);
> int imagesy($image);


5.3. PDFLib

Biblioteca PDFLib ajuta la crearea dinamica (din PHP) a documentelor PDF.
Crearea unui document PDF se face folosind fucntia PDF_new(); Un exemplu de utilizare se gaseste pe http://www.php.net/.

Functii PDFLib

> int PDF_add_textflow(resource $pdfdoc, int $textflow, string $text, string $optlist);
> bool PDF_begin_page_ext(resource $pdfdoc, float $width, float $height, string $optlist);

Obs: Dimensiuni standard: A4 595 x 842, A3 842 x 1190.
> bool PDF_circle(resource $pdfdoc , float $x , float $y , float $r);
> bool PDF_continue_text(resource $p, string $text);
> bool PDF_end_document(resource $pdfdoc, string $optlist);
> bool PDF_end_page(resource $p);
> bool PDF_fit_image(resource $pdfdoc, int $image, float $x, float $y, string $optlist);
> bool PDF_lineto(resource $p, float $x, float $y);
> int PDF_load_font(resource $pdfdoc, string $fontname, string $encoding, string $optlist);
> int PDF_load_image(resource $pdfdoc, string $imagetype, string $filename, string $optlist);
> bool PDF_moveto(resource $p, float $x, float $y);
> resource PDF_new(void);
> bool PDF_save(resource $p);
> bool PDF_setcolor(resource $p, string $fstype, string $colorspace, float $c1, float $c2, float $c3, float $c4);
> bool PDF_show(resource $pdfdoc, string $text);
> bool PDF_show_xy(resource $p, string $text, float $x, float $y);

Exemplu:
$pdf = pdf_new();
if (!pdf_open_file($pdf, ""))
       die("Error: Fail to open output file.");
pdf_set_info($pdf, "Author", $nume." <". $email.">");
pdf_set_info($pdf, "Title", "CV -".$nume);
pdf_set_info($pdf, "Subject", "The CV of ".$nume.".");
define("PAGE_HEIGHT", 842); /* A4 */
define("PAGE_WIDTH", 595);
define("VERT_SPACING", 14);
pdf_begin_page($pdf, PAGE_WIDTH, PAGE_HEIGHT);
// Print name
$font = pdf_findfont($pdf, "Times-Bold", "winansi", 0);
pdf_setfont($pdf, $font, 14.0);
$stringwidth = pdf_stringwidth($pdf, $nume, $font, 14.0);
$xpos = (PAGE_WIDTH / 2) - ($stringwidth / 2);
pdf_show_xy($pdf, $nume, $xpos, 700);
$xpos = pdf_get_value($pdf, "textx", 0);
$ypos = pdf_get_value($pdf, "texty", 0) - VERT_SPACING;
// Print personal information.
$font = pdf_findfont($pdf, "Times-Roman", "winansi", 0);
pdf_setfont($pdf, $font, 12.0);
$headerdata = array($adresa, $oras, $tara, $codPostal, $tel, $email);
pdf_end_page($pdf);
pdf_close($pdf);
$buf = pdf_get_buffer($pdf);
$len = strlen($buf);
header("Content-type: application/pdf");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=resume.pdf");
print $buf;