从数据库生成XML时出现PHP编码错误

时间:2013-03-03 04:30:14

标签: php mysql xml

我正在尝试使用简单的PHP服务为iPhone应用程序生成XML,从SQL数据库中获取。该数据库有各种文本源和字符,其中一些似乎抛弃了脚本并产生以下编码错误:

第6232行第1行的

错误:编码错误

php如下:

<?php
    //database configuration
    $config['mysql_host'] = "XXX.XXX.XXX.XXX";
    $config['mysql_user'] = "XXXX";
    $config['mysql_pass'] = "XXXX";
    $config['db_name']    = "XXXX";
    $config['table_name'] = "articles";

    //connect to host
    mysql_connect($config['mysql_host'],$config['mysql_user'],$config['mysql_pass']);
    //select database
    @mysql_select_db($config['db_name']) or die( "Unable to select database");

$xml          = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
$root_element = $config['table_name']."s"; 
$xml         .= "<$root_element>";

$sql = "SELECT * FROM ".$config['table_name'];

$result = mysql_query($sql);
if (!$result) {
    die('Invalid query: ' . mysql_error());
}

if(mysql_num_rows($result)>0)
{
    while($result_array = mysql_fetch_assoc($result))
    {
        $xml .= "<".$config['table_name'].">";

        //loop
        foreach($result_array as $key => $value)
        {

            $xml .= "<$key>";


            $xml .= "<![CDATA[$value]]>";

            //and close the element
            $xml .= "</$key>";
        }

        $xml.="</".$config['table_name'].">";
    }
}


$xml .= "</$root_element>";

//send xml
header ("Content-Type:text/xml");


echo $xml;
?>

有些文章导致整个页面失败,有些则没有。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

mysql_connect($config['mysql_host'],$config['mysql_user'],$config['mysql_pass']);
mysql_set_charset('utf8');
mysql_select_db($config['db_name']);

答案 1 :(得分:0)

您的问题非常广泛,我能给出的最佳答案是您应该使用一些现有的库来编码XML而不是编写自己的XML(因为您明显失败了,因此XML报告的XML编码错误consument)。

使用现有的库还可以让您更早地指出问题。例如。对于以下代码,请确保从数据库中获取的所有内容都是UTF-8编码的字符串。

同样使用更现代的数据库客户端类也将帮助您大大写下代码。以下是PDODOMDocument的示例:

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

请注意DomDocument正在注意正确编码从数据库返回的UTF-8字符串。这里(通常)不再需要<![CDATA[...]]>。你可以想象,你可能会在那里放置一些破坏了XML编码的东西。

同样对于数据库交互,大多数代码也不是必需的,你可以只迭代行,如果没有行,就不会有迭代。这通常最好用Iterator foreach语言构造来表达,该构造可以由现代数据库接口提供。从技术上讲,你可以在这里用许多其他东西替换$rows,比如一个接一个地遍历多个表的迭代器。

此外,使用异常错误模式可以使您无需在代码库中进行检查和die

示例性输出是:

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

如果你仍然需要创建CDATA元素,它的工作方式类似(我在这里只显示了脚本的一部分,只包含一些修改,添加CDATA部分而不是子值):

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

此处,DOMDocument负责正确编码CDATA部分。你可能没有做过的事情。

您可能遇到的潜在问题是表格或行名称为invalid XML names。但是DOMDocument实际上会在生成XML时告诉您,而不仅仅是在编码错误之后。

答案 2 :(得分:-1)

由于您已将XML格式描述为utf8,因此XML文件中的所有字符必须为utf8个字符。

您收到错误,因为有非UTF8字符。您必须将Character更改为UFT8格式,并且有两种方法可以检查UTF8字符

方式1

if (mb_check_encoding(file_get_contents($file), 'UTF-8')) {
    // yup, all UTF-8
}

这样可以确保所有字符都是UTF8兼容的,如果任何行不符合utf8,那么就省略了。

方式2

mysql_connect($config['mysql_host'],$config['mysql_user'],$config['mysql_pass']);
mysql_set_charset('utf8');
mysql_select_db($config['db_name']);

方式3

<xml>
 <![CDATA[

   ///Enter the Test here


 ]]>
</xml>