7 Elaborazione di dati XML con PHP SAX (Simple API for XML)



Похожие документы
XML e PHP. Gestire XML con PHP. Appendice

Indice Configurazione di PHP Test dell ambiente di sviluppo 28

Airone Gestione Rifiuti Funzioni di Esportazione e Importazione

Java Server Pages (JSP) JSP o Servlet? Java Server Pages (JSP) Java Server Pages Costituiscono un estensione della tecnologia delle servlet

Obiettivi d esame PHP Developer Fundamentals on MySQL Environment

Al giorno d oggi, i sistemi per la gestione di database

Manuale Amministratore Legalmail Enterprise. Manuale ad uso degli Amministratori del Servizio Legalmail Enterprise

Capitolo 4 Pianificazione e Sviluppo di Web Part

INSTALLAZIONE DI JOOMLA! Guida alla installazione di Joomla!

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (licenza per sito)

BDCC : Guida rapida all utilizzo

XSL: extensible Stylesheet Language

DATABASE IN RETE E PROGRAMMAZIONE LATO SERVER

Consultazione Documenti

5.3 TABELLE RECORD Inserire, eliminare record in una tabella Aggiungere record Eliminare record

Guida all uso di Java Diagrammi ER

19. LA PROGRAMMAZIONE LATO SERVER

. A primi passi con microsoft a.ccepss SommarIo: i S 1. aprire e chiudere microsoft access Start (o avvio) l i b tutti i pro- grammi

LA GESTIONE DELLE VISITE CLIENTI VIA WEB

PHP. A. Lorenzi, R. Giupponi, D. Iovino LINGUAGGI WEB. LATO SERVER E MOBILE COMPUTING Atlas. Copyright Istituto Italiano Edizioni Atlas

PIATTAFORMA DOCUMENTALE CRG

Tabelle di riferimento Pulsanti Inserire documento Predisposizione doc Approvazione Doc Numerazione Doc Pubblicazione Albo Webservice

Che cos'è un modulo? pulsanti di opzione caselle di controllo caselle di riepilogo

Breve introduzione curata da Alessandro Benedetti. Struts2-Introduzione e breve guida

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (utente singolo)

SITI-Reports. Progetto SITI. Manuale Utente. SITI-Reports. ABACO S.r.l.

LABORATORIO PER IL DESIGN DELLE INTERFACCE PEGORARO ALESSANDRO CASSERO.IT MANUALE DI AGGIORNAMENTO, MANUTENZIONE E USO DEL SITO

Capitolo 3. L applicazione Java Diagrammi ER. 3.1 La finestra iniziale, il menu e la barra pulsanti

PSNET UC RUPAR PIEMONTE MANUALE OPERATIVO

MANUALE PER LA GESTIONE DEL SERVIZIO DI NEWSLETTER

Gestione Risorse Umane Web. Gestione della foto in stampa unione. Versione V01

WG-TRANSLATE Manuale Utente WG TRANSLATE. Pagina 1 di 15

SOSEBI PAPERMAP2 MODULO WEB MANUALE DELL UTENTE

Settimana I...1. Giorno 1 - Introduzione all XSLT...3

Obiettivo dell esercitazione

Manuale Utente Albo Pretorio GA

Novità di Access 2010

Il sofware è inoltre completato da una funzione di calendario che consente di impostare in modo semplice ed intuitivo i vari appuntamenti.

XML INVITO ALLO STUDIO EUROPEAN NETWORK OF INNOVATIVE SCHOOLS

NAVIGAZIONE DEL SI-ERC: UTENTE PROGETTISTA

MANUALE D USO DELLA PIATTAFORMA ITCMS

Siti interattivi e dinamici. in poche pagine

Manuale per i redattori del sito web OttoInforma

Esercizi di JavaScript

Form Editor. Dove NomeProfilo è personalizzabile.

In questo manuale sono indicate le procedure per utilizzare correttamente la gestione delle offerte dei fornitori.

Corso basi di dati Installazione e gestione di PWS

Product Updater Scaricamento e Installazione aggiornamento

extensible Markup Language

Progettazione di un Database

PORTALE CLIENTI Manuale utente

Manuale Knowledge Base

MODULO 1 PARTE 3. Programmazione (scripting) server-side con PHP 3.c Cookies e sessioni. Goy - a.a. 2012/2013 Programmazione Web 1

Gestione Risorse Umane Web

MODULO 5 ACCESS Basi di dati. Lezione 4

Costruzione del layout in gino cms

Richiesta pagina PHP (es: index.php)

Guida Joomla. di: Alessandro Rossi, Flavio Copes

Manuale Gestore. STWS Web Energy Control - Servizio di telelettura sul WEB

Sistema Informativo Gestione Fidelizzazione Clienti MANUALE D USO

I cookie sono classificati in base alla durata e al sito che li ha impostati.

Impostare il browser per navigare in sicurezza Opzioni di protezione

GUIDA UTENTE... 2 Come si accede alla piattaforma del FORMAS?... 2 Quali sono i Browser da utilizzare?... 2 Quali sono le modalità di iscrizione?...

Scuola Digitale. Manuale utente. Copyright 2014, Axios Italia

Guida all uso delle Web View su ios

Dispensa di database Access

DOCUMENTO ESERCITAZIONE ONENOTE. Utilizzare Microsoft Offi ce OneNote 2003: esercitazione rapida

Software Servizi Web UOGA

flusso delle informazioni... 2 password... 3 password/ inserimento di una nuova richiesta... 4 le condizioni di vendita... 6

CREAZIONE DI UN AZIENDA

Infostat-UIF. Istruzioni per l accesso e le autorizzazioni

Online Help StruxureWare Data Center Expert

COOKIES COSA SONO I COOKIES? COME UTILIZZIAMO I COOKIES?

CONTENT MANAGEMENT SYSTEM

START Affidamenti diretti e Procedure concorrenziali semplificate. Istruzioni per i concorrenti Ver. 1.0

Manuale Utente. Data : 01/02/2011 Versione : 1.0

Consiglio regionale della Toscana. Regole per il corretto funzionamento della posta elettronica

VIVAIO LAUDENSE RELAZIONE

CHIUSURE di MAGAZZINO di FINE ANNO

Scheda operativa Versione rif c00. Libro Inventari

Regione Piemonte Portale Rilevazioni Crediti EELL Manuale Utente

CONTROLLO DI GESTIONE DELLO STUDIO

Guida rapida all uso di Moodle per gli studenti

Manuale di Aggiornamento BOLLETTINO. Rel H4. DATALOG Soluzioni Integrate a 32 Bit

Manuale d uso per la raccolta: Sicurezza degli impianti di utenza a gas - Postcontatore

Selezionando la sezione Avviso Bonario, si apre la schermata seguente:

Corso di PHP. Prerequisiti. 6.1 PHP e il web 1. Conoscenza HTML Tecnica della programmazione Principi di programmazione web

Manuale Servizio NEWSLETTER

Транскрипт:

7 Elaborazione di dati XML con PHP Nei precedenti capitoli è stata illustrata l elaborazione di dati XML sul lato client utilizzando lo standard DOM e il linguaggio XSLT. Verrà ora descritto come elaborare dati XML sul lato server utilizzando strumenti quali SAX, DOM e SimpleXML. In linea di massima, esistono due modi per gestire l elaborazione di dati XML: lo standard DOM (Document Object Model), che è stato già illustrato, e la tecnologia SAX (Simple API for XML). Lo standard DOM consente di creare una struttura ad albero gerarchica alla quale è possibile fare riferimento ripetutamente. Con SAX, i documenti XML vengono gestiti come una serie di eventi, un evento per ciascun elemento o attributo, e la risposta a questi eventi viene fornita durante l analisi del documento. Naturalmente, ogni approccio presenta i propri vantaggi e svantaggi. Il modello DOM, ad esempio, crea strutture ad albero che richiedono un uso esteso della memoria, ma una volta create, fornisce numerosi strumenti per spostarsi, elaborare e manipolare queste strutture ad albero. La tecnologia SAX consente una gestione lineare dei documenti XML, quindi si tratta di una tecnologia meno flessibile, ma che è anche più semplice e rapida da apprendere. PHP 5.0 fornisce un terzo approccio alla gestione dei documenti XML, un approccio che nel corso di questo manuale è stato già adottato. SimpleXML crea una struttura di oggetti gerarchica simile al modello DOM. La differenza sta nel fatto che questa struttura viene ottimizzata per l estrazione e l elaborazione delle informazioni, mentre il modello DOM fornisce una API più efficace, per un uso più generale, per manipolare la composizione della struttura ad albero.

