Sunteți pe pagina 1din 25

Documente XML 1.

Despre XML
XML vine de la Extensible Markup Language. XML e o forma de SGML (Standard Generalized Markup Language), pe scurt, acesta defineste o sintaxa pentru structurarea datelor (un limbaj) pe care si omul si calculatorul sa le poata citi. Fiind un curs de PHP, explicatiile despre XML vor fi mai putine, scurte si simple, cat e necesar pentru a se intelege ce e si cum poate fi utilizat cu PHP. Ca sa intelegeti cam ce este XML si ce se poate face cu el, ganditi-va ca e similar cu HTML-ul, dar fara aspect grafic, in sensul ca structura acestuia se formeaza pe baza unor tag-uri (elemente), precum <h1>, <div>, etc. in HTML, si care pot contine atribute (sau identificatori), iar in acelasi timp este o mini baza de date, deoarece scopul documentelor XML e acela de a aranja si stoca date intr-o anumita ordine si structura erarhica care sa poata fi citite si prelucrate de un alt limbaj, precum PHP. Documentele XML pot fi create, scrise, folosind un editor simplu de texte (precum Notepad). Dupa cum puteti vedea in modelul de mai jos, un document XML e asemanator cu unul HTML (daca stiti deja acest limbaj). Datele sunt incadrate in niste tag-uri. Spre deosebire de HTML, in XML denumirea tag-urilor (tehnic elemente) nu e stricta, putand fi folosite nume alese de fiecare in functie de optiunea fiecaruia pentru recunoasterea datelor ce vor fi scrise, care respecta cateva reguli minime. Aceste reguli sunt: Documentul XML trebuie sa inceapa cu sintaxa: <?xml version="1.0"?> urmata de un element de baza (radacina) care va cuprinde toate celelalte elemente (precum <html></html>), in exemplu de mai jos <book></book> Elementele trebuie sa aiba tag-uri de inchidere sau inchidere singulara (slash la sfarsitul tag-ului: <... />) si sa fie ierarhice, astfel e corect: <x> <y>...</y> </x> sau <x /> <y>...</y> (incorect <x> <y> </x> sau <x> <y> </x> </y>) Caracterele &, <, >, ', " sunt restrictionate in interiorul datelor, putand fi folosite prin escapare, cu forma: &amp;, &lt;, &gt;, &apos;, &quot; XML este case-sensitive, astfel <tag> e diferit de <Tag>, de aceea e indicat sa folositi litere mici la elemente si atribute pentru a evita confuzia. Exemplu de document XML:
<?xml version="1.0"?> <book> <publisher>Editura</publisher> <title>Titlu carte</title> <chapter title="Capitol carte"> <section title="Sub capitol"> <paragraph> O fraza din sectiunea acestui sub-capitol. </paragraph> <paragraph> Alta fraza din acelasi sub-capitol.

</paragraph> </section> </chapter> </book>

