XML e PHP

Sto scrivendo un gestionale per FAQ, queste ultime sono immagazzinate in file xml, fin qui pochi problemi.

Purtroppo però incontro problemi con la codifica UTF-8, ovvero per scrivere le FAQ uso queste poche righe:

function creaXML($domanda, $risposta, $num) {
   // Creo il file XML
      $xml_doc = new DOMDocument('1.0', 'utf-8');
      $xml_doc->formatOutput = true;
      
      $root = $xml_doc->createElement('root');
      $root_dom = $xml_doc->createElement('domanda');
      $root_dom_testo = $xml_doc->createTextNode($domanda);
      
      $root_ris = $xml_doc->createElement('risposta');
      $root_ris_testo = $xml_doc->createTextNode($risposta);
      
      $root_dom->appendChild($root_dom_testo);
      $root->appendChild($root_dom);
      $root_ris->appendChild($root_ris_testo);
      $root->appendChild($root_ris);
      $root->setAttribute('FAQ', (string)$num);
      $xml_doc->appendChild($root);
      $xml_doc->save("./FAQ/$num.xml");
   }

e per leggere, sto sviluppando or ora la giusta routine e qui incontro il primo scoglio:

Warning: simplexml_load_file() [function.simplexml-load-file]: FAQ/1.xml:4: parser error : Input is not proper UTF-8, indicate encoding ! Bytes: 0xF9 0x20 0x70 0x72 in E:\SERVER\xampp\htdocs\www\FAQ\index.php on line 26

Insomma il sistema non codifica affatto in UTF-8 ma in iso-8859-1 la lingua del sistema.

Non ha senso e comunque, anche se la cosa così di primo acchitto mi può persino andare bene, in un futuro preferirei usare l'utf, che modifiche posso fare?

inviato 10 anni fa
Marco Grazia
X 0 X

Ciao, su che versione di php fai girare lo scritp ?

risposto 10 anni fa
Toto007
X 0 X

Giusto! 5.1.5 anche se dal tipo di PHP si doveva capire  :D

risposto 10 anni fa
Marco Grazia
X 0 X

Forse ci sono arrivato da solo, in pratica su un libro appena visto in libreria, facendo un esempio simile al mio, prima di salvare il file con la funzione save(), fa un unlink al file stesso.

Ho guardato la funzione unlink() nel manuale di PHP e ho notato che è la copia di unlink in unix, ovvero cancella il file. Quindi per poter modificare un file con le funzioni del DOM in PHP, bisogna prima cancellare fisicamente il file dal disco rigido e poi riscriverlo.

Daccordo è la stessa cosa che il PHP fa in automatico quando lo si apre che so, con fopen() e i parametri r+ o w+  ma appunto ci pensa lui, qui pare che bisogna farlo a mano con unlink().

Stasera ci provo.

risposto 10 anni fa
Marco Grazia
X 0 X

Ho risolto alla vecchia maniera, quella che si usava tantissimi anni fa, anche se qualcosa qui non va.

<?php
                // Salvataggio del file
      $tmp_name = 'FAQ/' . session_id("faq") . '.xml'; // Nome e percorso del file temporaneo
      $xml_doc->save($tmp_name);   // Salvo il file temporaneo come xml
      $xml_name = "FAQ/$num.xml";   // Nome e percorso del file xml da creare
      if (file_exists($xml_name)) unlink($xml_name);   // Se già esiste un file con questo nome lo cancello
      rename($tmp_name, $xml_name);   // Rinomino il file temporaneo col giusto nome del file xml
?>

Dunque: per prima cosa creo il nome univoco di per un file temporaneo, usando come nome l'identificativo di sessione, così è sicuramente univoco.

Non uso tmpfile() perché per salvare un file in formato xml con la funzione DOM->save() deve avere necessariamente l'estenzione .xml e la tmpfile() mi mette sempre .tmp come estenzione, quindi ho creato questo sistema per crearmi il file temporaneo a nome unico, inoltre questo sistema mi permetterà di fare altre migliorie in futuro.

quindi salvo il file XML col nme temporaneo.

Ottengo il nome per il file definitivo, quello che conterrà la FAQ vero e proprio e se il file già esiste nella directory delle FAQ, lo cancello; dopo tutto è una modifica, se non c'è è un file nuovo e va bene lo stesso.

Fatto ciò rinomino il file temporaneo, già salvato in precedenza col giusto nome della DAQ ed è fatta.

Perché tutto 'sto casino? Semplice.

