sql >> Databáze >  >> RDS >> Mysql

Chyba kódování PHP při vytváření XML z databáze

Vaše otázka je opravdu široká, nejlepší odpověď, kterou mohu dát, je, že byste měli ke kódování XML použít nějakou existující knihovnu místo psaní své vlastní (protože se vám zjevně nedaří s úlohou, proto chyba kódování XML hlášená spotřebitelem XML).

Použití existující knihovny by vám také umožnilo upozornit na problémy dříve. Např. pro následující kód zajistěte, aby vše, co získáte zpět z databáze, jsou řetězce zakódované v UTF-8.

Také použití modernější třídy databázového klienta vám také pomůže velmi jednoduše zapsat kód. Zde je příklad s PDO a 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();

Podívejte se na tento DomDocument se zde stará o správné kódování řetězců UTF-8, které jsou vráceny z databáze. <![CDATA[...]]> (normálně) není potřeba tady už déle. Jak si dokážete představit, pravděpodobně jste tam vložili něco, co narušilo vaše kódování XML.

Také pro interakci s databází není nutná ani většina vašeho kódu, můžete jen iterovat přes řádky, pokud žádné řádky nejsou, žádná iterace by nebyla. To se obvykle nejlépe vyjadřuje pomocí Iterator foreach může fungovat jazykový konstrukt, na kterém je poskytováno moderní databázová rozhraní. Technicky můžete nahradit $rows zde s mnoha dalšími věcmi, jako je iterátor, který prochází více tabulkami jednu po druhé.

Navíc použití režimu chyb výjimek vás ušetří na umisťování kontrol a die je po celé vaší kódové základně.

Příkladný výstup je:

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

Pokud pak stále potřebujete vytvořit prvky CDATA, funguje to podobně (zde uvádím pouze část skriptu, která obsahuje pouze drobnou úpravu přidáním částí CDATA namísto podřízené hodnoty):

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

Zde také DOMDocument se stará o správné kódování sekce CDATA. Něco, co jste pravděpodobně neudělali.

Potenciální problémy, se kterými se stále můžete setkat, jsou s názvy tabulek nebo řádků, které jsou neplatné názvy XML . Ale pak DOMDocument ve skutečnosti vám to řekne, abyste věděli při generování XML, nejen poté s chybou kódování.



  1. Použití Mysql v příkazovém řádku v osx - příkaz nenalezen?

  2. Jak přenášíte nebo exportujete data SQL Server 2005 do Excelu

  3. Jak mohu použít UUID v SQLAlchemy?

  4. java.sql.SQLException:Nebyl nalezen žádný vhodný ovladač pro jdbc:mysql://localhost:3306/dbname