- Acesta este o structura XML creata pentru stocarea ordonata a unor date despre carti. Datele astfel stocate (cum puteti vedea in exemplul de sus) pot fi relativ usor citite si intelese de om (putand fi modificate simplu daca e nevoie) dar si de un limbaj de programare (PHP, ASP) care le preia din fisierul .xml, le prelucreaza si le poate aranja, manipula si transmite catre o alta aplicatie, precum un navigator (browser) web. In practica se folosesc de obicei pentru stocarea datelor baze de date SQL, iar acest format XML este de preferat cand se doreste utilizarea acestor date de catre mai mullti agenti, in general in scop de citire; transmiterea fiind mai rapida si economica, de exemplu: Stiri, Meteo, Clasamente, etc. Aici apare rolul important al limbajului PHP, care, dupa ce a preluat aceste date din fisierul .xml (ce poate fi pe alt server) le poate include intr-o pagina HTML pentru a fi afisate in browser, sau introduce intro alta baza de date mai mare. PHP are functii speciale pentru citirea, recunoasterea si manipularea datelor din format XML si chiar pentru crearea, scrierea de documente XML (daca are permisiuni de scriere pe server). Vor fi aratate in tutorialele (lectiile urmatoare.

2. Documente XML si DTD


Cerintele, criteriile, pentru scrierea unui document XML corect sunt simple si minime. Totusi, un document XML valid si usor de inteles are nevoie sa urmeze anumite reguli stabilite, cunoscute generic ca DTD (Document Type Definition). Ca sa intelegeti ce este si la ce e nevoie DTD, studiati urmatorul exemplu in comparatie cu cel de sus.
<?xml version="1.0"?> <book title="Nume carte"> <publisher name="Nume Editura"/> <chapter number="8"> <chapter_title>Titlu capitol</chapter_title> <p> <sentence>O fraza din sectiunea acestui sub-capitol.</sentence> <sentence>Alta fraza din acelasi sub-capitol.</sentence> </p> </chapter> </book>

- La prima vedere pare similar, dar, desi datele esentiale transmise sunt aceleasi, structura poate fi diferita. Se observa elemente cu alte denumiri si adaugarea de atribute. Pentru a folosi datele din documentele XML, trebuie sa le cunoasteti structura aranjarii lor si forma ierarhica, astfel puteti adauga noi date (de exemplu aici carti) care trebuie sa respecte acelasi format. Iar in cazul unor documente mai mari, cu ierarhii mai multe, intelegerea lor devine mai greoaie si va dura mai mult timp. Aici intervine rolul DTD, o forma de explicare pe scurt a structurii aranjarii datelor si relatia dintre ele. Adica, scrierea sub forma unei liste a specificatiilor exacte despre cum sunt elementele legate intre ele, ce tip si nume au fiecare si ce atribute sunt necesare. De exemplu, pentru modelul de sus, daca cineva doreste sa-l foloseasca si sa adauge noi carti, am putea scrie o descriere astfel: Obiectul radacina al acestu document este "book"

"book" are doar un atribut "title" "book" e compus direct din doua elemente: "publisher" si chapter" "publisher" are doar un atribut "name" "chapter" are un atribut "number" si doua elemente "chapter_title" si "p" "p" poate contine mai multe elemente "sentence"

- Astfel, dand o copie a acestei liste oricui are nevoie de acest document XML, va ajuta la intelegerea mai rapida si usoara a structurii datelor pentru a le folosi sau adauga corect altele noi. Se poate lucra in PHP cu datele din XML dupa ce a fost inteleasa structura lor. Setul de reguli DTD (Document Type Definition) poate fi specificat (scris) direct in documentul XML (precum documentatiile in PHP), intr-un tag special !DOCTYPE (document type declaration) si cu o sintaxa specifica. Exemplu listei de sus este pentru intelegerea de catre alte persoane, dar exista o sintaxa standard DTD care se adauga de obicei la inceputul fisierului XML. Pentru obiectul acestui curs nu e nevoie de cunostinte mai multe despre asta, vedeti totusi cum e in exemplul urmator. Ca sa intelegeti cum se poate adauga setul de reguli standard DTD direct in XML, vedeti exemplul urmator (partea scrisa ingrosat).
<?xml version="1.0"?> <!DOCTYPE <!ELEMENT <!ATTLIST <!ELEMENT <!ELEMENT <!ELEMENT ]> recipe [ recipe (ingredients, directions, servings)> recipe name CDATA #REQUIRED> ingredients (#PCDATA)> directions (#PCDATA)> servings (#PCDATA)>

<recipe name ="mancare"> <ingredients>Legume</ingredients> <ingredients>Paine</ingredients> <directions>Adauga la pachet</directions> <servings>12</servings> </recipe>

Documentul XML e impartit in 3 sectiuni. Prima sectiune e linia standard XML. A doua sectiune e setul intern de reguli DTD, marcat cu linii care incep cu <!. A treia sectiune sunt datele XML. Regulile interne DTD sunt scrise, incadrate de paranteze patrate in interiorul <!DOCTYPE recipe [...]> (document type declaration), 'recipe" fiint obiectul (elementul) radacina. Daca aveti mai multe documente cu aceeasi structura, se poate folosi un singur DTD dintr-un fisier extern, decat in fiecare, mai usor de actualizat in urma unei modificari. Si in cazul utilizarii unui DTD extern, trebuie folosit !DOCTYPE care sa precizeze locatia acestuia. Iata 2 exemple, in primul, SYSTEM indica locatia pe server, iar in al doilea, PUBLIC specifica un DTD standardizat (intalnnit si in documente HTML sau XHTML): <!DOCTYPE recipe SYSTEM "recipe.dtd"> si

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> In cazul aceluiasi DTD de mai sus, dar in fisier extern, "recipe.dtd" ar arata astfel:
<!ELEMENT <!ATTLIST <!ELEMENT <!ELEMENT <!ELEMENT recipe (ingredients, directions, servings)> recipe name CDATA #REQUIRED> ingredients (#PCDATA)> directions (#PCDATA)> servings (#PCDATA)>

Fara !DOCTYPE si paranteze patrate. Prin urmare, un document XML valid este acela care are un format corect, respecta minimile reguli de sintaxa, dar contine si un DTD. Aceasta a fost partea teoretica, de scurta introducere in formatul XML, in tutorialul urmatoar e prezentate aspectul practic si modul de lucru cu PHP.

Lucru cu XML - DOM


Pentru exemplele prezentate e nevoie de PHP 5+ 1. Module de lucru cu XML Pentru a prelucra in PHP datele dintr-un document XML trebuie ca acesta sa aibe structura si sintaxa corecta comform standardului XML, nu e nevoie sa fie strict valid, adica sa contina si DTD (vedeti explicatii despre asta in lectia precedenta), dar indicat e sa fie si valid. Sunt trei moduri (module) pentru lucrul cu XML: SimpleXML, DOM (Document Object Model) si SAX (Simple API for XML); toate trei sunt incluse in PHP. Fiecare are avantaje si minusuri, pot fi folosite oricare din ele pentru a lucra cu datele din XML, pt. a crea, extinde si modifica documente XML. In continuare iata cate ceva, pe scurt, despre aceste module, dupa care va fi explicat DOM, iar in lectia urmatoare si celelalte doua. SAX SAX este mai usor de invatat, dar trateaza in esenta XML ca un sir de date. Acest lucru face dificila adaugarea de noi elemente sau atribute, ori modificarea unuia anume. SAX e util pt. lucruri repetitive ce pot fi aplicate tuturor elementelor de acelasi tip. De exemplu, inlocuirea uni anumit element cu tag HTML pt. a transforma XML in HTML. DOM Extensiile PHP DOM citesc documentul XML si creaza pe baza acestuia, in memorie, un obiect cu o structura ierarhica de tip arbore, incepand cu un element (sau obiect) numit Nod (Node), elementele (obiectele) care sunt cuprinse (incadrate) in acesta se numesc Copii (Children) ai acestui obiect, iar elementele care-l cuprind (contin) pe el se numesc Parinti (Parents). Cu functiile specifice DOM se poate obtine, modifica sau crea oricare din aceasta ierarhie sau continutul, textul din ele. Apoi aceste date se pot folosi independent, fiecare unde este necesar. Dezavantajul poate fi faptul ca foloseste mai multe resurse, memorie.

DOM trebuie sa aibe in memorie tot arborele ierarhic inainte de a incepe analiza documentului XML, fapt ce afecteaza procesarea documentelor XML ce depasesc memoria alocata, dar se poate depasi aceasta limitare prin folosirea unui spatiu de pe hard-disc ca memorie. SimpleXML SimpleXML lucreaza cel mai bine pentru deschiderea si citirea rapida a datelor unui document XML, converteste elementele si atributele din XML in variabile native PHP (siruri, matrice) care pot fi utilizate dupa cum se face normal cand sunt scrise in PHP. SimpleXML foloseste mai putina memorie decat DOM, economiseste resurse si timp prin faptul ca necesita putine linii de cod, executa mai putine apelari decat fac SAX si DOM. Minusul acestuia sunt unele probleme ce pot apare cand e vorba de elemente imbricate mai adanc. 2. DOM XML Document Object Model (DOM) e un modul complet pentru crearea, editarea si manipularea datelor din documentele XML. Deoarece aceste date sunt retinute in memorie sub forma de arbore ierarhic, e recomandat ca documentul XML sa fie valid. Fiecare element e transformat intr-un Obiect si e vazut ca un Nod ce poate avea Continut, Parinti si Copii; incepand cu elementul radacina. La randul lor, fiecare din acestia putand fi un Nod si interpretat ca un Obiect separat, devenind totul o structura legata dar si individuala. Aceasta structura poate fi modificata cu functii speciale (dintr-o librarie de functii cum e "gnome-libxml2" care sunt implementate in PHP) si rescrisa iar intr-un format XML. Exemplu 1 - Creare document XML cu PHP Pentru a intelege despre ce e vorba, vom lua un exemplu practic. Vom crea cu PHP un document XML cat mai simplu, folosind functiile DOM XML. Etapele de lucru sunt urmatoarele: 1. Se creaza in memorie un nou obiect XML. 2. Se creaza si adauga cateva elemente, un atribut si un continut text. Aici alcatuim o structura cu tag-uri HTML 3. Se vor scrie (salva) datele intr-un fisier .xml (denumit "exemplu_dom.xml") pe server (PHP trebuie sa aiba permisiuni de scriere pe server). Codul PHP pentru crearea acestuia este urmatorul. Explicatiile necesare le gasiti in cod.
<?php $doc = new DomDocument('1.0', 'utf-8'); // Se creaza in memorie un nou obiect DOM $root = $doc->createElement('html'); // Se creaza primul obiect element, radacina $root = $doc->appendChild($root); // Se adauga in structura documentului, ca element $body = $doc->createElement('body'); // Se creaza un alt element, 'body' $body = $root->appendChild($body); // Se adauga 'body' ca element copil in radacina $body->setAttribute('bgcolor', '#e8e8fe'); // Se seteaza un atribut pt. elementul doi (body) $graff = $doc->createElement('p'); // Se creaza un alt element, 'p' $graff = $body->appendChild($graff); // Se adauga 'p' ca element copil in 'body' $text = $doc->createTextNode('Un text pentru continut'); // Se creaza un continut text $text = $graff->appendChild($text); // Se adauga continutul text in 'p'

// Salveaza, scrie datele create in obiectul $doc // Afiseaza mesaj daca a putut salva fisierul pe server sau nu if($doc->save("exemplu_dom.xml")) echo 'Documentul exemplu_dom.xml a fost creat'; else echo 'Eroare: documentul exemplu_dom.xml nu a putut fi creat'; ?>

Copiati acest script intr-un fisier .php si apelati-l din browser, daca va crea cu succes fisierul "exemplu_dom.xml" va afisa un mesaj afirmativ. Ca sa vedeti rezultatul, deschideti acest fisier cu un editor de text (sau un browser). Exemplu 2 - Modificare document XML cu PHP Dupa ce e creat, sau aveti deja un document XML, poate apare necesitatea de a modifica ceva la el, schimbarea continutului unui element, adaugarea unui element nou, sau altele. In urmatorul exemplu puteti invata cum se poate face cu PHP DOM cateva modificari la datele dintr-un document XML si salvate in alt fisier .xml. Va fi folosit documentul creat in primul exemplu, la care va fi modificat continutul text din elementul (tag-ul) 'p' si va fi adaugat un alt element 'div' in acelasi parinte unde e si 'p'. Explicatiile necesare le gasiti in cod. Etapele sunt urmatoarele: 1. Se creaza un nou obiect in memorie si se adauga in el datele dintr-un document XML existent. 2. Se preia si parcurg elementele (care devin Nod-uri) din documentul adaugat. 3. Cand parcurgerea ajunge la elementul caruia dorim sa-i adaugam un nou continut text, adauga (modifica) pe cel existent, creaza un nou element cu nume si text pe care-l adauga dupa cel modificat (in acelasi parinte)
<?php $file = 'exemplu_dom.xml'; $doc = new DOMDocument(); $doc->load($file); $get_elms = $doc->getElementsByTagName("*"); $nr_elms = $get_elms->length; // Calea si numele fisierului .xml // // // // Creaza un nou obiect in memorie Incarca datele din $file in obiectul nou creat Preia toate elementele ("*") stocate in obiect Obtine numarul de elemente (Nodes) preluate

// Parcurge variabila cu obiectul ce stocheaza elementele (Nod-urile) for($i = 0; $i<$nr_elms; $i++) { $node = $get_elms->item($i); $element = $node->nodeName; // Preia fiecare Nod din parcurgere // Obtine numele elementului

// Daca elementul este 'p', ii adauga alt continut text if($element=='p') { $node->nodeValue = 'Un continut text nou'; // Creaza noul element dupa 'p' (in elementul Parinte unde se afla si 'p'), cu nume si continut text $element_nou = $doc->createElement('div', 'Acesta este elementul nou adaugat'); $node->parentNode->appendChild($element_nou); // Adauga in elementul parinte noul element creat

} }

