joi, 9 iunie 2011

PHP Creare imagini cu PHP (Part34)

Pe langa crearea de cod de tip text (HTML, XML, ...), PHP poate fi folosit si pentru crearea si manipularea de imagini cu diferite formate (GIF, PNG, JPEG, WBMP si XPM).
PHP are implemetat cateva functii pentru lucru cu informatii legate de imagini, cum ar fi lungimea, latimea sau extensia imaginii. Pentru crearea de noi imagini sau manipularea celor existente este necesar sa aveti instalat in PHP o librarii GD cu functii pentru imagini. Pentru mai multe informatii despre cerinte si instalare librarie GD, vizitati
GD library.
- Daca folositi WampServer sau Xampp, acestea au deja incluse librarii GD.
Puteti afla informatii despre libraria GD instalata folosind functia gd_info(), aceasta returneaza o matrice cu informatii despre libraria GD inclusa.

Exemplu:

<?php
var_dump(gd_info());
?>

1. Crearea imaginilor

Pentru crearea unei imagini cu PHP sunt esentiali urmatorii pasi:

- Definirea identificatorului de imagine si suprafata de baza a imaginii.

- Stabilirea culorilor fundalului, formei sau a textului din imagine.

- Trimiterea datelor de iesire cu imaginea creata.

- Eliberarea memoriei asociata creeri imaginii.

Cam asta e, pe scurt, partea teoretica, acum sa trecem la practica, voi prezenta pas cu pas un script PHP simplu care va afisa in browser o imagine PNG formata dintr-un dreptunghi cu fundal albastru si in interior un text.
Scriptul este urmatorul:

<?php
$text = 'Textul din imagine';

// setare dimensiuni suprafetei de baza
$height = 40;
$width = 170;
// definirea imaginii
$im = imagecreate($width, $height);

// setare culori
$fundal = imagecolorallocate($im, 10, 10, 250);
$text_color = imagecolorallocate($im, 255, 255, 255);

// finalizarea imaginii
imagefill($im, 0, 0, $fundal);
imagestring($im, 4, 10, 15, $text, $text_color);

// trimiterea datelor de iesire
header('Content-type: image/png');
imagepng($im);

// curatarea memoriei
imagedestroy($im);
?>

- Acest script va afisa urmatorul rezultat


Sa studiem acest script
        - Pentru inceput am setat variabila "$text" ce contine textul care va fi adaugat in imagine, si variabilele "$height" si "$width" care reprezinta dimensiunile imaginii.
        - In continuare avem "$im = imagecreate($width, $height)", functia imagecreate() returneaza un identificator de imagine ce creaza suprafata de baza a imaginii, prelund ca argumente dimensiunile acesteia (in pixeli).
- Ca alternativa se poate folosi o imagine deja existenta, peste care sa adaugati testul, pentru aceasta se foloseste functia imagecreatefrompng("nume.png") (sau "imagecreatefromjpeg()", "imagecreatefromgif()"; in functie de tipul imaginii), exemplu: $im = imagecreatefrompng("img.png")
        - Urmatorul pas este definirea culorii pentru fundal si pentru text, pentru aceasta se foloseste functia imagecolorallocate(), aceasta returneaza un identificator de culoare care va fi folosit pentru accesarea culorii si preia 4 argumente: primul argument este identificatorul de imagine creat cu "imagecreate()" (in script este in variabila "$im"), urmatoarele trei argumente reprezinta valorile RGB (Red, Green, Blue) pentru stabilirea culorii.
        - Pentru adaugarea culorii de fundal se foloseste functia imagefill(), care preia 4 argumente (in script avem "imagefill($im, 0, 0, $fundal);"), argumentele sunt:
- identificatorul de imagine
- urmatoarele doua argumente definesc coordonatele X si Y de start pentru umplerea culorii (0, 0)
- ultimul argument reprezinta identificatorul de culoare folosit (aici cel din variabila $fundal)
        - Pentru adaugarea textului in cadrul imaginii se foloseste functia imagestring(), aceasta preia 6 argumente:
1. - identificatorul de imagine
2. - tipul fondului folosit, care poate fi un numar intre 1 si 5, reprezentand fonturi prestabilite
- ca alternativa se poate folosi functia imageloadfont(), pentru includerea de alte fonturi
3. - al treilea argument reprezinta distanta, in pixeli, fata de marginea din stanga a imaginii
4. - al patrulea argument reprezinta distanta, in pixeli, fata de marginea de sus a imaginii
5. - al cincilea argument reprezinta sirul introdus
6. - ultimul argument este culoarea textului
        - Urmatotul pas este trimiterea datelor de iesire pentru afisarea in browser.
- Pentru aceasta intai scriptul spune browser-ului ca trimite o imagine si nu test sau HTML, se face acest lucru folosind functia header() cu tipul MIME al imaginii "header('Content-type: image/png')". Daca doriti ca imaginea sa fie de tip JPEG (sau GIF) inlocuiti "png" cu "jpeg" (sau "gif"), astfel 'Content-type: image/jpeg'.
- dupa ce s-au trimis datele pentru "header", se trimit datele imaginii utilizand functia imagepng() (sau "imagejpeg()", "imagegif(); in functie de tipul imaginii") care preia ca argument identificatorul de imagine (in script avem "imagepng($im)")
Ca alternativa, imaginea poate fi scrisa intr-un fisier, in loc sa fie afisata in browser o salvati pe server, pentru aceasta se adauga un al doilea parametru la "imagepng()" reprezentand numele fisierului, exemplu "imagepng($im, "img.png")" si nu se mai scrie functia "header()". (trebuie sa aveti permisiuni de scriere pe server)
        - In final s-a folosit functia imagedestroy() (care foloseste ca argument identificatorul de imagine) pentru eliberarea resurselor de memorie folosite la crearea imaginii.
2. Utilizarea imaginilor create cu PHP
Deoarece un header poate fi trimis numai o data pentru o pagina, si asta este singura cale de a spune browser-ului ca sunt trimise date de imagine, poate deveni mai dificil cand se doreste crearea si afisarea mai multor imagini cu PHP.
In acest caz:

a) Puteti folosi scriptul pentru a salva imaginea pe server (dupa cum a fost explicat mai sus) si apoi folositi etichete <img> pentru afisarea imaginii
- Exemplu:
<?php
$text = 'Textul din imagine';

// setare dimensiuni
$height = 50;
$width = 170;
$im = imagecreate($width, $height);

// setare culori
$fundal = imagecolorallocate($im, 10, 10, 250);
$text_color = imagecolorallocate($im, 255, 255, 255);

// finalizarea imaginii
imagestring($im, 4, 10, 15, $text, $text_color);

// salvarea imaginii pe server
imagepng($im, "img.png");

// curatarea memoriei
imagedestroy($im);
?>

<img src="img.png" alt="Afisare 1" />
--- <img src="img.png" alt="Afisare 2" />
- Acest script va afisa urmatorul rezultat
b) O alta metoda este scrierea intr-un fisier php extern a scriptului care genereaza si afiseaza imaginea, apoi apelati scriptul PHP in atributul src, ca in exemplul urmator:
<img src="script_img.php" alt="Afisare 1" />
--- <img src="script_img.php" alt="Afisare 2" />
- Unde "script_img.php" este fisierul PHP care genereaza si afiseaza imaginea

PHP Trimitere date la o adresa de e-mail (Part33)

