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.

webmaster@pcmagazine.ro

LG - Life´s Good

deltafri

Concurs de Grafica Digitala si Web Design

www.agora.ro

www.agora.ro