Mysql
 sql >> Datenbank >  >> RDS >> Mysql

PHP-Codierungsfehler beim Erzeugen von XML aus der Datenbank

Ihre Frage ist wirklich weit gefasst, die beste Antwort, die ich geben kann, ist, dass Sie eine vorhandene Bibliothek verwenden sollten, um das XML zu codieren, anstatt Ihre eigene zu schreiben (da Sie offensichtlich mit dem Job scheitern, daher der vom XML-Konsumenten gemeldete XML-Codierungsfehler).

Die Verwendung einer vorhandenen Bibliothek würde es Ihnen auch ermöglichen, früher auf Probleme hinzuweisen. Z.B. Stellen Sie für den folgenden Code sicher, dass alles, was Sie von Ihrer Datenbank zurückerhalten, UTF-8-codierte Zeichenfolgen sind.

Auch die Verwendung einer moderneren Datenbank-Client-Klasse hilft Ihnen dabei, den Code einfach aufzuschreiben. Hier ist ein Beispiel mit PDO und 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();

Siehe dieses DomDocument kümmert sich hier um die korrekte Codierung der UTF-8-Zeichenfolgen, die von der Datenbank zurückgegeben werden. <![CDATA[...]]> ist (normalerweise) nicht erforderlich hier nicht länger. Wie Sie sich vorstellen können, haben Sie dort wahrscheinlich etwas eingefügt, das Ihre XML-Codierung beschädigt hat.

Auch für die Datenbankinteraktion ist der größte Teil Ihres Codes nicht erforderlich, Sie können einfach über die Zeilen iterieren, wenn es keine Zeilen gibt, würde es keine Iteration geben. Dies wird normalerweise am besten mit einem Iterator ausgedrückt die foreach Sprachkonstrukte operieren können, die durch moderne Datenbankschnittstellen bereitgestellt werden. Technisch gesehen können Sie $rows ersetzen hier mit vielen anderen Dingen, wie einem Iterator, der mehrere Tabellen nacheinander durchgeht.

Zusätzlich erspart Ihnen die Verwendung des Ausnahmefehlermodus das Setzen von Häkchen und die s überall in Ihrer Codebasis.

Eine beispielhafte Ausgabe ist:

<?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>

Wenn Sie dann noch CDATA-Elemente erstellen müssen, funktioniert es ähnlich (ich zeige hier nur einen Teil des Skripts, der nur eine geringfügige Änderung enthält, indem CDATA-Abschnitte anstelle eines untergeordneten Werts hinzugefügt werden):

### 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))
        ;
    }
}

Auch hier DOMDocument kümmert sich um die korrekte Codierung des CDATA-Abschnitts. Etwas, das Sie wahrscheinlich nicht getan haben.

Mögliche Probleme, auf die Sie noch stoßen könnten, sind Tabellen- oder Zeilennamen, die ungültige XML-Namen . Aber dann DOMDocument wird Ihnen eigentlich schon beim Generieren des XML mitteilen, nicht erst hinterher mit einem Codierungsfehler.