Agora
Media
Libraria Byblos



AgoraNews  





PC Magazine Ro  




NET Report   




Ginfo   




agora ON line   





PC Concrete   





Liste de discuții   




Cartea de oaspeți   




Mesaje   





Agora   








Clic aici
PC Report - ultimul numar aparut


IPRO - PC Magazine Romania, Martie 2003
SOLUȚII PENTRU PROGRAMATORII ȘI DESIGNERII WEB

Totul despre situri dinamice (III)

Konstantin Klyagin

Continuăm seria de articole despre crearea siturilor dinamice. În acest număr, veți găsi informații despre operațiile asupra bazei de date despre animale dispărute, utilă binecunoscutului erou Ace Ventura, explicații legate codul PHP-urilor de pe CD, descrierea metodei de lucru cu fișiere de tip imagine, trimiterea fișierelor prin formularul online, identificarea caracteristicilor pozelor, redimensionarea și includerea lor în baza de date.

Conectarea la baza de date
Nu prea are sens să explic fiecare linie din scripturile exemplului nostru, de aceea vă voi arăta cele mai interesante și utile locuri din cod.
Începem cu metoda de accesare a bazei de date, care, după cum vedem din fișierul connect.php, se face cu ajutorul a două funcții:

mysql_connect("localhost", "ace", "ace2") or die("Could not connect");
mysql_select_db("acedb") or die("Could not select database");

Prima linie din codul de sus face conectarea cu server-ul de baze de date, iar a doua accesează baza de date. Apropo, dacă avem mai multe conexiuni cu baze de date diferite, putem folosi o variabilă, pe care o returnează prima funcție. Dar în proiectul nostru avem o singură bază de date, deci și o singură conexiune. Sintaxa cu "or" vine din Perl și permite definirea unei acțiuni speciale, în caz că funcția care a fost chemată întoarce o eroare. Respectiv, funcția die() oprește executarea scriptului, afișând mesajul dorit.

Operații asupra bazei de date
Să vedem cum se adaugă și se șterg informații din baza de date. În fișierul pets.php selectăm toate înregistrările din tabela pets:

select id, name, lostdate, reward from pets

Iar pentru a o trimite la serverul de baze de date pentru a fi executată, folosim funcția mysql_query():

$r = mysql_query("select id, name, lostdate, reward from pets");

Rezultatul execuției îl găsim într-o variabilă de tip resursă "$r".

while ($row = mysql_fetch_assoc($r))

Sunt o sumedenie de funcții de genul fetch la partea de suport pentru MySQL în PHP. Una dintre ele este mysql_fetch_assoc(), care de fapt este foarte comodă pentru a accesa datele selectate. Rezultatul este un masiv asociativ ale cărui elemente se referă după nume. Numele câmpului este numele elementului respectiv din masiv. În exemplul nostru, vom avea următoarele variabile: $row["id"], $row["name"], $row["lostdate"] și $row["reward"]. mysql_fetch_assoc() întoarce o valoare pozitivă până când se termină înregistrările, de aceea am folosit intrucțiunea repetitivă "while".

Ca parametri ai instrucțiunii "select", putem avea atât câmpuri din baza de date, cât și funcții. Iată, spre exemplu, primul "select" din petdetails.php:

