sql >> Base de Datos >  >> RDS >> Mysql

Error de codificación de PHP al producir XML desde la base de datos

Su pregunta es realmente amplia, la mejor respuesta que puedo dar es que debe usar alguna biblioteca existente para codificar el XML en lugar de escribir la suya propia (ya que obviamente falla con el trabajo, por lo tanto, el error de codificación XML informado por el consumidor XML).

El uso de una biblioteca existente también le permitiría señalar problemas antes. P.ej. para el siguiente código, asegúrese de que todo lo que obtenga de su base de datos sean cadenas codificadas en UTF-8.

Además, el uso de una clase de cliente de base de datos más moderna también lo ayudará en gran medida a escribir el código. Aquí hay un ejemplo con PDO y 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();

Ver que DomDocument se ocupa aquí de codificar correctamente las cadenas UTF-8 que se devuelven desde la base de datos. No hay (normalmente) necesidad de <![CDATA[...]]> aquí por más tiempo. Como puede imaginar, es probable que haya puesto algo allí que rompió su codificación XML.

Además, para la interacción con la base de datos, la mayor parte de su código tampoco es necesario, simplemente puede iterar sobre las filas, si no hay filas, no habría iteración. Normalmente, esto se expresa mejor con un Iterator el foreach la construcción del lenguaje puede operar en lo que proporcionan las interfaces de bases de datos modernas. Técnicamente puedes reemplazar $rows aquí con muchas otras cosas, como un iterador que recorre varias tablas una tras otra.

Además, el uso del modo de error de excepción le evita colocar cheques y die s en todo su código base.

Un resultado ejemplar es:

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

Si aún necesita crear elementos CDATA, funciona de manera similar (aquí muestro solo una parte del script, que solo contiene una ligera modificación al agregar secciones CDATA en lugar de un valor secundario):

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

Aquí también, DOMDocument se encarga de codificar correctamente la sección CDATA. Algo que probablemente no hiciste.

Los posibles problemas con los que aún podría encontrarse son con nombres de tablas o filas que son nombres XML no válidos . Pero entonces DOMDocument en realidad le dirá para que sepa mientras genera el XML, no solo después con un error de codificación.