Capitolo 7: Elaborazione di dati XML con PHP In questo capitolo verranno illustrati, nell ordine riportato, SAX, DOM e SimpleXML. Al termine, si disporrà di una buona conoscenza del modo in cui è possibile utilizzare le diverse API per gestire documenti XML. Utilizzo di SAX Si immagini di creare un documento XML, quindi di scomporlo nelle singole parti e disporre queste parti come in una catena di montaggio. In tal modo, è possibile vedere istruzioni di elaborazione, tag di inizio, contenuto, tag di fine e così via, ossia tutti gli elementi che compongono il documento sistemati all interno di un unica lunga riga. Si preme un pulsante e il documento comincia a spostarsi lungo la catena di montaggio sotto l attenta sorveglianza di un omino con un megafono. I singoli elementi del documento (un commento, un entità, un istruzione di elaborazione oppure un blocco di testo) scorrono l uno dopo l altro e la loro presenza viene annunciata di volta in volta dall omino con il megafono. Questo è più o meno ciò che accade con il parser SAX. Sfortunatamente, per poter fare qualcosa di interessante con SAX, occorre creare manualmente funzioni personalizzate per gestire i tag di inizio, i tag di fine e i dati di tipo character, eseguendo un azione immediata in risposta a ciascun di essi. Se si desidera memorizzare informazioni dal documento in una struttura dati temporanea da utilizzare successivamente, è bene ricordare che SAX non esegue questa operazione. Non per altro si tratta di un API semplice per XML! E allora, per quale motivo si dovrebbe utilizzare questo parser? L uso di SAX risulta conveniente nelle seguenti situazioni: Si sta gestendo un documento XML di grandi dimensioni che se trasformato in una struttura DOM richiederebbe una quantità eccessiva di memoria. Occorre attivare ed eseguire il parser rapidamente. Si sta eseguendo un attività di elaborazione limitata oppure si sta eseguendo un tipo di elaborazione molto semplice e lineare (ad esempio, la conversione di determinati elementi XML in elementi HTML). Non occorre modificare il documento XML originale. Nelle circostanze appropriate come, ad esempio, un documento XML di grandi dimensioni, è sicuramente più opportuno utilizzare SAX che non DOM. Tuttavia, è importante comprendere che in alcuni casi, che verranno illustrati a breve, è più appropriato utilizzare una struttura ad albero. 164

Utilizzo di SAX Il parser SAX predefinito per PHP è Expat[1], una libreria C affidabile e testata, che per impostazione predefinita viene abilitata nella maggior parte delle installazioni PHP. Non occorre installare altre librerie: tutto è già stato creato in PHP. Di seguito ne viene descritto l uso analizzando i singoli passi di una breve esercitazione. Il primo passo consiste nel creare un semplice file XML per l elaborazione. Il file che verrà utilizzato in questa sezione è il seguente: <?xml version= 1.0 encoding= iso-8859-1?> <keywords> <keyword>xml</keyword> <keyword>php</keyword> <keyword>perl</keyword> <keyword>javascript</keyword> <keyword>asp</keyword> </keywords> Esempio 7.1. keyword-data.xml A questo punto, è possibile creare del codice PHP. Tuttavia, sarebbe opportuno, prima di iniziare, avere già un idea del risultato finale che si desidera conseguire. In questo caso specifico, si desidera trasformare questo elenco di elementi di parole chiave in un elenco puntato HTML, come illustrato nella Figura 7.1, Elenco di parole chiave elaborato mediante SAX. Figura 7.1. Elenco di parole chiave elaborato mediante SAX [1] http://expat.sourceforge.net/ 165

