Din fråga är verkligen bred, det bästa svaret jag kan ge är att du bör använda något befintligt bibliotek för att koda XML istället för att skriva ditt eget (eftersom du uppenbarligen misslyckas med jobbet, därav XML-kodningsfelet som rapporterats av XML-konsumenten).
Genom att använda ett befintligt bibliotek kan du också påpeka problem tidigare. T.ex. för följande kod se till att allt du får tillbaka från din databas är UTF-8-kodade strängar.
Att även använda en modernare databasklientklass kommer också att hjälpa dig att mycket bara skriva ner koden. Här är ett exempel med PDO
och 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();
Se det DomDocument
tar här hand om att korrekt koda UTF-8-strängarna som returneras från databasen. Det finns (normalt) inget behov av här längre. Som du kan föreställa dig har du troligtvis lagt in något där som bröt din XML-kodning.
Också för databasinteraktionen är det mesta av din kod inte heller nödvändig, du kan bara iterera över raderna, om det inte finns några rader skulle det inte finnas någon iteration. Detta uttrycks normalt bäst med en Iterator
foreach
språkkonstruktion kan arbeta på vilket tillhandahålls av moderna databasgränssnitt. Tekniskt sett kan du ersätta $rows
här med många andra saker, som en iterator som går över flera tabeller efter varandra.
Genom att använda undantagsfelläget slipper du placera kontroller och dö
finns över hela din kodbas.
Ett exempel på utdata är:
<?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>
Om du sedan fortfarande behöver skapa CDATA-element fungerar det på samma sätt (jag visar bara en del av skriptet här, som bara innehåller en liten modifiering som lägger till CDATA-sektioner istället för ett underordnat värde):
### 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))
;
}
}
Även här, DOMDocument
tar hand om korrekt kodning av CDATA-sektionen. Något du förmodligen inte gjorde.
Potentiella problem som du fortfarande kan stöta på är med tabell- eller radnamn som är ogiltiga XML-namn
. Men sedan DOMDocument
kommer faktiskt att berätta så att du vet när XML genereras, inte bara efteråt med ett kodningsfel.