Se dopo che il file temporaneo è stato salvato mi cade la connessione per qualsiasi motivo, almeno mi rimane questo file memorizzato nel file system del server e quindi il lavoro fatto non lo perdo, se ripristino la sessione (ecco la modifica futura da fare) mi basta richiamare il file temporaneo e rinominarlo, così da non perdere il lavoro già fatto.

Cosa non funziona? A volte la funzione dom->save() mi va in errore perché tenta di salvare un file vuoto, il che è pazzesco, ma va così, e non capisco perché, ovviamente i dati passati ci sono tutti, se no il codice a monte nemmeno chiamerebbe la funzione di salvataggio/modifica.

Per la precisione, l'intera funzione è questa:

<?php
function creaXML($domanda, $risposta, $num) {
   // Creo il file XML
      $xml_doc = new DOMDocument('1.0', 'iso-8859-1');
      $xml_doc->formatOutput = true;
      
      $root = $xml_doc->createElement('root');
      $root_dom = $xml_doc->createElement('domanda');
      $root_dom_testo = $xml_doc->createTextNode($domanda);
      
      $root_ris = $xml_doc->createElement('risposta');
      $root_ris_testo = $xml_doc->createTextNode($risposta);
      
      $root_dom->appendChild($root_dom_testo);
      $root->appendChild($root_dom);
      $root_ris->appendChild($root_ris_testo);
      $root->appendChild($root_ris);
      $root->setAttribute('FAQ', (string)$num);
      $xml_doc->appendChild($root);
      
      // Salvataggio del file
      $tmp_name = 'FAQ/' . session_id("faq") . '.xml'; // Nome e percorso del file temporaneo
      $xml_doc->save($tmp_name);   // Salvo il file temporaneo come xml
      $xml_name = "FAQ/$num.xml";   // Nome e percorso del file xml da creare
      if (file_exists($xml_name)) unlink($xml_name);   // Se già esiste un file con questo nome lo cancello
      rename($tmp_name, $xml_name);   // Rinomino il file temporaneo col giusto nome del file xml
   }
risposto 10 anni fa
Marco Grazia
X 0 X

Ma nel tuo codice c'è:

$xml_doc = new DOMDocument('1.0', 'iso-8859-1');

non doveva essere UTF8?

risposto 10 anni fa
Gianni Tomasicchio
X 0 X

Ma nel tuo codice c'è:

$xml_doc = new DOMDocument('1.0', 'iso-8859-1');

non doveva essere UTF8?

L'ho cambiato Gianni, non ho trovato una soluzione al mio problema, quindi nel frattempo lo inserisco in quel formato.

Purtroppo come sai il PHP non gestisce il formato utf, e questo vale anche per quel modulo purtroppo.

Una delle pecche di PHP :(

risposto 10 anni fa
Marco Grazia
X 0 X

Purtroppo come sai il PHP non gestisce il formato utf, e questo vale anche per quel modulo purtroppo.

Una delle pecche di PHP :(

Neanche il DOM supporta l'UTF8? Porca pupazza!  :'(

Hai controllato se in qualche framework recente (es. Zend, ezComponents) c'è qualcosa per gestire l'XML anche in UTF8?

Ma quando arriva PHP 6 ?  :tichedoff:

risposto 10 anni fa
Gianni Tomasicchio
X 0 X

Come tu sai, per salvare in UTF-x non basta la dichiarazione come per le altre tabelle iso, dato che comunque il salvataggio prevede un numero superiore di byte per supportare l'enorme tabella caratteri utf.

Le funzioni DOM di cui parlo sono quelle del PHP, e non il Document Object Model supportato dai browser, quindi in realtà sempre di PHP si parla ed è un peccato che sia così.

Tu dici di vedere qualche modulo particolare, io ti dico che non ne voglio inserire, anche se questa cosa che sto facendo è uno script che mi serve a me personalmente, non voglio comunque realizzare qualcosa che un domani non possa distribuire gratuitamente, penalizzando però chi non supporta quei moduli, senza dover reinventare la ruota ancora una volta.

PHP 6 dici? Spero di no, ma perché se il passaggio alla versione 5 non è stata (e non è) priva di dolore, quando arriverà la 6 così diversa, almeno nelle premesse, la rivoluzione sarà ancora più dolorosa, quindi meglio prima vedere cosa sarà e poi semmai programmare la migrazione.

risposto 10 anni fa
Marco Grazia
X 0 X

Sapevo a quale DOM ti stavi riferendo...

Ti segnalo questa raccolta di esempi di codice relativi a PHP/XML. In diversi ho visto la magica parolina UTF8... Vedi se ti possono tornare utili.

http://www.cdatazone.org/files/workshop.zip

 :bye:

risposto 10 anni fa
Gianni Tomasicchio
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda