Mysql
 sql >> Database >  >> RDS >> Mysql

Errore di codifica PHP durante la produzione di XML dal database

La tua domanda è davvero ampia, la migliore risposta che posso dare è che dovresti usare una libreria esistente per codificare l'XML invece di scriverne uno tuo (poiché ovviamente fallisci con il lavoro, quindi l'errore di codifica XML segnalato dal consumo XML).

L'utilizzo di una libreria esistente consentirebbe anche di evidenziare i problemi in precedenza. Per esempio. per il codice seguente assicurati che tutto ciò che ottieni dal tuo database siano stringhe con codifica UTF-8.

Anche l'uso di una classe client di database più moderna ti aiuterà anche a scrivere il codice. Ecco un esempio con PDO e DOMDocument :

### configuration values

$config = array(
    'Database'     => array(
        'dsn'  => 'mysql:dbname=test;host=localhost;charset=utf8',
        'user' => 'testuser',
        'pass' => 'test',
    ),
    'table_name'   => 'config',
    'table_fields' => '*',
);

### implement database access

class Database extends PDO
{
    public function __construct(array $config = null)
    {
        $config = $config ? : $GLOBALS['config'][__CLASS__];
        parent::__construct($config['dsn'], $config['user'], $config['pass']);
        $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
        $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    }
}

### setup the datasource ($rows)

$db   = new Database();
$rows = $db->query("SELECT $config[table_fields] FROM $config[table_name]");

### setup the XML encoder ($doc)

$doc               = new DOMDocument();
$doc->formatOutput = true;
$doc->loadXML("<$config[table_name]s/>");
$doc->encoding = 'utf-8';

### fetch data from the datasource and encode the XML

foreach ($rows as $row) {
    $child = $doc->createElement($config['table_name']);
    $child = $doc->documentElement->appendChild($child);
    foreach ($row as $key => $value) {
        $child->appendChild($doc->createElement($key, $value));
    }
}

### output XML

header("Content-Type:text/xml");
echo $doc->saveXML();

Vedi quel DomDocument si occupa qui di codificare correttamente le stringhe UTF-8 restituite dal database. Non c'è (normalmente) bisogno di <![CDATA[...]]> qui più a lungo. Come puoi immaginare, probabilmente hai inserito qualcosa che ha violato la tua codifica XML.

Anche per l'interazione con il database, la maggior parte del codice non è necessaria, puoi semplicemente scorrere le righe, se non ci sono righe, non ci sarebbe alcuna iterazione. Questo è normalmente meglio espresso con un Iterator il foreach il costrutto del linguaggio può operare su cui è fornito dalle moderne interfacce di database. Tecnicamente puoi sostituire $rows qui con molte altre cose, come un iteratore che va su più tabelle una dopo l'altra.

Inoltre, l'utilizzo della modalità di errore dell'eccezione ti risparmia di piazzare assegni e die s in tutta la tua base di codice.

Un output esemplare è:

<?xml version="1.0" encoding="utf-8"?>
<configs>
  <config>
    <id>1</id>
    <option>value for option with ID1</option>
  </config>
  <config>
    <id>2</id>
    <option>value for option with ID2</option>
  </config>
  ...
</configs>

Se poi hai ancora bisogno di creare elementi CDATA, funziona in modo simile (qui mostro solo una parte dello script, che contiene solo una leggera modifica aggiungendo sezioni CDATA invece di un valore figlio):

### fetch data from the datasource and encode the XML

foreach ($rows as $row) {
    $child = $doc->createElement($config['table_name']);
    $child = $doc->documentElement->appendChild($child);
    foreach ($row as $key => $value) {
        $child->appendChild($doc->createElement($key))
              ->appendChild($doc->createCDATASection($value))
        ;
    }
}

Anche qui DOMDocument si occupa di codificare correttamente la sezione CDATA. Qualcosa che probabilmente non hai fatto.

I potenziali problemi che potresti ancora incontrare riguardano i nomi di tabelle o righe nomi XML non validi . Ma poi DOMDocument ti dirà effettivamente in modo che tu lo sappia durante la generazione dell'XML, non solo in seguito con un errore di codifica.