Este util sa avem pe o pagina din site un formular prin care vizitatorii sa poata trimite mesaje la o adresa de e-mail.
Am putea lasa pe pagina doar adresa de e-mail la care vizitatorii sa ne poata contacta, dar aceasta metoda (comoda pt. webmaster) nu este indicata. In primul rand din cauza programelor bot care circula pe net si colecteaza adresele de e-mail de pe site-uri pentru ca mai tarziu sa transmita mail-uri spam. In al doilea rand este mai simplu si mai rapid pentru vizitator sa trimita mesajul direct de pe site.
In cadrul acestei lectii este explicat un mod simplu de utilizare a limbajului PHP pentru a expedia la o adresa de e-mail date sub forma de text, preluate de la un formular HTML.
Pentru a putea expedia datele la adresa de mail, scripturile PHP trebuie sa fie capabile de a obtine accesul la serviciile SMTP (Simple Mail Transfer Protocol).
Daca folositi serviciile oferite de un "web hosting", majoritatea au implementate aceste functii.
Daca folositi propriul sistem pentru gazduirea site-ului, sau pentru teste, este nevoie sa aveti instalat si un server SMTP, acesta preia datele prelucrate de modulul PHP si le trimite la adresa de e-mail.

Expedierea mesajelor de e-mail

Configuratia PHP standard accepta expedierea mesajelor de e-mail prin intermediul SMTP (abreviere de la Simple Mail Transfer Protocol). Acesta este protocolul standard folosit pentru transferul mesajelor de e-mail, prin intermediul Internetului.
Mesajele de e-mail sunt alcatuite din doua parti: o serie de antete de mesaj si un corp.

- Antetele de mesaj indica adresa destinatarului si subiectul mail-ului, precum si alte informatii.

- Corpul contine mesajul in sine.

Pentru a trimite datele la o adresa de e-mail, se foloseste functia mail(), care preia 3 argumente principale, avand urmatoarea forma:

mail($to, $subject, $message)

Unde, in ordinea argumentelor:

- primul argument, aici variabila "$to", va contine adresa de e-mail a destinatarului (unde va fi trimis mesajul)

- al doilea argument, aici variabila "$subject", va contine subiect-ul mail-ului

- al treilea argument, aici variabila "$message" va contine mesajul

Functia "mail()" poate contine si alte adrese de e-mail optionale, astfel un al patrulea argument poate fi "From", care indica adresa de e-mail a expeditorului (cel care trimite mesajul).
Functia ar avea astfel urmatoarea forma:

mail($to, $subject, $message, $from )

- Variabila "$from" trebuie sa contina in sir cuvantul "From: " inaintea adresei de e-mail, adica asa:
            $from="From: adresa@de.mail";
- Daca argumentul "$from" nu este specificat, serverul va transmite automat aceasta adresa (in functie de cum este configurat). Astfel, cand primim mail-ul, pe langa subiect vom avea adresa expeditorului, si daca nu este specificata, putem vedea ceva de genul "nobody@localhost.ro"

Datele pentru aceste argumente, in special al treilea (aici "$message"), pot fi preluate dintr-un formular HTML, folosind functia "$_POST".
Functia "mail()" returneaza TRUE daca mail-ul a fost acceptat pentru expediere, in caz contrar returneaza FALSE.

Iata un script PHP simplu care va trimite mesaje la o adresa de e-mail:

<?php
// Verifica daca au fost trimise datele de la formular
if (isset($_POST['email']) && isset($_POST['mesaj'])) {
    $to = 'adresa_ta@de.mail';                 // Adresa unde va fi trimis mesajul
    $subiect = 'Mesaj de pe site';
    $mesaj = $_POST['mesaj'];
    $from = 'From: '. $_POST['email'];

    // PHP trimite datele la serverul de e-mail
    if (mail($to, $subiect, $mesaj, $from)) {
              echo 'Mesajul a fost trimis cu succes.';
    }
    else {
              echo 'Eroare, mesajul nu a putut fi expediat.';
    }
}
?>

- Intai se verifica (cu isset()) daca au fost trimise date de la formularul HTML. Fara aceasta verificare, s-ar expedia mesaje de e-mail ori de cate ori cineva (intentionat) acceseaza direct fisierul php cu scriptul.
- Variabilele "$mesaj" si "$from" preiau datele adaugate de vizitator in campurile unui formular HTML care au atributele 'name="mesaj"' si 'name="email"'.
Daca functia "mail()" este executata cu succes, va apare mesajul "Mesajul a fost trimis cu succes.", in caz contrar va afisa "Eroare, mesajul nu a putut fi expediat.".
Un model de cod HTML pentru crearea formularului care trimite datele la scriptul php de mai sus este urmatoru:

<h3>Trimiteti mesaj</h3>
<form name="form" method="post" action="nume_script.php">
<label>E-mail : </label>
<input type="text" name="email" size="20" /> <br />
<label>Scrie mesajul : </label> <br />
<textarea name="mesaj" cols="35" rows="6"></textarea> <br />
<input type="submit" value="Trimite" />
</form>

- "nume_script.php" este calea si numele fisierului in care se afla scriptul php de mai sus.
In browser va apare:

PHP OOP - Clase si obiecte (2) (Part32)

1. Redefinirea metodelor

Uneori, o clasa parinte include o metoda (functie) care nu este adecvata pentru o clasa copil. In loc de a re-crea noua clasa fara referire la o clasa de baza, puteti anula metoda inadecvata adaugand o metoda cu acelasi nume in clasa copil (derivata). Astfel la instantiere va fi folosita metoda, cu acelasi nume, din clasa derivata.
De exemplu, sa consideram urmatoarea clasa:

<?php
class ContBanca2 {
    var $cont_id;
    var $nume_posesor;
    var $sold = 1;

    function ContBanca2($id, $nume, $suma) {
        $this->cont_id = $id;
        $this->nume_posesor = $nume;
        $this->sold = $suma;
    }
    function inchide_cont() {
        $suma = $this->sold;
        $this->sold = 1;
        return $this->sold;
    }
}
?>

Sa presupunem ca dorim sa derivam din aceasta o clasa copil care reprezinta un nou tip de cont bancar, cu dobânda. La închiderea contului, programul trebuie sa calculeze dobânda pe care sa o adauge la soldul curent si sa returneze suma acumulata.
Iata cum putem proceda, definim clasa derivata astfe:

<?php
class ContEco extends ContBanca2 {
    function inchide_cont($zile, $rata) {
        $suma = $this->sold * $rata * ($zile / 365);
        $suma = $suma + $this->sold;
        $this->sold = 1;
        return $suma;
    }
}
?>

- In cadrul clasei derivate (copil) este definita o metoda numita "inchide_cont()". O metoda cu acelasi nume exista si în clasa de baza (clasa parinte), dar are o alta definitie. Astfel, in clasa copil nu va mai fi mostenita metoda cu acelasi nume, ci o va folosi pe cea proprie.
In continuare creem un obiect "ContEco" si apelam metoda "inchide_cont()" astfel:

<?php
// Aici sunt adaugate datele pentru definirea clasei de baza, ContBanca2
// Aici sunt adaugate datele pentru definirea clasei derivate, ContEco

$cont = new ContEco(8, "Didi", 100);
echo "<br /> Didi primeste ". $cont->inchide_cont(22, 0.8);
// Va fi afisat sirul:     "Didi primeste 104.82191780822"
?>

- Este invocata metoda "inchide_cont" definita de clasa copil, nu cea definita în clasa parinte. Astfel, metoda definita în clasa parinte a fost anulata (redefinita) de catre metoda, cu acelasi nume, definita în clasa copil.

2. Invocarea unei metode redefinite

Daca încercati sa invocati o metoda anulata (redefinita), probabil ca veti obtine o eroare.
Daca in exemplul anterior, am fi scris instructiunea: "echo "<br /> Didi primeste ". $cont->inchide_cont();", fara cele doua argumente (22, 0.8), incercand astfel sa facem referire la metoda anulata "inchide_cont()", am primi mesaje de eroare:

Warning: Missing argument 1 for ContEco::inchide_cont(),

Warning: Missing argument 2 for ContEco::inchide_cont(),