// Daca poate salva noul continut XML (din obiectul $doc) intr-un fisier .xml // Preia continutul si intr-un sir (cu "saveXML()") pt. a afisa rezultatul obtinut if($doc->save('exemplu2_dom.xml')) { echo htmlentities($doc->saveXML()); } // Daca doriti rescrierea primului document XML, inlocuiti 'exemplu2_dom.xml' cu numele aceluia ?>

Obs. O lista cu mai multe functii utile in lucrul cu DOM si XML in PHP gasiti la pagina -> Functii DOM XML In tutorialul urmator este explicat utilizarea modulului SAX

Lucru cu XML - SAX


SAX (Simple API for XML) este utilizat pe scara larga pentru a analiza documente XML. E un API bazat pe evenimente. Functiile pentru aceste evenimente nu sunt standard, ci sunt create de utilizator. Utilizatorul creaza un numar de functii ce sunt apelate cand este recunoscut un anumit eveniment. Analiza documentelor XML cu SAX este unidirectionala. In timp ce analiza parcurge datele XML, sunt recunoscute bucati din XML precum: elemente, atribute, continut text, fiecare fiind un eveniment, iar datele asociate unui eveniment sunt transmise la o functie creata de utilizator, dupa ce functia termina operatiile analiza XML-ului continua. Datele care au fost analizate anterior nu pot fi recitite decat incepand iar parsarea. Avantajul principal fata de DOM este faptul ca SAX foloseste mai putina memorie si procesarea datelor poate fi mai rapida. DOM trebuie sa aibe in memorie tot arborele ierarhic inainte de a incepe analiza documentului XML, fapt ce afecteaza procesarea documentelor XML ce depasesc memoria alocata, (dar se poate depasi aceasta limitare in cazul DOM prin folosirea unui spatiu de pe hard-disc ca memorie). In schimb, cantitatea de memorie folosita de SAX depinde de adancimea imbricarii elementelor si de cantitatea de date a atributelor dintr-un element, ambele fiind mai mici decat marimea arborelui, ceea ce-l face o alternativa mai buna in cazul documentelor XML mari dar cu adancime de imbricare mai mica. 1. Utilizarea SAX Utilizarea SAX depinde in general de scopul prelucrarii documentului XML, deoarece utilizatorul scrie functiile necesare, dar sunt cativa pasi comuni: 1. Determinarea evenimentelor care se doresc folosite. 2. Scrierea functiilor ce vor fi apelate pentru fiecare eveniment, de cele mai multe ori pentru scrierea datelor, inceputul si sfarsitul unui eveniment. 3. Crearea unui parser folosind "xml_parser_create()" si apoi apelarea lui cu "xml_parse()". 4. Eliberarea memoriei cu "xml_parser_free().".

Urmatorul exemplu arta modul de creare si utilizare a acestor functii de baza. Ca model, va fi folosit urmatorul document XML, stocat intr-un fisier "exemplu_sax.xml":
<?xml version="1.0" encoding="utf-8"?> <carti> <titlu titlul="Titlu Carte" id="1"> <autor nume="Nume Autor" /> <text>Un text din carte</text> <pret suma="00" /> </titlu> </carti>

Cu functiile definite mai jos, vor fi prelucrarte si afisate numele, atributele si continutul text din fiecare element al acxestui document XML. Documentatia din cod explica detaliat rolul si utilizarea fiecarei functii.
<?php

$file = "exemplu_sax.xml";

// Calea si numele fisierului XML

// Functie apelata la inceputul fiecarui element // Pe langa $parser (analizatorul), $name e numele elementului // $ar_attr e un array in care sunt stocate atributele din element [nume]=>valoare function startElement($parser, $name, $ar_attr) { // Aici pot fi prelucrate matricea cu atributele ($ar_attr) si numele elementului ($name) echo "<b>$name -</b> "; // Afiseaza numele elementului

// Daca matricea contine cel putin un atribut, o parcurge if(count($ar_attr)>0) { foreach($ar_attr as $atr=>$val) { echo " $atr => $val ,"; // Preia si afiseaza numele si } } }

valoarea fiecarui atribut

// Functie apelata la sfarsitul fiecarui element // Pe langa $parser (analizatorul), $name stocheaza numele elementului (la inchidere)

function endElement($parser, $name) {


// Aici, daca se mai doreste de facut ceva dupa ce a ajuns la inchiderea elementului

print "\n"; }
// Functie apelata de fiecare data cand sunt intalnite caractere de date (continut text) in element // Pe langa $parser (analizatorul), $value stocheaza valoarea elementului intalnit (continutul-text)

