sql >> Database >  >> RDS >> Mysql

PHP-coderingsfout bij het produceren van XML uit database

Je vraag is erg breed, het beste antwoord dat ik kan geven is dat je een bestaande bibliotheek moet gebruiken om de XML te coderen in plaats van je eigen te schrijven (omdat je duidelijk faalt met de taak, vandaar de XML-coderingsfout gerapporteerd door de XML-consument).

Door een bestaande bibliotheek te gebruiken, kunt u ook eerder op problemen wijzen. bijv. voor de volgende code moet je ervoor zorgen dat alles wat je terugkrijgt van je database UTF-8-gecodeerde strings zijn.

Ook het gebruik van een modernere database-clientklasse zal u ook helpen om de code gewoon op te schrijven. Hier is een voorbeeld met PDO en 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();

Zie dat DomDocument zorgt hier voor de juiste codering van de UTF-8-strings die uit de database worden geretourneerd. Er is (normaal gesproken) geen <![CDATA[...]]> nodig hier niet langer. Zoals je je kunt voorstellen, heb je waarschijnlijk iets erin gestopt dat je XML-codering heeft verbroken.

Ook voor de database-interactie is het grootste deel van je code ook niet nodig, je kunt gewoon de rijen herhalen, als er geen rijen zijn, zou er geen iteratie zijn. Dit wordt normaal gesproken het best uitgedrukt met een Iterator de foreach taalconstructie kan werken op die wordt geleverd door moderne database-interfaces. Technisch gezien kun je $rows replace vervangen hier met veel andere dingen, zoals een iterator die meerdere tabellen na elkaar doorloopt.

Bovendien bespaart het gebruik van de uitzonderingsfoutmodus u cheques te plaatsen en die is overal in je codebase.

Een voorbeeldige output is:

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

Als je dan nog steeds CDATA-elementen moet maken, werkt het op dezelfde manier (ik laat hier slechts een deel van het script zien, dat slechts een kleine wijziging bevat door CDATA-secties toe te voegen in plaats van een onderliggende waarde):

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

Ook hier, DOMDocument zorgt voor de juiste codering van de CDATA-sectie. Iets dat je waarschijnlijk niet hebt gedaan.

Mogelijke problemen die u nog steeds kunt tegenkomen, zijn met tabel- of rijnamen die ongeldige XML-namen . Maar dan DOMDocument zal het u daadwerkelijk vertellen, zodat u het weet tijdens het genereren van de XML, niet alleen achteraf met een coderingsfout.



  1. Geen toegewezen Doctrine ORM-entiteiten volgens de huidige configuratie

  2. Krijg een lijst met datums tussen twee datums met behulp van een functie

  3. SQL-instructie om tabel te schrijven?

  4. Voorbeeld DW-database herstellen AdventureWorksDW2019