Cu toate acestea, este posibila invocarea metodei redefinite. Prin specificarea in clasa copil a numelui clasei parinte, urmat de o pereche de caractere doua puncte (::) si metoda redefinita. Astfel se poate indica programului PHP sa foloseasca metoda, cu acelasi nume, definita în clasa parinte, nu metoda definita în clasa copil.

Invocarea unei metode redefinite este un procedeu mai complicat, pentru incepatori este mai bine a fi evitat deoarece poate complica intelegerea scriptului.


Iata cum ar arata clasa derivata utilizand acest procedeu:

<?php
class ContEco extends ContBanca2 {
    function inchide_cont($zile, $rata) {
        $suma = ContBanca2::inchide_cont();
        $suma = $suma + $suma * $rata * ($zile / 365);
        return $suma;
    }
}
?>

3. Tablouri cu obiecte

Tablourile (numite si matrice) reprezinta o modalitate convenabila pentru lucrul cu mai multe valori. Valorile stocate în tablouri pot face referire la obiecte exact asa cum procedeaza în cazul numerelor sau al sirurilor.
Un tablou care face referire la obiecte se numeste "tablou cu obiecte".
Pentru a intelege modul de utilizare a unui tablou cu obiecte, sa examinam urmatoarea clasa "ContBanca" si doua clase copil ale acesteia:

<?php
// Clasa parinte
class ContBanca {
    var $cont_id;
    var $nume_posesor;
    var $sold;
    var $tip_cont;

    function ContBanca($id, $nume, $suma, $tip) {
        $this->cont_id = $id;
        $this->nume_posesor = $nume;
        $this->sold = $suma;
        $this->tip_cont = $tip;
    }

    function dump() {
        return "Cont = ". $this->cont_id.
            " posesor = ". $this->nume_posesor.
            " sold = ". $this->sold.
            " tip = ". $this->tip_cont;
    }
}

// Incepe codul pt. prima clasa copil
class ContCurent extends ContBanca {
    function ContCurent ($id, $nume, $suma) {
        ContBanca::ContBanca($id, $nume, $suma, "curent");
    }
}

// Incepe codul pt. a doua clasa copil
class ContEco extends ContBanca {
    function ContEco ($id, $nume, $suma) {
        ContBanca::ContBanca($id, $nume, $suma, "economii");
    }
}
?>

- Remarcati faptul ca metodele constructor ale celor doua clase copil fac referire la constructorul clasei parinte (folosind perechea "::"), reutilizând în mod eficient caracteristica furnizata de clasa parinte, reducand astfel codul programului.
Acum, creem instante ale claselor copil si stocam referintele la aceste instante într-un tablou:

<?php
$cont[0] = new ContCurent(11, "Plo Mar", 100);
$cont[1] = new ContEco(12, "Didi", 140);
?>

Dupa ce referintele au fost stocate în tablou, pot fi accesate în mai multe moduri, (vedeti lectiile despre lucrul cu tablouri: Lectia 9 si Lectia 10 ).
De exemplu, dupa ce am definit clasele si am stocat instantele in tabloul "$cont[]" de mai sus, adaugam urmatorul cod:

<?php
// Aici adaugam datele pt. definirea claselor
// Aici adaugam codul pentru stocarea instantelor in tablou

foreach ($cont as $contul) {
    echo "<br /> ". $contul->dump();
}
?>

- Apelam metoda "dump()" deoarece aceasta este inclusa in clasa parinte, deci mostenita de clasele copil, si are ca rol returnarea datelor.
- Tabloul este simplu de parcurs, prin invocarea metodei "dump()", care doar afiseaza membrii claselor unui obiect "ContBancar" sau ale unui obiect din una din clasele sale copil.
Exemplul va afisa urmatorul rezultat:

Cont = 11 posesor = Plo Mar sold = 100 tip = curent
Cont = 12 posesor = Didi sold = 140 tip = economii
- Primul rand reprezinta datele returnate din "$cont[0]" care face referire la obiectul clasei copil "ContCurent"
- Al doilea rand reprezinta datele returnate din "$cont[1]" care face referire la obiectul clasei copil "ContEco"