$r = mysql_query("select p.name as pname, p.marks,
date_format(p.lostdate, '%d.%m.%Y') as lostdate, p.reward,
not isnull(p.picture) and p.picture != '' as haspic,
o.name as oname, p.owner_id
from pets p, owners o where p.id = $id and o.id = p.owner_id");

Da, aici avem un "select" adevărat: sunt prezente pseudonime pentru tabele și parametri, un apel de funcție, precum și o expresie logică al cărei rezultat îl primim la ieșire. Pseudonimele se folosesc atunci când într-o solicitare sunt expresii logice, apeluri la funcții, sau numele câmpurilor sunt identice în mai multe tabele și nu este clar pe care vrem să îl selectăm. Expresia logică cu câmpul "picture" din tabela pets determină dacă înregistrarea include o imagine, iar rezultatul se regăsește sub numele "haspic" și va fi 0 sau 1.
Uneori prin cod vedem și apeluri de genul:

header("Location: pets.php");

Ca la orice protocol de comunicare, HTTP are atât părți de conținut (date) cât și cele de "header", care de obicei spun ce urmează, lungimea și opțiunile necesare pentru recepție și procesare. Există cazuri în care nu există conținut ci doar o redirectare către o altă pagină. De exemplu, în owneradd.php, după ce s-au verificat toate datele trimise de către utilizator, a fost adăugată o nouă înregistrare în tabela "owners". În continuare, browserul este redirectat către pagina ce afișează lista. Așa funcționează redirecționarea, cu o singură limitare: înaintea sa nu poate fi nici un alt "output", altfel PHP ne dă următoarea înștiințare:

Warning: Cannot add header information - headers already sent by
(output started at <unde: fișierul și linia>)
in <unde s-a produs eroarea>
Formulare online
Dintr-o pagină web, informațiile pot fi trimise către baza de date printr-un formular online. Definirea unui formular începe cu tag-ul <FORM>. Dacă numele scriptului care prelucrează formularul diferă de cel care a generat pagina, se adaugă parametrul "action". Metoda de transfer a datelor se definește prin parametrul METHOD. Astfel, avem:

<form action="petadd.php" method="get">
<input type="text" name="name" value="Tomcat">
...
</form>

O metodă pentru păstrarea parametrilor de la o prelucrare la alta, este includerea în formular a unor câmpuri ascunse ("hidden"), care chiar dacă nu sunt vizibile, se trimit o dată cu datele din formular. Găsim un exemplu în petadd.php.

<input type="hidden" name="mode" value="<?= $mode ?>">
<input type="hidden" name="id" value="<?= $id ?>">

Sintaxa "<?= $variabilă ?>" este prescurtarea pentru "<?php echo($variabila); ?>" care afișează valoarea variabilei respective.
În instrucțiunea de mai jos, am apelat funcția htmlspecialchars() care transformă anumite caractere în coduri speciale HTML. De exemplu " (ghilimelele duble) devin '&quot;'.

<input type="text" name="name" value="<?= htmlspecialchars($name) ?>">

Adăugarea înregistrărilor în petadd.php și owneradd.php se face după o schemă destul de răspândită: formularul trimite datele către același script care a generat inițial pagina. Pentru a face diferența între operațiile de adăugare și modificare a informațiilor în baza de date, folosim un "if" simplu:

if(!empty($name)) {

După trimiterea formularului, în script e suficient să verificăm doar pentru unul dintre parametri dacă a fost transmis, deoarece dacă un parametru a ajuns la script, atunci ajung și ceilalți.

Scriptul care primește datele trimise prin formularul online, face atât adăugarea, cât și modificarea înregistrărilor.

Ștergerea înregistrărilor se face din aceleași script-uri care afișează listele de animale sau de proprietari. Aici, ca și în petadd.php și owneradd.php, regimul de folosire depinde de parametrul "mode". Dacă este "remove", se afișează câte un "checkbox" lângă fiecare înregistrare, precum și două butoane noi în josul paginii. Acestea sunt "Remove checked" și "Back". Fiecare "checkbox" are un identificator "id" din baza de date ca nume. Scriptul care prelucrează formularul este remove.php, care primește lista de id-uri pentru checkbox-urile selectate. Acum să vedem ce face programul respectiv. Mai întâi, se verifică dacă a fost apăsat butonul "Back" care anulează operațiunea:

if(empty($back)) {

Dacă nu, se plimbă prin parametri construind condiția pentru comanda "delete":
foreach($_GET as $id => $val) {
if($id != "src") {
if($del != "") $del .= " or ";
if($upd != "") $udp .= " or ";

$del .= "id = $id";
$upd .= "owner_id = $id";
}
}

" .=" reprezintă operația de concatenare a două șiruri.
Știm că în afară de "src", care reprezintă numele tabelei de modificat, toți parametrii sunt id-uri, și nu toate, ci doar id-urile checkbox-urilor care au fost marcate. Astfel, dacă 1, 3 și 4 au fost selectate, condiția va fi, "id = 1 or id = 3 or id = 4". Restul comenzii nu se schimbă:

mysql_query("delete from $src where $del");

Dacă se șterge un proprietar, ne asigurăm că toate animalele sale se marchează ca "fără proprietar" (câmpul "owner_id" la ele devenind zero):

if($src = = "owners")
mysql_query("update pets set owner_id = 0 where $upd");

Trimiterea fiȘierelor
prin formulare online
O metodă interesantă se folosește și la transferul fișierelor prin formulare online. Putem transfera o poză și imediat ea va apare în sit. Dacă ne uităm la script-ul de adăugare a unui animal, vedem o deosebire în definirea formularului:

<form enctype="multipart/form-data" method="post">

După cum știm, metoda POST permite trimiterea unor șiruri mai mari de informații, iar parametrul "enctype" este un element obligatoriu pentru încărcarea fișierelor. Altfel nu va merge. Apoi punem un câmp de tip "file" în formular:

<input type="file" size=50 name="photo">

Pentru fiecare tip de parametru, avem diverse variabile. Pentru un parametru cu tipul "file", avem variabilele:
$photo
Numele local temporar al fișierului încărcat.

$photo_name
Numele original al fișierului de la client (browser).

$photo_type

Tipul MIME al fișierului. Acest tip conține un text scurt care îi spune programului "browser" cum să trateze datele care urmează: dacă ceea ce vine este o imagine sau un document PDF. Imaginile de obicei au image/jpeg, image/gif, ș.a.m.d.

$photo_size
Mărimea fișierului în octeți.

Iată cum folosim noi aceste variabile:

if(!empty($photo)) {
$orig = @imagecreatefromstring(fread(fopen($photo, "r"),
filesize($photo)));

if(empty($orig)) {
$msg = "The picture format is unknown or unsupported.";
}
}

După trimiterea unei poze, conținutul fișierului este prelucrat de către funcția imagecreatefromstring() care crează în memorie o variabilă de tip resursă. Acestă funcție are o sintaxă interesantă: prefixul "@" elimină mesajele de eroare pe care le poate produce funcția apelată. Aici poate apărea o eroare spunând că ceea ce a primit funcția n-a fost o imagine, însă noi vrem să evităm producerea erorilor interne în sit. De aceea, punem "@". Dacă imagecreatefromstring() nu reușește să citească imaginea, vom avea variabila $orig goală și în acest caz va apărea un mesaj.

Acesta n-a fost însă cel mai interesant lucru care se poate face cu imaginile, pentru că urmează schimbarea dimensiunilor pozei. Într-adevăr nu avem nevoie de niște panouri de reclamă atunci când ne este lene să micșorăm imaginea într-un editor grafic. Mai bine să lasăm scripturile de pe sit să facă tot ce e necesar, mai ales că PHP-ul ne permite să facem diverse prelucrări asupra fișierelor grafice. Iată funcția scalepicture() din connect.php:
function scalepicture($orig) {
$needx = $needy = 250;
$rx = imagesx($orig);
$ry = imagesy($orig);

if($rx > $needx) {
$ry *= $needx/$rx;
$rx = $needx;
}

if($ry > $needy) {
$rx *= $needy/$ry;
$ry = $needy;
}

$res = imagecreate($rx, $ry);
imagecopyresized($res, $orig, 0, 0, 0, 0, $rx, $ry,
imagesx($orig), imagesy($orig));

$tn = tempnam("img", "/tmp");
imagejpeg($res, $tn);
$content = addslashes(fread(fopen($tn, "r"),
filesize($tn)));
unlink($tn);

return $content;
}

După cum observați din definiție, ea are un parametru reprezentând imaginea citită și procesată cu fread() și imagecreatefromstring(). La început, limita o avem în $needx și $needy. Dacă nu ne convin dimensiunile originale - sunt mai mari decât cele maxime posibile, adică 250x250, calculăm noile dimensiuni păstrând proporțiile. Este clar ce facem în cele două if-uri. Sintaxa "*=" vine din C, și înseamnă că rezultatul mai întâi se multiplică în partea dreaptă a expresiei: "$ry *= $needx/$rx" este egal cu "$ry = $ry*$needx/$rx".

După ce am calculat noile dimensiuni, trecem direct la treabă. Creăm imaginea goală în $res cu dimensiunile dorite, și apoi o copiem pe cea originală schimbându-i dimensiunea. După ce această operațiune este gata, obținem în $tn un nume unic pentru un fișier temporar unde scriem rezultatul în format JPEG. Numele fișierului rezultat va fi pus într-un șir de caractere, se adaugă și slash-urile ca să fie gata pentru a-l include într-o comandă "insert". Știm bine, că în cazul în care valoarea unui câmp conține ghilimele neecranate cu semnul "slash - /", întreaga comandă va fi considerată incorectă.

Rezultatul returnat de scaleimage() este deja foarte ușor de folosit:

if($id = mysql_insert_id()) {
if(!empty($orig)) {
$content = scalepicture($orig);
mysql_query("update pets set picture = '$content'
where id = $id");
}
}

El se include imediat în comanda de "update". Apropo, să vedem cum putem accesa ultima înregistrare inclusă în baza de date, în cazul în care tabela respectivă are un câmp "auto_increment". Funcția mysql_insert_id() ne dă valoarea acestuia ca apoi să putem adăuga sau schimba ceva știind exact cu ce înregistrare lucrăm. În exemplu, mai întâi se pun informațiile generale și apoi, dacă este prezentă, se adaugă și imaginea trimisă de către utilizator.

După ce imaginile se întroduc în baza de date, folosim script-ul fetchimage.php pentru a le vizualiza. După cum știm din documentația de HTML, imaginea statică se afișează cu ajutorul tag-ului <IMG SRC="locația imaginii">. Diferența între afișarea imaginilor dinamice și a celor statice constă în faptul că la cele dinamice, în loc de calea și numele imaginii trebuie dată locația programului CGI care ne returnează imaginea. Cum în cazul nostru aceasta este fetchimage.php, includem atât numele cât și parametrii în tag:

<img src="fetchimage.php?src=owners&id=1">

După fiecare modificare a datelor, se execută comanda "commit", pentru a salva schimbările:

mysql_query("commit");

În acest loc facem "commit" și noi. Deoarece există atât de multe tehnologii fascinante, software minunat, inclusiv cel free și Open Source, ne întrebăm de ce să nu avem mai multe situri interesante și utile. Pentru început, cunoștințele din acest articol ar trebui să fie suficiente, iar mai multe detalii puteți găsi foarte ușor în siturile programelor utilizate în exemplu (PHP - www.php.net și MySQL - www.mysql.com). Vă urez să aveți multe idei de realizat și inspirație, care este foarte importantă pentru a face un produs de calitate.
Situl demo se află online la:
http://konst.org.ua/ace



PC Magazine Ro | CD ROM | Redactia | Abonamente | CautareArhive

Copyright © 1999-2002 Agora Media.

[email protected]

LG - LifeŽs Good

deltafri

Concurs de Grafica Digitala si Web Design

www.agora.ro

www.agora.ro