function characterData($parser, $value){ // Aici pot fi manipulate datele din $value echo "$value <br>"; // Afiseaza valoarea transmisa functiei }
// Se defineste analizatoru care va fi apelat alaturi de functiile pentru evenimente (definite mai sus) // Pentru a utiliza standardul ISO-8859-1, se sterge parametru 'utf-8'

$simpleparser = xml_parser_create('utf-8');
// Daca se doreste anularea preluarii cu majuscule (se sterge // din fata functiei) // xml_parser_set_option($simpleparser, XML_OPTION_CASE_FOLDING, 0); // Evenimentul care apeleaza functiile la inceputul si sfarsitul fiecarui element

xml_set_element_handler($simpleparser, "startElement", "endElement");


// Eveniment ce apeleaza functia "characterData()" cand analiza ajunge la continutul din element

xml_set_character_data_handler($simpleparser, "characterData");
// Deschide fisierul XML pentru citire

if($fo = fopen($file, "r")) { // Preia continutul fisierului intr-un sir while ($date_xml = fread($fo, filesize($file))) {
// Transmite datele la parser (analizator)

if (!xml_parse($simpleparser, $date_xml, feof($fo))) {


// Afiseaza eroarea aparuta daca analiza nu poate fi executata

echo xml_error_string(xml_get_error_code($simpleparser)); } } fclose($fo); }


// Elibereaza memoria folosita pt deschiderea fisierului

else echo "Nu a putut citi $file"; // Elibereaza memoria folosita la parsare xml_parser_free($simpleparser); ?>

Acest script va afisa urmatorul rezultat: CARTI TITLU - TITLUL => Titlu Carte , ID => 1 , AUTOR - NUME => Nume Autor , TEXT - Un text din carte PRET - SUMA => 00 , Observati ca numele elementelor si atributelor sunt receptionate si returnate de SAX cu majuscule. In mod initial, SAX foloseste aceste nume cu majuscule iar formatul caracterelor e ISO-8859-1. Pentru a anula preluarea cu majuscule si folosirea unui alt format (US-ASCII sau UTF8) se poate utiliza functia "xml_parser_set_option()", care preia ca prim argument parserul creat, apoi o constanta: ML_OPTION_CASE_FOLDING sau XML_OPTION_TARGET_ENCODING pentru format; al treilea argument este optiunea acelei constante. De exemplu, pentru anularea preluarii cu majuscule si utilizarea coding-ului UTF-8, se foloseste urmatorul cod la definirea analizatorului: // Se defineste analizatoru $simpleparser = xml_parser_create(); // Anuleaza preluarea cu majuscule si foloseste formatul UTF-8 xml_parser_set_option($simpleparser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($simpleparser, XML_OPTION_TARGET_ENCODING, 'UTF8'); Pentru definirea formatului de codare, se poate specifica direct in functia "xml_parser_create('utf-8')". 2. Functii SAX Iata o lista cu cele mai importante functii SAX: xml_parser_create([format]) - Creaza parser-ul (analizatorul), pot fi create mai multe in acelasi script. Format e optional, 'utf-8' daca se doreste acesta. xml_parser_free(parser) - Elibereaza memoria folosita de parametru "parser", care a fost creat cu "xml_parser_create()". xml_parse(parser, "date_xml" [, final]) - Porneste analiza datelor XML, din "date_xml", cu analizatorul "parser". Parametru trei, "final" e optinal, precizeaza ultima bucata de date unde sa se termine analiza. xml_get_error_code(parser) - Daca procesarea esueaza, aceasta functie returneaza un cod de eroare din care se poate gasi cauza problemei. xml_error_string(errorcode) - Returneaza un sir care specifica eroarea gasita de "xml_get_error_code()", dat ca parametru. xml_set_element_handler(parser, start_element_handler, end_element_handler) - Aceasta functie seteaza evenimentele (functiile definite de utilizator) ce trebuiesc apelate la inceputul, apoi inchiderea, unui element.

xml_set_character_data_handler(parser, date_handler) - Seteaza evenimentul cu functia ce trebuie apelata cand analiza ajunge la contextul (continutul text) al elementului. xml_set_default_handler(parser, handler) - Seteaza evenimentul "default" care e apelat daca nu a fost definita o anume apelare pentru un eveniment.

In tutorialul urmator este explicat utilizarea modulului SimpleXML.

PHP - XML - SimpleXML


SimpleXML a aparut in PHP 5. Lucreaza ca si DOM, cu obiecte, preia tot documentul XML sub forma unui arbore ierarhic in memorie, dar spre deosebire de acesta, e mai flexibil si foloseste mai putina memorie deoarece elementele sunt stocate direct ca variabile PHP (de tip string si array) si astfel pot fi imediat utilizate. Foloseste un minim necesar de cod si are o forma intuitiva a datelor. In SimpleXML se lucreaza mult cu functii pentru Array, majoritatea datelor sunt stocate in variabile de tip array. Este util cand se doreste citirea catorva date dintr-un document XML, a carui structura o cunoasteti, si scrierea altora inapoi. Ca si in cazul DOM, este indicat ca documentul XML sa aibe un format corect facut, cel mai bine, valid. 1. Citire document XML cu SimpleXML La inceput se preia documentul XML dintr-un fisier (cu simplexml_load_file().) sau dintr-un sir (cu simplexml_load_string()) care este imediat adaugat sub forma de obiect in memorie. Apoi se face referire direct la oricare element din obiect, dupa cum puteti vedea in exemplul de mai jos (trebuie sa stiti structura datelor XML si elementele pe care doriti sa le folositi). Ca model, va fi folosit urmatorul document XML, stocat intr-un fisier "exemplu_simplexml.xml":
<?xml version="1.0" encoding="utf-8"?> <carti> <titlu titlul="Titlu Carte" id="1"> <autor nume="Nume Autor" /> <text>Un text din carte</text> <text>Un alt paragraf din carte</text> <pret suma="0" /> </titlu> <titlu titlul="Titlu a doua carte" id="2"> <autor nume="Nume Autor carte 2" /> <text>Un text din a doua carte</text> <text>Un alt paragraf din cea dea doua carte</text> <pret suma="00" /> </titlu> </carti>

- Urmatorul script preia si afisaza cateva date din acest document XML (explicatiile necesare sunt in cod).
<?php $obj = simplexml_load_file("exemplu_simplexml.xml"); // Calea si numele fisierului .xml $titlu = $obj->titlu; // Preia toate elementele cu nume "titlu" (intr-o variabila tip array) $text = $obj->titlu[0]->text; // Preia toate elementele cu nume "text" din primul element "titlu"

// Parcurge matricea cu $titlu si preia intr-un array elementele "autor" si "pret" din fiecare

for($i=0; $i<count($titlu); $i++) { $autor[] = $titlu[$i]->autor; $pret[] = $titlu[$i]->pret; } // Afiseaza valoarea atributului "nume" din primul element "autor" echo $autor[0]['nume']. '<br>'; // Nume Autor