Capitolo 7: Elaborazione di dati XML con PHP Creazione di gestori Prima di poter proseguire, occorre creare funzioni che gestiscano i tag di inizio, i tag di fine e i dati di tipo character. Queste funzioni verranno richiamate dal parser SAX mentre elabora il documento XML. Il primo gestore, a cui verrà assegnato il nome start_element, sarà responsabile della gestione di tutti i tag di inizio contenuti nel documento XML. È possibile scegliere per questo gestore il nome che si desidera; i nomi assegnati ai singoli gestori verranno poi comunicati a PHP. La funzione gestore per i tag di inizio deve accettare tre argomenti: un riferimento al parser SAX (che verrà creato a breve), il nome dell elemento il cui tag di inizio è stato rilevato e un array di attributi dell elemento (e dei relativi valori). Come è possibile notare di seguito, in questo caso il gestore non è altro che un istruzione switch che ricerca un nome di un tag XML e che risponde emettendo il codice HTML appropriato. Esempio 7.2. saxdemo.php (estratto) function start_element($parser, $element_name, $element_attrs) { switch ($element_name) { case KEYWORDS : echo <h1>keywords</h1><ul> ; break; case KEYWORD : echo <li> ; break; In SAX tutti i nomi dei tag sono maiuscoli Per impostazione predefinita, il parser SAX in PHP esegue un processo chiamato case folding, in cui qualsiasi carattere minuscolo contenuto nei nomi degli attributi o dei tag viene sostituito con l equivalente maiuscolo. Questo è il motivo per il quale i nomi degli elementi KEYWORDS e KEYWORD in questo esempio sono tutti in maiuscolo. Qualora si desideri disabilitare il case-folding, il manuale di PHP contiene informazioni[2] su come eseguire questa operazione. [2] http://www.php.net/xml#xml.case-folding 166

Creazione del parser ed elaborazione del documento XML Al prossimo gestore verrà assegnato il nome end_element. Questo gestore viene richiamato per rispondere ai tag di fine presenti nel documento e utilizza la stessa istruzione switch che è stata introdotta precedentemente per emettere il codice HTML appropriato quando i singoli tag di fine vengono rilevati. function end_element($parser, $element_name) { switch ($element_name) { case KEYWORDS : echo </ul> ; break; case KEYWORD : echo </li> ; break; Esempio 7.3. saxdemo.php (estratto) Infine, occorre trovare un modo per gestire i dati di tipo character. A tale scopo, viene creata una funzione character_data che visualizzi il valore di ciascun nodo che rileva. È bene ricordare che in XML, con dati di tipo character si indica tutto il testo che non sia markup; questo gestore visualizza tutte le informazioni che si trovano tra i tag di inizio e di fine di un elemento. function character_data($parser, $data) { echo htmlentities($data); Esempio 7.4. saxdemo.php (estratto) Dopo aver definito le funzioni personalizzate per la gestione del contenuto e dei tag, è necessario creare un istanza del parser. Creazione del parser ed elaborazione del documento XML I passi successivi sono relativamente semplici, anche perché gran parte del lavoro viene coordinata dalle funzioni di gestione appena create. Tutto ciò che occorre fare è creare il parser e indicargli quali funzioni sono state create per gestire i tag di inizio, i tag di fine e i dati di tipo character: Esempio 7.5. saxdemo.php (estratto) $parser = xml_parser_create(); xml_set_element_handler($parser, start_element, end_element ); xml_set_character_data_handler($parser, character_data ); 167

Capitolo 7: Elaborazione di dati XML con PHP Dopo aver fatto ciò, è possibile utilizzare la funzione PHP fopen standard per aprire il documento XML: $fp = fopen( keyword-data.xml, r ) or die ( Cannot open keyword-data.xml! ); Esempio 7.6. saxdemo.php (estratto) Con il documento XML, è possibile utilizzare un semplice loop while per leggere blocchi di codice gestibili (4 KB è una dimensione ragionevole) ed eseguirli attraverso il parser con la funzione xml_parse. In caso di errore, viene utilizzata la funzione die di PHP per visualizzare il messaggio di errore fornito da xml_error_string sulla base del codice di errore fornito da xml_get_error_code. xml_get_current_line_number viene utilizzato per puntare alla riga in cui si è verificato l errore. Esempio 7.7. saxdemo.php (estratto) while ($data = fread($fp, 4096)) { xml_parse($parser, $data, feof($fp)) or die(sprintf( XML ERROR: %s at line %d, xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser))); Una volta terminato il loop, liberare il parser utilizzando xml_parser_free. xml_parser_free($parser); Esempio 7.8. saxdemo.php (estratto) Per assimilare quanto illustrato finora, è opportuno ricapitolare tutte le singole attività che sono state completate: 1. Creazione di gestori per tag di inizio, tag di fine e dati di tipo character. 2. Avvio del parser. 3. Registrazione dei gestori personalizzati con il parser. 4. Apertura del file XML. 5. Esecuzione di un loop nel file, inviando singoli blocchi di dati attraverso il parser. 6. Utilizzo della funzione di rilevazione errori incorporata per identificare eventuali problemi. 7. Disimpegno del parser una volta completate tutte le operazioni. Come è possibile notare, l approccio SAX è molto semplice e chiaro. Tuttavia, non presenta alcune delle più efficaci funzioni che sono invece disponibili con altri approcci come, ad esempio, il modello DOM. 168

Utilizzo di DOM Utilizzo di DOM In questa sezione verrà illustrato come opera la funzionalità DOM in PHP. Il modello DOM è una tecnologia robusta e affidabile che consente di gestire svariate situazioni. Infatti, il principale punto di forza di questo standard è proprio la sua grande flessibilità. Per quanto concerne gli svantaggi, invece, è possibile citare l estrema complessità, la vastità e il fatto che, quando si carica in memoria un documento di grandi dimensioni, può addirittura bloccare le risorse. L utilizzo di DOM sul lato client è stato già illustrato. Per quanto riguarda il lato server, il DOM è un interfaccia standardizzata. Il modo più semplice per illustrare l utilizzo di DOM sul lato server consiste nel confrontarlo con le caratteristiche di SAX descritte nella sezione precedente. Come si è visto, è possibile utilizzare SAX per elaborare documenti XML in maniera molto lineare. La funzionalità DOM di PHP adotta un approccio differente. Carica un documento XML in memoria e lo converte in una propria struttura gerarchica di oggetti, fornendo due funzioni molto importanti che in SAX mancano. La prima è la possibilità di manipolare la struttura XML in memoria, consentendo l aggiunta, la rimozione, la modifica e la ridisposizione dei nodi. La seconda è quella che consente di esaminare il documento continuamente, con accesso casuale, e non solo in maniera lineare. Per un confronto dettagliato dei due approcci, utilizzare di nuovo il file XML contenuto nella sezione dedicata al parser SAX: <?xml version= 1.0 encoding= iso-8859-1?> <keywords> <keyword>xml</keyword> <keyword>php</keyword> <keyword>perl</keyword> <keyword>javascript</keyword> <keyword>asp</keyword> </keywords> Esempio 7.9. keyword-data.xml A questo punto, creare un parser DOM e caricare il file XML. Creazione di un parser DOM Per creare il parser, occorre creare un oggetto DOMDocument. Prima di utilizzarlo, è necessario disattivarne la funzione di gestione degli spazi vuoti per impedire che spazi, tab e interruzioni di riga tra i tab vengano gestiti come nodi di testo: 169

Capitolo 7: Elaborazione di dati XML con PHP $doc = new DOMDocument(); $doc->preservewhitespace = false; Esempio 7.10. domdemo.php (estratto) Successivamente, occorre caricare il documento XML e assegnare un riferimento all elemento documento: $doc->load( keyword-data.xml ); $root = $doc->documentelement; Esempio 7.11. domdemo.php (estratto) Recupero degli elementi Dopo aver creato il parser e caricato il file XML, è possibile richiamare informazioni dal documento. Uno dei modi più semplici di utilizzare il modello DOM consiste nel richiamare elementi servendosi del metodo getelementsbytagname. Il metodo getelementsbytagname consente di acquisire tutti gli elementi contenuti in un altro elemento che presentano un determinato nome. È possibile utilizzare questo metodo per acquisire tutti i singoli elementi keyword nel documento di esempio e memorizzarli in un array: $keywords = $root->getelementsbytagname( keyword ); Esempio 7.12. domdemo.php (estratto) Dal momento che il metodo è stato richiamato sull elemento root del documento, l array $keywords contiene ora ogni singolo elemento keyword del documento XML. A questo punto è possibile eseguire un iterazione nell array $keywords per assicurarsi che ciascun elemento sia valido. Successivamente, è possibile eseguire attività di elaborazione su quell elemento. Esempio 7.13. domdemo.php (estratto) echo <ul> ; foreach ($keywords as $kw) { echo <li>. htmlentities($kw->nodevalue). </li> ; echo </ul> ; Il risultato viene visualizzato nel browser Web come illustrato nella Figura 7.2, Esempio di elaborazione di parole chiave. 170

Recupero degli elementi Figura 7.2. Esempio di elaborazione di parole chiave Finora i risultati ottenuti sono praticamente gli stessi di quelli conseguiti con SAX. La differenza principale sta nell approccio: in SAX, è stato necessario creare funzioni personalizzate che gestissero i vari tipi di tag mano a mano che venivano rilevati dal parser; con DOM, invece, è possibile accedere ai diversi livelli della struttura gerarchica del nodo nell ordine desiderato. Per quanto concerne l uso di XML e DOM, vi è ancora un altro aspetto da sottolineare. Se si desidera modificare ciò che viene emesso come output oppure il formato delle modifiche XML, di solito è preferibile eseguire queste modifiche in DOM piuttosto che in SAX. Ad esempio, si supponga che ciascuno degli elementi keyword disponga di un attributo status, come riportato di seguito: <?xml version= 1.0 encoding= iso-8859-1?> <keywords> <keyword status= live >XML</keyword> <keyword status= in progress >PHP</keyword> <keyword status= live >Perl</keyword> <keyword status= live >Javascript</keyword> <keyword status= in progress >ASP</keyword> </keywords> Esempio 7.14. keyword-data2.xml (estratto) A questo punto, si desidera visualizzare l attributo status di keyword insieme alla parola chiave. A tale scopo, occorre apportare solo una semplice modifica: 171

Capitolo 7: Elaborazione di dati XML con PHP Esempio 7.15. domdemo2.php (estratto) echo <ul> ; foreach ($keywords as $kw) { echo <li>. htmlentities($kw->nodevalue). (. htmlentities($kw->getattribute( status )). )</li> ; echo </ul> ; Il risultato di questa piccola modifica viene illustrato nella Figura 7.3, Modifica dell elenco delle parole chiave. Figura 7.3. Modifica dell elenco delle parole chiave Per visualizzare solo le parole chiave live, è sufficiente aggiungere un semplice test if: Esempio 7.16. domdemo3.php (estratto) echo <ul> ; foreach ($keywords as $kw) { if ($kw->getattribute( status ) == live ) { echo <li>. htmlentities($kw->nodevalue). </li> ; echo </ul> ; Il risultato viene illustrato nella Figura 7.4, Visualizzazione delle sole parole chiave live. 172

Creazione di nodi Figura 7.4. Visualizzazione delle sole parole chiave live Creazione di nodi Come evidenziato precedentemente, il modello DOM consente di aggiungere nuovi nodi e di manipolare quelli esistenti. Creare, dunque, un nuovo elemento keyword e aggiungerlo alla struttura DOM esistente. È possibile aggiungere un nuovo nodo utilizzando il metodo create_element dell oggetto DOMDocument. A tale scopo è sufficiente passare il nome del nuovo nodo e, facoltativamente, il relativo valore del nodo (il testo che dovrebbe contenere): $newkw = $doc->createelement( keyword, XSLT ); Esempio 7.17. domdemo4.php (estratto) Successivamente occorre associare il nuovo nodo parola chiave alla struttura DOM. A tale scopo, è possibile utilizzare il metodo appendchild, ma è necessario indicare a DOM il punto esatto in cui si desidera aggiungere il nodo. In questo caso specifico, è sufficiente aggiungere il nuovo elemento parola chiave alla variabile $root stabilita (è bene ricordare che questa variabile rappresenta l elemento root del documento, in questo esempio, keywords). $root->appendchild($newkw); Esempio 7.18. domdemo4.php (estratto) Con un documento modificato a disposizione, è possibile effettuare numerose operazioni. Una delle operazioni più comuni consiste nell emettere l output del codice XML del documento modificato in un file sul server oppure in un browser Web. 173

Capitolo 7: Elaborazione di dati XML con PHP Visualizzazione di codice XML da DOM La visualizzazione di una struttura DOM come codice XML è piuttosto semplice. Infatti, è sufficiente utilizzare il metodo savexml della classe DOMDocument. Impostando come prima cosa la proprietà formatoutput dell oggetto su true, è possibile generare il codice XML desiderato. Esempio 7.19. domdemo4.php (estratto) $doc->formatoutput = true; echo <p>updated XML source code:</p> ; echo <pre>. htmlentities($doc->savexml()). </pre> ; Questa rapida analisi ha illustrato in maniera molto generica la funzionalità del modello DOM. Maggiori dettagli verranno forniti nel corso di questo capitolo e in quelli successivi, soprattutto quando sarà necessario ricorrere a questo modello per la creazione immediata di documenti XML. Utilizzo di SimpleXML Prima dell introduzione di SimpleXML in PHP 5, gli sviluppatori potevano manipolare ed elaborare i documenti XML solo con SAX e DOM. Entrambi gli approcci erano consolidati e affidabili, ma il loro uso presupponeva una conoscenza approfondita da parte dello sviluppatore dei processi che avrebbe creato. Con SimpleXML, come implica il nome, si semplifica il modo in cui uno sviluppatore PHP interagisce, elabora e manipola i dati XML. SimpleXML offre, infatti, grandi vantaggi. Sostanzialmente, SimpleXML carica i dati XML all interno di una gerarchia di oggetti e array di oggetti, quindi consente di accedere all array utilizzando metodi familiari quali i loop foreach e gli indici di array. In altre parole, gli sviluppatori di SimpleXML si erano resi conto che XML veniva utilizzato prevalentemente per l estrazione e l elaborazione di informazioni, quindi studiarono un modo che rendesse più semplice eseguire questo tipo di operazioni. Come è stato evidenziato nel Capitolo 4, Visualizzazione di XML in un browser, SimpleXML assegna a ciascun tag presente in un file XML una proprietà che corrisponde al relativo nome dell elemento. Esaminare il seguente documento XML: <document> <msg>hello</msg> </document> 174

Caricamento di documenti XML In questo caso è possibile accedere al valore del tag <msg> utilizzando la notazione freccia orientata agli oggetti di PHP, come mostrato di seguito: echo $xml->msg; Le modifiche dei nomi degli elementi influiscono sul codice PHP Uno dei grandi svantaggi di questo approccio è rappresentato dal fatto che se, per un qualsiasi motivo, i nomi degli elementi XML subiscono una modifica, sarà necessario ritornare indietro e modificare la logica SimpleXML perché vi sia corrispondenza con i nuovi nomi. Il modo migliore per evitare questo tipo di problemi consiste nell assicurarsi che i documenti XML siano definitivi e strutturati nella maniera richiesta. Se si apportano modifiche ai documenti XML dopo aver iniziato la codifica PHP, occorre intervenire anche nel codice per garantire la corrispondenza con le nuove modifiche apportate. Nelle sezioni successive verranno illustrate tutte le principali funzioni di SimpleXML. Caricamento di documenti XML Per utilizzare SimpleXML, come prima cosa occorre identificare il documento XML che si desidera elaborare. SimpleXML può caricare un file in memoria oppure lavorare sul codice XML sotto forma di una stringa PHP. Per aprire un file, utilizzare la funzione simplexml_load_file come riportato di seguito: Esempio 7.20. sxmldemo.php (estratto) $keywords = simplexml_load_file( keyword-data2.xml ); È anche possibile fornire il proprio XML come variabile, quindi caricare questa variabile in memoria utilizzando la funzione simplexml_load_string: $xml = <<<XML <?xml version= 1.0 encoding= iso-8859-1?> <keywords> <keyword status= live >XML</keyword> <keyword status= in progress >PHP</keyword> <keyword status= live >Perl</keyword> <keyword status= live >JavaScript</keyword> <keyword status= in progress >ASP</keyword> </keywords> XML; $keywords = simplexml_load_string($xml); Esempio 7.21. sxmldemo2.php (estratto) 175

Capitolo 7: Elaborazione di dati XML con PHP Dichiarazione di stringhe PHP con heredoc La stringa PHP che contiene il codice XML nell esempio sopra riportato viene dichiarata utilizzando la sintassi heredoc. Coloro che non conoscono questa sintassi possono consultare il manuale di PHP[3]. Indipendentemente dall approccio utilizzato, il risultato sarà una gerarchia di oggetti e di array chiamata $keywords. È ora possibile accedere alle diverse parti di questa struttura utilizzando la sintassi di array o di oggetti PHP standard. Gerarchia degli elementi XML Quando un elemento XML contiene più elementi figlio con lo stesso nome (come accade per l elemento keywords di questo esempio), questi elementi figlio vengono memorizzati in un array nella gerarchia degli oggetti. Pertanto è possibile utilizzare indici di array per accedere alle informazioni necessarie. Ad esempio, è possibile utilizzare la seguente sintassi per accedere alle varie parole chiave contenute nel documento XML: echo $keywords->keyword[0]; // prints XML echo $keywords->keyword[1]; // prints PHP Si noti che, in ogni caso, si utilizza l oggetto $keywords, che rappresenta l elemento root del documento, seguito dall operatore freccia e dal nome del nodo figlio a cui si è interessati (in questo caso, keyword). Poiché si tratta di un array, si utilizza keyword[0] per accedere al primo elemento keyword. Per accedere al secondo, si utilizza keyword[1] e così via. Per ottenere, invece, tutti i valori di un array di elementi XML creato da SimpleXML, è possibile utilizzare un semplice loop foreach PHP: Esempio 7.22. sxmldemo.php/sxmldemo2.php (estratto) echo <ul> ; foreach ($keywords->keyword as $kw) { echo <li>. htmlentities($kw). </li> ; echo </ul> ; Quando un elemento contiene solo un elemento figlio di un determinato tipo, non viene creato alcun array. Infatti, è possibile accedere all elemento direttamente. Si supponga che il file XML che si sta utilizzando sia più complesso e che contenga un altro livello di elementi: nodi figlio di ciascun elemento keyword. Il file potrebbe risultare come riportato di seguito: [3] http://www.php.net/language.types.string#language.types.string.syntax.heredoc 176

Gerarchia degli elementi XML <keywords> <keyword status= live > <name>xml</name> <url>http://www.example.com/xml/</url> </keyword> <keyword status= in progress > <name>php</name> <url>http://www.example.com/php/</url> </keyword> </keywords> Per visualizzare i valori degli elementi name e url per il primo elemento keyword, procedere come riportato di seguito: echo $keywords->keyword[0]->name; // XML echo $keywords->keyword[0]->url; // http://www.example.com/xml/ Come è possibile notare, il procedimento è davvero molto semplice. Infatti, è molto più semplice lavorare con SimpleXML che non utilizzare una struttura DOM oppure dichiarare gestori SAX personalizzati. Gli oggetti elemento SimpleXML possono essere utilizzati laddove sono richieste stringhe e si comporteranno come tali, includendo il valore di testo contenuto nel corrispondente elemento XML. Tuttavia, è importante ricordare che, di fatto, questi oggetti non sono stringhe. Questa distinzione scatta nei casi in cui non è richiesta una stringa e pertanto PHP non eseguirà la conversione. Segue un esempio: if ($keywords->keyword[0] == XML ) { echo The first keyword is XML. ; Analizzando il documento XML di esempio ci si aspetterebbe che questa l istruzione if faccia eseguire l istruzione successiva e visualizzare il messaggio, ma ciò non si verifica in quanto $keywords->keyword[0] è un oggetto e come tale non è uguale alla stringa XML. Perché questo codice si comporti come previsto, è necessario eseguire la conversione attraverso l esecuzione del cast dell oggetto in una stringa: if ((string)$keywords->keyword[0] == XML ) { echo The first keyword is XML. ; 177

Capitolo 7: Elaborazione di dati XML con PHP Se non si conosce bene PHP, potrebbe risultare alquanto difficile capire quando occorre eseguire la conversione e quando invece questa operazione verrà eseguita da PHP. Gli esempi contenuti in questo manuale dovrebbero chiarire questo aspetto, ma in caso di dubbi, si consiglia di eseguire il cast del valore in una stringa: in tal modo, si avrà sempre la certezza che PHP gestirà il valore nella maniera prevista. Valori degli attributi XML È possibile accedere al valore di un attributo gestendo l oggetto elemento come array e utilizzando il nome dell attributo come chiave di array. Ad esempio, per visualizzare il valore dell attributo status del primo elemento keyword, è possibile utilizzare la seguente istruzione: echo $keywords->keyword[0][ status ]; // prints live Tuttavia, con i valori degli elementi, il discorso si complica quando si tenta di confrontare valori degli attributi con stringhe PHP, in quanto sono fondamentalmente oggetti. Ad esempio, si supponga di voler visualizzare solo parole chiave live. In tal caso, si potrebbe procedere come riportato di seguito: foreach ($keywords->keyword as $kw) { if ($kw[ status ] == live ) { // wrong! echo <li>. htmlentities($kw). </li> ; Questo frammento di codice sembra accettabile. Tuttavia, dal momento che PHP non può eseguire il confronto di due entità diverse, in questo caso, oggetti e stringhe, nessuna delle parole chiave verrà visualizzata. Pertanto, è necessario eseguire il cast dell oggetto attributo in una stringa: foreach ($keywords->keyword as $kw) { if ((string)$kw[ status ] == live ) { echo <li>. htmlentities($kw). </li> ; Esempio 7.23. sxmldemo3.php (estratto) In questo caso si è scelto di imboccare la strada più difficile. Tuttavia, grazie a Xpath esiste un metodo più semplice per filtrare i valori che vengono richiamati da un documento XML. 178

Query XPath Query XPath Esiste un altro modo per filtrare elementi XML basati sul valore di un attributo, che implica l uso del metodo xpath incontrato nel Capitolo 4, Visualizzazione di XML in un browser. Come già evidenziato, questo metodo consente di passare query XPath in SimpleXML e di ricevere i risultati sotto forma di array. Il modo più semplice per acquisire tutti gli elementi keyword il cui attributo status sia impostato su live consiste nell eseguire la query XPath riportata di seguito dall elemento keyword nel documento: keyword[@status= live ] Questa query esaminerà tutti gli elementi keyword che sono elementi figlio dell elemento corrente ed estrarrà tutti quelli il cui status sia live. Di seguito viene illustrato come effettuare questa operazione con SimpleXML: Esempio 7.24. sxmldemo4.php (estratto) foreach ($keywords->xpath( keyword[@status= live ] ) as $kw) { echo <li>. htmlentities($kw). </li> ; Ma quali sono i vantaggi che offre una query XPath? In primo luogo, non è più necessario eseguire un confronto tra stringhe all interno di PHP: questa operazione viene gestita da XPath. Se si ha familiarità con lo sviluppo di database in PHP, questo tipo di operazione equivale a consentire a una istruzione SQL di eseguire il filtraggio dei valori di database prima di restituirli nello script. In secondo luogo, il codice risulta ora meno complesso e, fortunatamente, anche più semplice da gestire. Analizzando il secondo costrutto, si può ritenere questo approccio molto più complicato che non eseguire il cast di un oggetto in una stringa per il confronto. Tuttavia, la difficoltà e la semplicità di un approccio sono relative. Utilizzo di SimpleXML per aggiornare codice XML Un altro dei grandi vantaggi offerti da SimpleXML è rappresentato dal fatto che consente di aggiornare i valori in maniera molto semplice. Si supponga di voler modificare la terza parola chiave dell esempio da PHP a JSP. Di seguito viene mostrato come procedere: 179

Capitolo 7: Elaborazione di dati XML con PHP $keywords->keyword[2] = JSP ; Per modificare il valore di un attributo, è sufficiente aggiungere il nome dell attributo appropriato come chiave di array: $keywords->keyword[2][ status ] = live ; Per salvare oppure visualizzare il codice XML aggiornato, utilizzare il metodo asxml: echo $keywords->asxml(); Correzione di problemi SimpleXML con DOM SimpleXML, pur nella sua semplicità ed eleganza, presenta alcuni svantaggi. In primo luogo, non è possibile (al momento della scrittura) aggiungere nuovi nodi a un documento XML, ma solo modificare i valori di quelli esistenti. Non è possibile neppure eliminare nodi. Non è possibile associare fogli di stile al proprio XML per eseguire trasformazioni. Infine, come è stato possibile notare, il codice PHP dipende fortemente dai nomi dei tag XML: se questi vengono modificati, l aggiornamento del codice può essere una vera seccatura. Ad ogni modo, SimpleXML dispone di una funzione davvero comoda che gli consente di interoperare con altre funzionalità XML PHP. Precisamente, questa funzionalità permette di importare documenti DOM e di convertirli in strutture di dati SimpleXML. Ma quali sono i vantaggi? Questa funzionalità consente di attuare la parte più impegnativa della funzionalità DOM nativa in PHP; successivamente è possibile convertirla in SimpleXML e completare il lavoro. Per comprendere quanto appena illustrato attraverso un esempio pratico, caricare un documento con DOM e apportarvi una modifica che non sarebbe possibile eseguire con SimpleXML: $doc = new DOMDocument(); $doc->preservewhitespace = false; $doc->load( keyword-data2.xml ); $root = $doc->documentelement; Esempio 7.25. sxmldemo5.php (estratto) $newkw = $doc->createelement( keyword, JSP ); $newkw->setattribute( status, live ); $root->appendchild($newkw); Con un nuovo elemento aggiunto alla struttura DOM, è possibile utilizzare la funzione simplexml_import_dom per importarlo in una struttura di dati SimpleXML. Successivamente, 180

Quando utilizzare i diversi metodi è possibile utilizzare l API SimpleXML per eseguire tutte le operazioni richieste: ad esempio, ricercare e visualizzare nodi con un determinato valore di attributo. Esempio 7.26. sxmldemo5.php (estratto) $keywords = simplexml_import_dom($doc); echo <ul> ; foreach ($keywords->xpath( keyword[@status= live ] ) as $kw) { echo <li>. htmlentities($kw). </li> ; echo </ul> ; Questo codice consente di visualizzare un elenco di parole chiave il cui status è live, compresa JSP, che è stata aggiunta utilizzando DOM. Quando utilizzare i diversi metodi A questo punto è lecito domandarsi quando è appropriato utilizzare SAX, DOM e/o SimpleXML. Di seguito vengono elencate alcune regole generali: Nel caso di un documento XML molto semplice che richiede unicamente una elaborazione lineare e che non deve essere modificato, SAX rappresenta la scelta appropriata. Se occorre elaborare un documento XML più complesso, ma al solo scopo di estrarre informazioni, SimpleXML rappresenta la scelta appropriata. Se occorre creare nuovi documenti XML oppure apportare modifiche sostanziali a documenti esistenti, utilizzare DOM. Progetto CMS A questo punto è possibile creare le funzionalità di amministrazione del progetto CMS. Gli strumenti di amministrazione di cui si dispone consentiranno agli utenti autorizzati di collegarsi a CMS e di amministrare le varie parti del sito Web. Più specificamente, si procederà alla realizzazione delle seguenti funzionalità: pagina di accesso/verifica indice amministrativo (da cui gli utenti di CMS possono accedere ad altre pagine) pagina per la creazione di nuovi articoli 181

Capitolo 7: Elaborazione di dati XML con PHP pagina per la modifica degli articoli pagina per l eliminazione degli articoli Dopo aver creato queste pagine, il discorso sullo strumento di amministrazione verrà temporaneamente interrotto e ripreso poi nell Appendice B, Strumento di amministrazione di CMS, in quanto gran parte delle informazioni è piuttosto ripetitiva e può essere trattata in una sezione a parte. Questa trattazione include: pagine per la creazione/modifica/eliminazione di notizie pagine per la creazione/modifica/eliminazione di file binari pagine per la creazione/modifica/eliminazione di categorie pagine per la creazione/modifica/eliminazione di amministratori Tutte le pagine dell area di amministrazione si trovano nella directory admin del sito. Disabilitazione della funzione magic quotes Tutti gli script PHP presenti in questo libro presuppongono che la funzione magic quotes di PHP sia disabilitata. Per disabilitare questa funzione, impostare l opzione magic_quotes_gpc contenuta nel file php.ini del proprio server su Off. Se questa funzione viene lasciata attiva, quando si manipola il contenuto utilizzando gli script di amministrazione che verranno sviluppati in questa sezione e nell Appendice B, Strumento di amministrazione di CMS, il contenuto presenterà numerose barre rovesciate (\) indesiderate. Pagina di accesso La pagina di accesso è molto semplice. Si basa su un elementare form HTML che consente agli amministratori di specificare il proprio nome utente e la propria password. Questo form diventerà più complesso quando si strutturerà l HTML in modo che possa essere efficacemente stilizzato grazie all applicazione di un CSS. <?php session_start();?> <!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd > <html xmlns= http://www.w3.org/1999/xhtml > <head> <title>please Log In</title> <meta http-equiv= Content-Type content= text/html; charset=iso-8859-1 > Esempio 7.27. login.php 182

Pagina di accesso <link rel= stylesheet type= text/css href=../xmlcms.css /> <link rel= stylesheet type= text/css href= login.css /> </head> <body> <form class= login action= verify.php method= post > <h1>please log in</h1> <div class= fields > <label for= username >User name</label> <input type= text id= username name= username class= text /> <label for= password >Password</label> <input type= password id= password name= password class= password /> </div> <div class= actions > <input type= submit value= Submit /> <input type= reset value= Reset /> </div> <p class= error ><?php echo $_SESSION[ error ];?></p> </form> </body> </html> Oltre al foglio di stile del sito di base (xmlcms.css), questa pagina utilizza un foglio di stile specifico per il layout del form di accesso. Come già evidenziato in precedenza, non essendo questo un manuale dedicato ai fogli di stile CSS, i dettagli relativi a questo file verranno tralasciati, ma per una questione di completezza di seguito ne viene fornito il codice: form.login { width: 290px; margin: 1em auto; padding: 4px; background: #ccc; form.login h1 { text-align: center; font-size: medium; background: #fff; margin: 1px; form.login.fields { text-align: right; form.login label { float: left; width: 130px; text-align: right; Esempio 7.28. login.css 183

Capitolo 7: Elaborazione di dati XML con PHP form.login.actions { text-align: center; form.login input.text, form.login input.password { width: 150px; margin-bottom: 1px; form.login.error { color: red; margin: 0; padding: 0; Analizzando la pagina di accesso, è possibile notare che l elemento action del form è impostato su una pagina denominata verify.php. La logica PHP contenuta in questa pagina deve verificare i valori immessi in un elenco di amministratori che si trova in admin.xml. Protezione dei file XML Ai fini degli esempi proposti in questo manuale e per l archiviazione del relativo codice, i file XML in cui si trovano il contenuto, le categorie, gli autori e gli utenti amministrativi sono stati inseriti in una sottodirectory del sito principale. Tuttavia, per proteggere ulteriormente le informazioni riservate contenute in questi file come, ad esempio, la crittografia delle password degli amministratori, fare in modo che i visitatori occasionali del sito non abbiano accesso diretto a questi file. Per proteggere questi file, è possibile configurare il server Web in modo che impedisca ai browser di accedere alla directory oppure è possibile spostare la directory all esterno della struttura di directory del sito accessibile dal Web. Nel secondo caso, sarà necessario modificare il file common.inc.php perché punti alla nuova ubicazione della directory, in modo che tutti gli script del sito possano trovare i file XML. Password crittografate Come è stato possibile notare, i valori delle password memorizzati in admin.xml vengono crittografati, così da garantire maggiore protezione. Per utilizzare il file di esempio admin.xml incluso nell archivio del codice per questo libro, occorre sapere che la password iniziale di tutti e tre gli amministratori memorizzata in quel file (joe, bill e tom) è password. In caso di corrispondenza, il codice PHP imposterà una variabile di sessione e reindirizzerà l utente verso la pagina dell indice di amministrazione. In caso contrario, PHP riporterà l utente di nuovo alla pagina login.php, con una variabile di sessione speciale ($_SESSION[ error ]) contenente un messaggio di errore da visualizzare. 184

Pagina di accesso Il codice specifico viene riportato di seguito. Si noti che in questo caso si è scelto di utilizzare SimpleXML, in quanto è il metodo più veloce per caricare le informazioni da admin.xml. <?php include_once../common.inc.php ; Esempio 7.29. verify.php $admins = simplexml_load_file($filedir. admin.xml ); foreach ($admins->admin as $admin) { if ($_POST[ username ] == (string)$admin->username and crypt($_post[ password ], (string)$admin->password) == (string)$admin->password) { $_SESSION[ login ] = true; header( location: index.php ); exit; $_SESSION[ error ] = Wrong user name or password. Try again. ; header( location: login.php );?> Inoltre, quando vengono crittografate le password in admin.xml, occorre accettare la password fornita dall utente, crittografarle allo stesso modo, quindi confrontare l input utente con la password memorizzata nel file XML. Se non si ha familiarità con la funzione crypt di PHP, è possibile consultare il manuale di PHP[4]. Dal momento che chiunque può immettere un URL per una delle pagine di amministrazione, è necessario garantire per il contenuto di queste pagine una maggiore protezione. Nella parte superiore di ciascuna pagina, occorre verificare se il valore della variabile di sessione $_SESSION[ login ] è impostato su true. Se questo valore non è impostato su true, l utente verrà indirizzato di nuovo verso la pagina login.php. Dal momento che questa funzionalità verrà utilizzata di nuovo, si consiglia di inserire questa verifica all interno di un file delle inclusioni: <?php include_once../common.inc.php ; Esempio 7.30. security.inc.php if (@$_SESSION[ login ]!== true) { header( location: login.php ); $_SESSION[ error ] = You must log in before you can access administration pages. ; exit;?> [4] http://www.php.net/crypt 185

Capitolo 7: Elaborazione di dati XML con PHP Disabilitazione della protezione per la configurazione iniziale Quando si configura il sito per la prima volta, è possibile che non siano stati ancora creati degli amministratori. Ci si chiede dunque come fare ad aggiungere amministratori se non è possibile eseguire l accesso. Per aggiungere i primi account amministratore, è necessario disabilitare la protezione: a tale scopo, annullare i commenti del contenuto del file security.inc.php, in modo che il file non possa eseguire alcuna azione. Successivamente, è necessario abilitare la visualizzazione libera delle pagine di amministrazione e aggiungere uno o due amministratori. Dopo di che, è possibile abilitare di nuovo la protezione e collegarsi utilizzando uno degli account appena creati. In ultimo, occorre creare una pagina di logout a cui collegarsi in modo che gli utenti possano scollegarsi e uscire dal sito prima di abbandonare la propria postazione: <?php include_once../common.inc.php ; Esempio 7.31. logout.php $_SESSION[ login ] = false; header( location: index.php );?> Pagina dell indice amministrativo La prima pagina dello strumento di amministrazione fornisce accesso a tutte le funzionalità e all intero contenuto del sito, compresi gli utenti amministrativi, gli articoli, i news item e altri tipi di contenuto. Il codice per questa pagina è molto conciso. È necessario fornire collegamenti a ciascuna delle principali parti dello strumento di amministrazione. <?php include security.inc.php ;?> <!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd > <html xmlns= http://www.w3.org/1999/xhtml > <head> <meta http-equiv= Content-Type content= text/html; charset=iso-8859-1 /> <title>welcome to the Admin Index Page</title> <link rel= stylesheet type= text/css href=../xmlcms.css /> Esempio 7.32. index.php 186

Utilizzo degli articoli </head> <body> <h1>welcome to the Admin Index Page</h1> <p> <a href= articletool.php >Manage Articles</a><br /> <a href= newstool.php >Manage News Items</a><br /> <a href= admintool.php >Manage Administrators</a> </p> <p><a href= logout.php >Log out</a></p> </body> </html> Ciascuna delle aree rappresentate da questi collegamenti avrà la stessa funzionalità. Ogni singola area consentirà agli utenti di CMS di creare, modificare ed eliminare item. Nelle sezioni successive verranno analizzate le singole attività per la prima area: gli articoli. Utilizzo degli articoli L area di amministrazione degli articoli consente agli utenti di CMS di creare nuovi articoli, modificare quelli esistenti e di eliminare articoli quando occorre. Dal momento che gli articoli sono la parte più importante del sito, si partirà da essi per poi procedere con i news item e gli amministratori del sito nell Appendice B, Strumento di amministrazione di CMS. Per la pagina principale dell area di amministrazione degli articoli, sarà necessario un elenco di tutti gli articoli presenti sul sito. Poiché si suppone di aver acquisito sufficiente dimestichezza con il codice PHP, questa operazione non dovrebbe risultare troppo complicata: Esempio 7.33. articletool.php <?php include security.inc.php ; include_once../common.inc.php ;?> <!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd > <html xmlns= http://www.w3.org/1999/xhtml > <head> <meta http-equiv= Content-Type content= text/html; charset=iso-8859-1 /> <title>article Index</title> <link rel= stylesheet type= text/css href=../xmlcms.css /> </head> <body> <h1>article Index</h1> 187

Capitolo 7: Elaborazione di dati XML con PHP <p><a href= articletool_create.php >Create New Article</a></p> <p><a href= index.php >Cancel</a></p> <ul> <?php $handle = opendir($filedir); while (($file = readdir($handle))!== FALSE) { if (is_dir($filedir. $file)) continue; if (!eregi( ^article.*\.xml$, $file)) continue; $articlefile = simplexml_load_file($filedir. $file); echo <li>. htmlentities($articlefile->headline); echo <a href= articletool_edit.php?id=. $articlefile[ id ]. >edit</a> ; echo <a href= doarticledelete.php?id=. $articlefile[ id ]. >delete</a></li> ;?> </ul> </body> </html> Creazione di nuovi articoli La pagina di creazione degli articoli è molto importante, in quanto consente agli amministratori del sito di creare nuovi articoli XML sul sito utilizzando un semplice form Web. Ciascuno dei campi del form è associato a un elemento nella struttura del documento XML pianificata nel Capitolo 1, Introduzione a XML, e modificata nel Capitolo 3, DTD per la consistenza. Gli articoli creati dovrebbero risultare come quello riportato di seguito: <?xml version= 1.0 encoding= iso-8859-1?> <article id= article12499300388912 > <authorid>1</authorid> <categoryid>1</categoryid> <headline>using XML with PHP</headline> <description>php offers many ways to work with XML</description> <pubdate>2004-06-26</pubdate> <status>live</status> <keywords>xml PHP SAX DOM SimpleXML</keywords> <body><![cdata[ <h1>using XML with PHP</h1> <p>php is very powerful. It offers many ways to work with XML.</p> ]]></body> </article> 188

Creazione di nuovi articoli In particolare, è bene ricordare che occorre generare un ID univoco e compilare tutte le varie parti dei metadati. Creare un form che contenga campi per tutte queste informazioni. Iniziare con la verifica che permette di assicurarsi che l utente è collegato: <?php include security.inc.php ; include_once../common.inc.php ;?> Esempio 7.34. articletool_create.php (estratto) Iniziare ora la creazione del codice HTML, includendo un collegamento a un nuovo foglio di stile denominato forms.css, che conterrà le regole per il layout di form di amministrazione piuttosto complessi come quello riportato di seguito: Esempio 7.35. articletool_create.php (estratto) <!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd > <html xmlns= http://www.w3.org/1999/xhtml > <head> <meta http-equiv= Content-Type content= text/html; charset=iso-8859-1 /> <title>create a New Article</title> <link rel= stylesheet type= text/css href=../xmlcms.css /> <link rel= stylesheet type= text/css href= forms.css /> </head> <body> Infine, creare il form. Il form è costituito prevalentemente da semplici campi, ma per selezionare un autore e una categoria occorrono elenchi dinamici che verranno estratti dai file appropriati utilizzando SimpleXML. Esempio 7.36. articletool_create.php (estratto) <h1>create a New Article</h1> <p><a href= articletool.php >Cancel</a></p> <form action= doarticlecreate.php method= post > <div class= fields > <p> <label for= headline >Headline</label> <input type= text id= headline name= headline class= text /> </p> <p> <label for= author >Author</label> <select id= authorid name= authorid > <?php 189

Capitolo 7: Elaborazione di dati XML con PHP $authors = simplexml_load_file($filedir. authors.xml ); foreach ($authors->author as $author) { echo <option value=. htmlentities($author[ id ]). >. htmlentities($author->name). </option> ;?> </select> </p> <p> <label for= category >Category</label> <select id= categoryid name= categoryid > <?php $cats = simplexml_load_file($filedir. categories.xml ); foreach ($cats->category as $cat) { echo <option value=. htmlentities($cat[ id ]). >. htmlentities($cat[ label ]). </option> ;?> </select> </p> <p> <label for= status >Status</label> <select id= status name= status > <option value= in progress >In Progress</option> <option value= live >Live</option> </select> </p> <p> <label for= keywords >Keywords</label> <input type= text id= keywords name= keywords class= text /> </p> <p> <label for= description >Description</label> <textarea id= description name= description ></textarea> </p> <p> <label for= body >Article Body (HTML)</label> <textarea id= body name= body ></textarea> </p> </div> <div class= actions > <input type= submit value= Add Article /> <input type= reset value= Reset /> </div> </form> </body> </html> 190

Creazione di nuovi articoli Di seguito viene riportato il codice del foglio di stile che esegue il layout di questo complesso form: form.actions { text-align: center; form p { clear: left; margin: 1px 0; form label { float: left; width: 15%; padding-right: 10px; text-align: right; input.text, input.password, select { width: 300px; textarea { width: 70%; height: 4em; textarea#body { height: 30em; Esempio 7.37. forms.css L action del form è impostata sulla pagina doarticlecreate.php, che utilizza funzioni DOM per creare un articolo XML dalle informazioni contenute nel form. Dal momento che si tratta di un passaggio molto complesso, il codice verrà riportato e analizzato a blocchi. La prima parte del file è l inizio del nuovo documento XML, in cui viene impostata la versione e creato l elemento root, article. <?php include security.inc.php ; include_once../common.inc.php ; Esempio 7.38. doarticlecreate.php (estratto) $doc = new DOMDocument(); $root = $doc->createelement( article ); $root = $doc->appendchild($root); 191

Capitolo 7: Elaborazione di dati XML con PHP Successivamente, viene aggiunto un attributo id al nodo article. L ID sarà composto dal termine article seguito da un timestamp. Nel caso in cui si creino contemporaneamente più di un articolo, ricercare un file esistente il cui nome contenga lo stesso ID e incrementare il timestamp di un unità fino a individuare un ID che non crei conflitti. Esempio 7.39. doarticlecreate.php (estratto) $timestamp = date( YmdHis ); do { $id = article. $timestamp++; while (file_exists($filedir. $id..xml )); $root->setattribute( id, $id); Dopo aver creato l elemento root, occorre creare, nell ordine appropriato, i relativi elementi figlio. Il primo è authorid. Si noti che l elemento authorid è un elemento figlio di article e che lo stesso ID è un elemento figlio di authorid. Esempio 7.40. doarticlecreate.php (estratto) $author = $doc->createelement( authorid ); $root->appendchild($author); $atext = $doc->createtextnode($_post[ authorid ]); $author->appendchild($atext); Viene utilizzata la stessa tecnica illustrata sopra per generare gli elementi categoryid, headline, description, status e keywords. Il valore di pubdate viene generato dallo script, ma per il resto è lo stesso. Esempio 7.41. doarticlecreate.php (estratto) $cat = $doc->createelement( categoryid ); $root->appendchild($cat); $ctext = $doc->createtextnode($_post[ categoryid ]); $cat->appendchild($ctext); $head = $doc->createelement( headline ); $root->appendchild($head); $htext = $doc->createtextnode($_post[ headline ]); $head->appendchild($htext); $desc = $doc->createelement( description ); $root->appendchild($desc); $dtext = $doc->createtextnode($_post[ description ]); $desc->appendchild($dtext); $pub = $doc->createelement( pubdate ); $root->appendchild($pub); $pubtext = $doc->createtextnode(date( Y-m-d )); $pub->appendchild($pubtext); 192

Creazione di nuovi articoli $stat = $doc->createelement( status ); $root->appendchild($stat); $stext = $doc->createtextnode($_post[ status ]); $stat->appendchild($stext); $key = $doc->createelement( keywords ); $root->appendchild($key); $ktext = $doc->createtextnode($_post[ keywords ]); $key->appendchild($ktext); Successivamente, viene elaborato il testo del corpo. È bene ricordare che tali informazioni dovranno essere archiviate come HTML, il che significa che conterranno numerosi tag. Se si utilizza DOM per emettere questo valore come testo, il file XML risultante sarà difficile da leggere, con entità di caratteri quali < e > sparse in tutto il file. Come già menzionato nel Capitolo 1, Introduzione a XML, per garantire la leggibilità del codice, occorre memorizzare il testo del corpo come sezione CDATA all interno del file XML, in modo che i caratteri speciali non debbano essere convertiti in entità di caratteri. Anziché utilizzare createtextnode, verrà utilizzato createcdatasection. Il testo HTML del form verrà inserito all interno di questo comando. Esempio 7.42. doarticlecreate.php (estratto) $body = $doc->createelement( body ); $root->appendchild($body); $cdata = $doc->createcdatasection($_post[ body ]); $body->appendchild($cdata); Successivamente, scrivere l intera struttura ad albero XML in un file, utilizzando l ID generato precedentemente con un nome file: $filename = $filedir. $id..xml ; $doc->save($filename); Esempio 7.43. doarticlecreate.php (estratto) Infine, occorre reindirizzare l utente verso la pagina articletool.php, dove il file appena creato dovrebbe essere contenuto nell elenco degli articoli principale. header( location: articletool.php ); Esempio 7.44. doarticlecreate.php (estratto) 193

Capitolo 7: Elaborazione di dati XML con PHP Modifica di un articolo XML In genere, la modifica di un articolo XML è pressoché uguale alla creazione di un articolo, ad eccezione del fatto che occorre caricare i valori di un articolo esistente nel form e scrivere le modifiche apportate all esterno del file. Come prima cosa, creare il codice per la pagina del form. La prima parte dovrebbe risultare ora familiare: infatti, verifica che l utente sia collegato. <?php include security.inc.php ; include_once../common.inc.php ; Esempio 7.45. articletool_edit.php (estratto) Successivamente, occorre aprire il file per ricercare il documento che l utente desidera modificare. Poiché per ora non verranno apportate modifiche al file, è possibile utilizzare SimpleXML per aprire il file ed estrarre le informazioni necessarie. Esempio 7.46. articletool_edit.php (estratto) if (!isset($_get[ id ]) $_GET[ id ] ==!file_exists($filedir. $_GET[ id ]..xml )) { header( location: articletool.php ); exit; $file = simplexml_load_file($filedir. $_GET[ id ]..xml );?> Si dispone ora semplicemente della markup per un form molto simile a quello di articletool_create.php, ad eccezione del fatto che questa volta il valore esistente per ciascun file verrà richiamato dalla variabile $file. Esempio 7.47. articletool_edit.php (estratto) <!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd > <html xmlns= http://www.w3.org/1999/xhtml > <head> <meta http-equiv= Content-Type content= text/html; charset=iso-8859-1 /> <title>edit Article</title> <link rel= stylesheet type= text/css href=../xmlcms.css /> <link rel= stylesheet type= text/css href= forms.css /> </head> <body> <h1>edit Article</h1> <p><a href= articletool.php >Cancel</a></p> <form action= doarticleupdate.php method= post > <input type= hidden name= id value= <?php echo htmlentities($_get[ id ]);?> /> 194

Modifica di un articolo XML <div class= fields > <p> <label for= headline >Headline</label> <input type= text id= headline name= headline class= text value= <?php echo htmlentities($file->headline);?> /> </p> <p> <label for= author >Author</label> <select id= authorid name= authorid > <?php $authors = simplexml_load_file($filedir. authors.xml ); foreach ($authors->author as $author) { if ((string)$author[ id ] == (string)$file->authorid) { echo <option value=. htmlentities($author[ id ]). selected= selected >. htmlentities($author->name). </option> ; else { echo <option value=. htmlentities($author[ id ]). >. htmlentities($author->name). </option> ;?> </select> </p> <p> <label for= category >Category</label> <select id= categoryid name= categoryid > <?php $cats = simplexml_load_file($filedir. categories.xml ); foreach ($cats->category as $cat) { if ((string)$cat[ id ] == (string)$file->categoryid) { echo <option value=. htmlentities($cat[ id ]). selected= selected >. htmlentities($cat[ label ]). </option> ; else { echo <option value=. htmlentities($cat[ id ]). >. htmlentities($cat[ label ]). </option> ;?> </select> </p> <p> <label for= status >Status</label> <select id= status name= status > <option value= in progress <?php if ((string)$file->status == in progress ) echo selected= selected?>>in Progress</option> 195

Capitolo 7: Elaborazione di dati XML con PHP <option value= live <?php if ((string)$file->status == live ) echo selected= selected?>>live</option> </select> </p> <p> <label for= keywords >Keywords</label> <input type= text id= keywords name= keywords class= text value= <?php echo htmlentities($file->keywords);?> /> </p> <p> <label for= description >Description</label> <textarea id= description name= description > <?php echo htmlentities($file->description);?></textarea> </p> <p> <label for= body >Article Body (HTML)</label> <textarea id= body name= body > <?php echo htmlentities($file->body);?></textarea> </p> </div> <div class= actions > <input type= submit value= Update Article /> <input type= reset value= Reset /> </div> </form> </body> </html> Il file doarticleupdate.php doarticlecreate.php: che elabora questo form è molto simile allo script <?php include security.inc.php ; include_once../common.inc.php ; Esempio 7.48. doarticleupdate.php $doc = new DOMDocument(); $root = $doc->createelement( article ); $root = $doc->appendchild($root); $id = $_POST[ id ]; $root->setattribute( id, $id); $filename = $filedir. $id..xml ; unlink($filename); 196

Eliminazione di un articolo XML $doc->save($filename); header( location: articletool.php );?> Eliminazione di un articolo XML Eliminare un file XML è un operazione molto semplice. Quando si passa un ID alla pagina doarticledelete.php, il file corrispondente viene eliminato e l utente viene riportato alla pagina articletool.php: <?php include security.inc.php ; include_once../common.inc.php ; Esempio 7.49. doarticledelete.php $filename = $filedir. $_GET[ id ]..xml ; unlink($filename); header( location: articletool.php );?> A questo punto, si dispone di una pagina di accesso, di un indice amministrativo, nonché di pagine in cui è possibile aggiungere, modificare ed eliminare gli articoli. Come già anticipato nel corso di questo capitolo, le altre pagine di amministrazione verranno descritte nell Appendice B, Strumento di amministrazione di CMS. Come sarà possibile notare, il codice scritto per la creazione di queste prime pagine verrà utilizzato di nuovo per completare la realizzazione dello strumento di amministrazione. Riepilogo In questo capitolo è stato illustrato l utilizzo delle funzionalità SAX, DOM e SimpleXML in PHP. A questo punto, le informazioni acquisite finora sono sufficienti per gestire la maggior parte delle attività di elaborazione XML. La seconda parte di questo capitolo è stata dedicata alla creazione di form amministrativi necessari per gestire gli articoli del sito Web. Nel capitolo successivo verranno descritti i due standard RSS e RDF, generalmente utilizzati per la creazione di intestazioni e altri feed di informazioni disponibili per terze parti nel formato XML. 197