// Afiseaza valoarea atributului "suma" din al doilea element "pret" echo $pret[1]['suma']. '<br>'; // 00

// Parcurge matricea $text (cu elementele "text" din primul "titlu") // Afiseaza valoarea fiecaruia for($i=0; $i<count($text); $i++) { echo $text[$i]. ' - '; } ?> // Un text din carte - Un alt paragraf din carte

Testati singuri exemplul pentru a vedea rezultatul (folosind documentul XML "exemplu_simplexml.xml"). 2. Modificare document XML cu SimpleXML Pe langa a prelua si folosi date dintr-un document XML, cu SimpleXML se poate si adauga date noi in acel document. Pentru a modifica valorile unor elemente sau atribute deja existente, se identifica acel element (sau atribut - cheie in matricea elementului) in sistemul ierarhic, si i-se atribue o noua valoare (vedeti metoda in exemplu de mai jos). Daca studiati si testati urmatorul exemplu, puteti intelege cum se modifica document-ul XML (Scriptul va folosi acelasi fisier ca in primul exemplu, "exemplu_simplexml.xml").
<?php $obj = simplexml_load_file("exemplu_simplexml.xml"); $titlu = $obj->titlu; // Calea si numele fisierului .xml

// Preia toate elementele cu nume "titlu" (intr-o variabila tip array)

//Parcurge matricea cu $titlu si adauga, cu "addChild("inca un element in fiecare,denumit "stoc",cu val 1

for($i=0; $i<count($titlu); $i++) { $titlu[$i]->addChild('stoc', 1); } // Modifica valoarea atributului 'nume' din elementul "autor" al primul element "titlu" $titlu[0]->autor['nume'] = 'Nume Modificat'; // Folosind sistemul de lucru cu array, creaza inca un element "autor" (fiind al doilea cu acelasi nume, are indice [key] 1) $titlu[0]->autor[1] = 'Alt autor';
// Tot cu sistemul de matrice, adauga in al doilea element "autor" inca o cheie 'atribut', cu o valoare, care vor deveni atributul elementului

$titlu[0]->autor[1]['atribut'] = 'Atribut_adaugat'; // Adauga datele XML intr-un sir $xml_doc = $obj->asXML(); echo htmlentities($xml_doc); ?> // Afiseaza documentul XML rezultat

O lista cu mai multe functii utile pentru lucrul cu SimpleXML gasiti la pagina -> Functii SimpleXML

PHP PDO - Introducere si Conectari la Baze de Date


PDO (PHP Data Objects) este o extensie PHP pentru accesare baze de date in PHP. PDO foloseste caracteristicile OOP (Programare Orientata pe Obiecte) valabile incepand cu PHP 5.1. Deoarece PDO lucreaza cu clase si obiecte, trebuie sa fiti familiarizati cu modul de lucru al programarii orientate pe obiecte. PDO poate lucra cu urmatoarele tipuri de baze de date: MySQL PostgreSQL SQLite 2 & 3 Firebird Informix (IBM Informix Dynamic Server) ODBC Oracle DBLM: FreeTDS / Sybase / MS-SQL IBM (IBM DB2) Unul din avantajele PDO este acela ca se folosesc functii similare pentru interogarea si prelucrarea bazelor de date, indiferent de tipul lor (din cele mentionate mai sus). Script-urile care folosesc interfata PDO pentru conectare la baza de date efectueaza in general urmatoarele operatii:

1.

Conectare la serverul bazei de date, prin apelare new PDO(), obtinand un obiect pentru lucru cu acea baza de date. 2. Aplicare functii specifice PDO pt. efectuarea interogarilor la baza de date. 3. Retinerea si prelucrarea datelor returnate. 4. Deconectarea de la server. - Pentru a vedea daca PDO este valabil pentru baza dv. de date, se poate verifica cu phpinfo(), unde e o sectiune PDO, sau cu metoda PDO::getAvailableDrivers()
foreach(PDO::getAvailableDrivers() as $driver) { echo $driver.''; }

1. Conectare la baza de date Orice interactiune cu o baza de date incepe prin conectarea la ea. In functie de tipul bazei de date se face intai conectarea, prin crearea unei instante de obiect cu new PDO(). Dupa conectare se aplica metodele PDO pentru retinerea si prelucrarea datelor, care in mare parte sunt aceleasi, indiferent de baza de date conectata. Iata cum se face conectarea la cateva din acestea: Conectare la MySQL
<?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'numebd'; $userdb = 'username'; $passdb = 'password';

// Afiseaza mesaj daca s-a reusit conectarea, altfel, retine eventuala eroare try { $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); echo 'Connected to database'; } catch(PDOException $e) { echo $e->getMessage(); } ?>

In variabila $dbh se creaza obiectul PDO in care vor fi stocate datele transmise de la serverul MySQL. La aceasta instanta de obiect vor fi aplicate metodele pentru prelucrarea datelor. Observati ca s-a folosit formula try() ... catch(), aceasta pentru a nu expune datele de conectare in cazul vreunei erori. De exemplu, folosind aceasta tehnica, daca numele bazei de date este incorect, returneaza ceva de genul: SQLSTATE[42000] [1049] Unknown database 'numebd' Daca numele sau parola sunt gresite, afiseaza ceva similar cu: SQLSTATE[28000] [1045] Access denied for user 'numele'@'localhost' (using password: YES) Dar, daca s-ar folosi direct:
<?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'numebd'; $userdb = 'username'; $passdb = 'password'; $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); ?>

Mesajul de eroare ar expune mai multe date, inclusiv parola, dupa cum se vede mai jos:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[28000] [1045] Access denied for user 'numele'@'localhost' (using password: YES)' in E:\server\www\zzz.php:14 Stack trace: #0 E:\server\www\zzz.php(14): PDO>__construct('mysql:host=loca...', 'numele', 'parola') #1 {main} thrown in E:\server\www\zzz.php on line 7

Deci, este indicata aplicarea formulei try() ... catch(). Conectare PostgreSQL
<?php try { $dbh = new PDO("pgsql:host=localhost port=5432 dbname=pdo", "username", "password"); echo "PDO connection object created"; } catch(PDOException $e) { echo $e->getMessage(); } ?>

Conectare la SQLite Cand PDO e folosit cu SQLite, trebuie specificata doar calea catre fisierul cu baza de date. Daca acesta nu exista, va incerca sa-l creeze.

<?php try { // connect to SQLite database $dbh = new PDO("sqlite:/path/to/database.sdb"); } catch(PDOException $e) { echo $e->getMessage(); } ?>

Conectare la Firebird Firebird este o baza de date folosita pe Windows.


<?php try { $dbh = new PDO("firebird:dbname=localhost:C:\Programs\Firebird\DATABASE.FDB", "SYSDBA", "masterkey"); } catch (PDOException $e) { echo $e->getMessage(); } ?>
Conectare la Informix

<?php try { $dbh = new PDO("informix:DSN=InformixDB", "username", "password"); } catch (PDOException $e) { echo $e->getMessage(); } ?>
Conectare la Oracle <?php try { $dbh = new PDO("OCI:dbname=accounts;charset=UTF-8", "username", "password") } catch (PDOException $e) { echo $e->getMessage(); } ?>

Conectare la ODBC Exista mai multe conexiuni ODBC care pot fi create. Iata conectarea la o baza de date MS Access, numita "accounts".
<?php try { $dbh = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\accounts.mdb;Uid=Admin"); } catch (PDOException $e) { echo $e->getMessage(); } ?>

Conectare la DBLIB O alta baza de date specifica Windows.


<?php

$hostdb = "localhost"; $port = 10060; $namedb = "my_database"; $userdb = "username"; $passdb = "password"; try { $dbh = new PDO ("dblib:host=$hostdb: $port;dbname=$namedb","$userdb","$passdb"); } catch (PDOException $e) { echo $e->getMessage(); } ?> Conectare la IBM Urmatorul exemplu arata conectarea la o baza de date IBM DB2 numita "accounts".
<?php try { $db = new PDO("ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=accounts; HOSTNAME=1.2.3,4;PORT=56789;PROTOCOL=TCPIP;", "username", "password"); } catch (PDOException $e) { echo $e->getMessage(); } ?>

2. Inchiderea conexiunii cu baza de date In mod normal, PHP inchide conexiunea la baza de date dupa ce a fost executat tot scriptul. Dar deconectarea se poate face si intentionat, atribuind valoare null la obiectul PDO, dupa cum e prezentat in exemplu de mai jos. Instanta la acel obiect va fi distrusa, prin urmare, aceasta metoda trebuie adaugata dupa ce au fost scrise toate instructiunile care trebuie aplicate obiectului PDO. Deconectarea prin aceasta metoda este utila deoarece elibereaza memoria folosita.
<?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'numebd'; $userdb = 'username'; $passdb = 'password'; // Afiseaza mesaj daca s-a reusit conectarea, altfel, retine eventuala eroare try { $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); echo 'Connected to database'; /* Instructiuni de lucru cu $dbh */ $dbh = null; // Inchidere conexiune } catch(PDOException $e) { echo $e->getMessage(); } ?>

In tutorialul urmator e prezentat modul de creare si adaugare date in tabel MySQL, INSERT, UPDATE si DELETE folosind metoda PDO exec().

PHP PDO - exec (INSERT, UPDATE, DELETE) MySQL


Dupa ce se realizeaza cu succes conectarea la baza de date (aici MySQL) si se creaza instanta de obiect PDO, poate fi utilizata pentru executia de interogari SQL. Interogarile SQL cu PDO pot fi facute in 2 moduri: direct (cu metodele "exec()" si "query()"), sau cu declaratiile prepare() ... execute(). Prima varianta e mai simpla si in aceasta lectie va fi prezentata metoda exec. Comenzile care modifica randuri din tabel, dar nu returneaza un set de rezultate cu randuri si coloane (INSERT, UPDATE), se transmit cu metoda exec(), aceasta returneaza numarul de randuri afectate, sau FALSE in caz de eroare. $count = $dbh->exec("Comanda SQL"); Interogarile care selecteaza randuri (SELECT) si returneaza un set de rezultate cu randuri si coloane se transmit cu metoda query(). In caz de eroare da FALSE. $res = $dbh->query("Interogare SQL");
Pentru a lucra cu baze de date in PHP trebuie cunoscute interogarile specifice SQL, precum: CREATE TABLE, INSERT, SELECT, etc. Cu PDO, PHP transmite aceste comenzi sub forma de sir la MySQL, daca nu le cunoasteti, sunt prezentate in lectiile despre baze de date SQL, incepand cu Baze de date SQL.

1. Creare tabel MySQL Crearea unui tabel MySQL folosind PDO se face prin metoda "exec()" si instructiunea specifica SQL, "CREATE TABLE ...", sintaxa fiind: $obiectPDO->exec("CREATE TABLE `nume_tabel` (`coloana1` TIP, `coloana2` TIP, ...)"); Toate aceste instructiuni se adauga dupa cea de creare a obiectului PDO si conectare la MySQL.

In exemplu urmator se creaza in baza de date "teste" un tabel denumit "sites", cu 4 coloane: "id", "nume", "categorie" si "adresa".
<?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Setare encoding caractere UTF-8 // Creare tabel $sql = "CREATE TABLE `sites` (`id` int(8) NOT NULL AUTO_INCREMENT PRIMARY KEY , `nume` varchar(70) NOT NULL DEFAULT '', `categorie` varchar(25), `adresa` varchar(100)) CHARACTER SET utf8 COLLATE utf8_general_ci"; if($dbh->exec($sql) !== false) echo 'Tabelul sites e creat'; // Daca rezultatul e diferit de false, afiseaza confirmare $dbh = null; // Deconectare } catch(PDOException $e) { echo $e->getMessage(); }

?>

Daca tabelul e creat, afiseaza: Tabelul sites e creat - Prin "exec("SET CHARACTER SET utf8")" seteaza ca transferul de date dintre PHP si serverul MySQL sa se faca in format de caractere UTF-8. Este indicata adaugarea acestei instructiuni cand se lucreaza cu date ce contin diacritice si caractere mai putin uzuale, dar in scriptul PHP trebuie aplicat si header-ul header('Content-type: text/html; charset=utf-8');. 2. INSERT Dupa ce tabelul MySQL este creat, se pot adauga randuri cu date in el. Acest lucru se face cu instructiunea INSERT, prin metoda exec(). Sintaxa generala este:
$obiectPDO->exec("INSERT INTO `nume_tabel` (`coloana1`, `coloana2`, ...) VALUES ('valoare1', 'valoare2', ...));

Iata cum se aplica.


<?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Adaugare date $sql = "INSERT INTO `sites` (`nume`, `categorie`, `adresa`) VALUES ('Cursuri - Tutoriale', 'educatie', 'www.marplo.net'), ('Curs PHP-MySQL', 'programare', 'www.marplo.net/php-mysql'), ('Cursuri Engleza', 'limbi straine', 'www.marplo.net/engleza')"; $count = $dbh->exec($sql); $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } // Daca datele au fost adaugate ($coun nu e false) afiseaza nr. randuri adaugate if($count !== false) echo 'Nr. randuri adaugate: '. $count; ?> // Deconectare // Setare encoding caractere UTF-8

- Acest cod adauga 3 randuri in tabelul "sites". Variabila $count retine numarul de randuri afectate (adaugate) si script-ul va afisa:
Nr. randuri adaugate: 3

Tabelul "sites" va arata astfel:

| id | | nume | 1 | | Cursuri - Tutoriale | 2 | | Curs PHP-MySQL | 3 | | Cursuri Engleza

| | categorie | | educatie | | programare | | limbi straine

| | adresa | | www.marplo.net | | www.marplo.net/php-mysql | | | www.marplo.net/engleza | |

------------------------------------------------------------------------------------------------------------

Pentru a obtine ultimul "id" adaugat cu INSERT intr-o coloana AUTO_INCREMENT PRIMARY KEY, se foloseste metoda lastInsertId(). Atentie, cand sunt adaugate mai multe randuri in aceeasi instructiune INSERT, va returna id-ul primului rand adaugat (ca si cum se adauga un singur rand).

UPDATE si DELETE sunt instructiuni SQL care modifica date din tabel, dar nu returneaza un set de rezultate cu randuri si coloane, acestea (la fel ca INSERT) pot fi executate in PDO cu metoda exec(). 3. UPDATE Dupa ce sunt adaugate date in tabelul MySQL, acestea pot fi modificate cu instructiunea UPDATE. Formula generala aplicata cu PDO este:
$obiectPDO ->exec("UPDATE `nume_tabel` SET `coloana1`='valoare1', `coloana2`='valoare2' WHERE conditie");

In urmatorul exemplu se modifica datele din coloanele "nume" si "adresa", unde "id" are valoarea 3, din tabelul "sites", creat mai sus.
<?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Setare encoding caractere UTF-8 // Modificare date din coloanele "nume" si "adresa", unde id=3 $sql = "UPDATE `sites` SET `nume`='Cursuri Spaniola', `adresa`='www.marplo.net/spaniola' WHERE `id`=3"; $count = $dbh->exec($sql); $dbh = null; // Deconectare } catch(PDOException $e) { echo $e->getMessage(); } // Daca interogarea e facuta cu succes ($count diferit de false) if($count !== false) echo 'Randuri afectate: '. $count; // Afiseaza nr. randuri afectate ?>

In browser va afisa:
Randuri afectate: 1
In unele situatii se poate ca UPDATE sa nu afecteze vreun rand si va returna 0. De aceea este indicata verificarea prin conditia if($count !== false). - E gresit if(!$count)

4. DELETE Instructiunea DELETE sterge randuri din tabel. Formula generala aplicata cu PDO este:

$obiectPDO ->exec("DELETE FROM `nume_tabel` WHERE conditie"); In urmatorul exemplu se sterg toate randurile din tabelul "sites" care au coloana "categorie" cu valoarea "educatie" sau "programare".
<?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Setare encoding caractere UTF-8 // Stergere randuri in functie de campul "categorie" $sql = "DELETE FROM `sites` WHERE `categorie` IN('educatie', 'programare')"; $count = $dbh->exec($sql); $dbh = null; // Deconectare } catch(PDOException $e) { echo $e->getMessage(); } // Daca interogarea e facuta cu succes ($count diferit de false) if($count !== false) echo 'Randuri afectate: '. $count; // Afiseaza nr. randuri afectate ?>

- In browser va afisa: Randuri afectate: 2


In lectia urmatoare sunt prezentate modul in care se poate selecta si prelua date din tabelul MySQL cu metoda PDO query().

PHP PDO - Select, fetch


Pentru selectare date dintr-un tabel MySQL se foloseste instructiunea SELECT, iar prin metode fetch specifice PDO datele cu randurile selectate primite de la serverul MySQL pot fi preluate in mai multe moduri, cu metode si constante FETCH.

1. Selectare date din tabel MySQL


Dupa ce tabelul MySQL este creat si are randuri adaugate, se aplica interogarea SELECT pentru a obtine date din randurile tabelului. Se poate folosi metoda query(), aceasta returneaza un set de rezultate cu datele obtinute de la MySQL, sau FALSE in caz de eroare. In exemplele prezentat aici se foloseste tabelul creat in lectia anterioara, care arata astfel: | id | | nume | 1 | | Cursuri - Tutoriale | 2 | | Curs PHP-MySQL | 3 | | Cursuri Engleza | | categorie | | educatie | | programare | | limbi straine | | adresa | | www.marplo.net | | www.marplo.net/php-mysql | | | www.marplo.net/engleza | | | ------------------------------------------------------------------------------------------------------------

- In urmatorul exemplu vor fi selectate randurile in care "id" este 1 sau 3. <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password';

try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Selectare date $sql = "SELECT * FROM `sites` WHERE `id` IN (1, 3)"; $datas = $dbh->query($sql); // Daca select-ul e facut cu succes ($datas nu e false) if($datas !== false) { $cols = $datas->columnCount(); // Numar coloane returnate // Setare encoding caractere UTF-8

echo 'Nr. coloane returnate: '. $cols. '<br />'; // Se parcurg si afiseaza datele selectate foreach($datas as $row) { echo $row['id']. ' - '. $row['nume']. ' - '. $row['categorie']. ' - '. $row['adresa']. '<br />'; } } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - Metoda "columnCount()" returneaza numarul de coloane din setul de rezultate. Observati ca se aplica la instanta in care s-a executat interogarea (aici variabila $datas). - Parcurgerea datelor se poate face si cu WHILE, while($row=$datas->fetch()), in acest caz trebuie aplicata si metoda "fetch()" (este prezentata mai jos). - Scriptul de mai sus va afisa: Nr. coloane returnate: 4 1 - Cursuri - Tutoriale - educatie - www.marplo.net 3 - Cursuri Engleza - limbi straine - www.marplo.net/engleza // Deconectare

2. Metoda fetch()
fetch() returneaza fiecare rand, unul dupa altul, sau FALSE cand nu mai sunt randuri. Cu aceasta metoda se poate determina modul in care sunt preluate datele. fetch() poate primi optional un argument prin care se determina modul in care valorile sunt returnate: Array, Obiect, Sir, .... Acest argument este o constanta care se aplica cu sintaxa: PDO::FETCH_MOD In continuare sunt prezentate cateva din aceste moduri, cele mai comune: FETCH_ASSOC - Returneaza fiecare rand ca un Array in care cheile sunt numele coloanelor (similar cu mysql_fetch_assoc). <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Selectare date din MySQL $sql = "SELECT * FROM `sites`"; $datas = $dbh->query($sql); // Se parcurg datele si le afiseaza while($row = $datas->fetch(PDO::FETCH_ASSOC)) { // Setare encoding caractere UTF-8

echo $row['id']. ' - '. $row['nume']. ' - '. $row['categorie']. ' - '. $row['adresa']. '<br />'; } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - In browser apare: 1 - Cursuri - Tutoriale - educatie - www.marplo.net 2 - Curs PHP-MySQL - programare - www.marplo.net/php-mysql 3 - Cursuri Engleza - limbi straine - www.marplo.net/engleza FETCH_NUM - Returneaza fiecare rand ca un Array in care cheile sunt numere consecutive (incepand de la 0), reprezentand ordinea coloanelor din setul de rezultate (similar cu mysql_fetch_row). <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Selectare date din MySQL $sql = "SELECT * FROM `sites`"; $datas = $dbh->query($sql); // Se parcurg datele while($row = $datas->fetch(PDO::FETCH_NUM)) { echo $row[0]. '-'. $row[1]. '<br />'; } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - In browser afiseaza: 1-Cursuri - Tutoriale 2-Curs PHP-MySQL 3-Cursuri Engleza FETCH_BOTH - Produce un Array cu ambele tipuri de chei, atat numele coloanelor cat si numere consecutive reprezentand ordinea coloanelor din setul de rezultate. <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Setare encoding caractere UTF-8 // Deconectare // Afiseaza datele din prima si a doua coloana // Setare encoding caractere UTF-8 // Deconectare

// Selectare date din MySQL, unde "id" are valoarea 2 $sql = "SELECT `id`, `nume` FROM `sites` WHERE `id`=2"; $datas = $dbh->query($sql); // Se parcurg datele while($row = $datas->fetch(PDO::FETCH_BOTH)) { echo $row['id']. '-'. $row['nume']. '<br />'; echo $row[0]. '-'. $row[1]. '<br />'; } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - In browser apare: 2-Curs PHP-MySQL 2-Curs PHP-MySQL FETCH_OBJ - Returneaza fiecare rand ca un obiect. Valorile coloanelor se acceseaza ca proprietati ale obiectului, prin numele lor. <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Setare encoding caractere UTF-8 // Deconectare // Afiseaza datele din coloanele 'id' si 'nume' // Afiseaza din prima si a doua coloana (aceleasi)

// Selectare date din MySQL, randuri cu "id" mai mic decat 3 $sql = "SELECT `id`, `nume` FROM `sites` WHERE `id`<3"; $datas = $dbh->query($sql); // Se parcurg datele while($row = $datas->fetch(PDO::FETCH_OBJ)) { echo $row->id. '-'. $row->nume. '<br />'; } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - Va afisa: 1-Cursuri - Tutoriale 2-Curs PHP-MySQL FETCH_CLASS - Permite ca datele sa fie preluate intr-o clasa, creand o instanta de obiect la acea clasa. Numele campurilor sunt folosite ca proprietati in acea clasa. Se aplica cu metoda fetchALL(). <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; // Deconectare // Afiseaza datele din coloanele 'id' si 'nume'

$passdb = 'password'; // Definire clasa class Sites { // Definire proprietati public $id; public $categorie; // Metoda a clasei function makeString() { // Returneaza un sir cu valorile proprietatilor, cu primul caracter din cuvinte majuscula return ucwords($this->id. ' - '. $this->categorie). '<br />'; } } try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Setare encoding caractere UTF-8

// Selectare date din MySQL, coloanele "id" si "categorie" $sql = "SELECT `id`, `categorie` FROM `sites`"; $datas = $dbh->query($sql); $obj = $datas->fetchALL(PDO::FETCH_CLASS, 'Sites'); // Aplicare FETCH_CLASS la clasa Sites

// Parcurge datele din setul de rezultate, creaza instanta de clasa $insSites foreach($obj as $insSites) { echo $insSites->makeString(); } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - Observati cum e aplicat FETCH_CLASS, la metoda "fetchALL()" si cu un argument tip sir ce reprezinta numele clasei (aici "Sites"). - Acesta metoda e utila in cazul unor proiecte mai mari, definind intr-o clasa instructiunile ce trebuie aplicate datelor primite de la baza de date se poate reduce cantitatea de cod si se imbunatateste flexibilitatea scriptului. - Script-ul va afisa: 1 - Educatie 2 - Programare 3 - Limbi Straine O alternativa la FETCH_CLASS este metoda fetchObject(). Similar, si cu aceasta datele din coloanele fiecarui rand din cele obtinute la "query()" sunt preluate printr-o clasa care este adaugata ca argument la metoda. Exemplu: <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; // Definire clasa class Sites { // Definire proprietati public $id; public $categorie; // Metoda a clasei function makeString() { // Deconectare // Apeleaza metoda makeString() la instanta clasei

// Returneaza un sir cu valorile proprietatilor, primul caracter al cuvintelor majuscula return ucwords($this->id. ' - '. $this->categorie). '<br />'; } } try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Setare encoding caractere UTF-8

// Selectare date din MySQL, coloanele "id" si "categorie" $sql = "SELECT `id`, `categorie` FROM `sites`"; $datas = $dbh->query($sql); // Parcurgere instanta de obiect creata cu fetchObject() la clasa Sites while($obj = $datas->fetchObject('Sites')) { echo $obj->makeString(); } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - Numele coloanelor din fiecare rand sunt folosite ca proprietati ale clasei apelate (aici Sites) - In browser apare: 1 - Educatie 2 - Programare 3 - Limbi Straine FETCH_FUNC - O alta constanta FETCH_ care se aplica la metoda fetchALL() este FETCH_FUNC. Returneaza un Array cu rezultatul apelarii unei functii, folosind ca argumente coloanele fiecarui rand din setul de rezultate. Cheile din Array sunt numere consecutive (de la 0), iar valoarea lor e rezultatul dat de functie pt. fiecare rand. <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; // Definire functie function test($id, $nume) { // Returneaza un sir cu datele din parametri, cu majuscule return strtoupper($id.'-'.$nume); } try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Selectare date din MySQL $sql = "SELECT `id`, `nume` FROM `sites`"; $datas = $dbh->query($sql); $ar_row = $datas->fetchALL(PDO::FETCH_FUNC, 'test'); var_export($ar_row); $dbh = null; } // Afiseaza structura Array-ului // Aplicare FETCH_FUNC la functia test() // Setare encoding caractere UTF-8 // Deconectare // Afiseaza rezultatul apelarii metodei makeString()

// Deconectare

catch(PDOException $e) { echo $e->getMessage(); } ?> - Acest mod este util cand se doreste aplicarea acelorasi instructiuni la mai multe seturi de date obtinute din tabel MySQL, astfel, pot fi toate definite intr-o functie. - Rezultatul afisat este: array ( 0 => '1-CURSURI - TUTORIALE', 1 => '2-CURS PHP-MYSQL', 2 => '3-CURSURI ENGLEZA', ) Metoda query() accepta, dupa interogarea SQL, si un argument optional ce reprezinta modul-fetch. Exemplu: <?php // Datele de conectare (adresa_server, baza_de_date, nume si parola) $hostdb = 'localhost'; $namedb = 'teste'; $userdb = 'username'; $passdb = 'password'; try { // Conectare si creare obiect PDO $dbh = new PDO("mysql:host=$hostdb; dbname=$namedb", $userdb, $passdb); $dbh->exec("SET CHARACTER SET utf8"); // Selectare date din MySQL, unde "id" este 3 $sql = "SELECT `id`, `adresa` FROM `sites` WHERE `id`=3"; $datas = $dbh->query($sql, PDO::FETCH_OBJ); // Se parcurg datele while($row = $datas->fetch()) { echo $row->id. '-'. $row->adresa. '<br />'; } $dbh = null; } catch(PDOException $e) { echo $e->getMessage(); } ?> - In browser apare: 3-www.marplo.net/engleza
Daca metoda fetch() este apelata fara argumente si la "query()" nu e specificat vreun tip FETCH_, modul implicit (default) este PDO::FETCH_BOTH. - O alta metoda prin care se poate seta modul FETCH_ default este setFetchMode(). Ex.: $datas = $dbh->query($sql); $datas->setFetchMode (PDO::FETCH_OBJ); while($row = $datas->fetch()) { // ... } - Mai multe detalii la pagina oficiala setFetchMode

// Setare encoding caractere UTF-8

// Aplicare query() cu un mod-fetch

// Afiseaza datele din coloanele "id" si "adresa"

// Deconectare

In tutorialul urmator este prezentat modul de utilizare al metodelor prepare() si execute().- Lectia 55 PHP PDO - exec ... <<-- Anterior ----------- Urmator -->> PHP PDO - prepare ...
Tutoriale de MarPlo

http://www.marplo.net/php-mysql/pdo-select-query-fetch.html

S-ar putea să vă placă și