【问题标题】:Another PHP XML parsing error: "Input is not proper UTF-8, indicate encoding!"另一个 PHP XML 解析错误:“输入不是正确的 UTF-8,表示编码!”
【发布时间】:2011-06-07 09:57:29
【问题描述】:

错误:

警告:simplexml_load_string() [function.simplexml-load-string]: 实体:第 3 行:解析器错误:输入 不是正确的UTF-8,表示编码 !字节数:0xE7 0x61 0x69 0x73

来自数据库的 XML(从 FF 中的视图源输出):

<?xml version="1.0" encoding="UTF-8" ?><audit><audit_detail>
    <fieldname>role_fra</fieldname>
    <old_value>Role en fran&#xe7;ais</old_value>
    <new_value>Role &#xe7; en fran&#xe7;ais</new_value>
</audit_detail></audit></xml>

如果我理解正确,该错误与 old_value 标记中编码的第一个 ç 有关。准确地说,错误与此有关,基于字节:“çais”?

这是我加载 XML 的方式:

$xmlData = simplexml_load_string($ed['updates'][$i]['audit_data']);

我循环使用这个:

foreach ($xmlData->audit_detail as $a){
//code here
}

数据库中的字段为文本数据类型,设置为utf8_general_ci。

我创建 audit_detail 存根的函数:

function ed_audit_node($field, $new, $old){


    $old = htmlentities($old, ENT_QUOTES, "UTF-8");
    $new = htmlentities($new, ENT_QUOTES, "UTF-8");

    $out = <<<EOF
        <audit_detail>
            <fieldname>{$field}</fieldname>
            <old_value>{$old}</old_value>
            <new_value>{$new}</new_value>
        </audit_detail>
EOF;
    return $out;
}

在数据库中的插入是这样完成的:

function ed_audit_insert($ed, $xml){
    global $visitor;

    $sql = <<<EOF
    INSERT INTO ed.audit
    (employee_id, audit_date, audit_action, audit_data, user_id) 
    VALUES (
        {$ed[emp][employee_id]}, 
        now(), 
        '{$ed[audit_action]}', 
        '{$xml}', 
        {$visitor[user_id]}
    );      
EOF;
    $req = mysql_query($sql,$ed['db']) or die(db_query_error($sql,mysql_error(),__FUNCTION__));

}

最奇怪的部分是以下工作(虽然没有 xml 声明)在一个简单的 PHP 文件中:

$testxml = <<<EOF
<audit><audit_detail>
        <fieldname>role_fra</fieldname>
        <old_value>Role en fran&#xe7;ais</old_value>
        <new_value>Role &#xe7; en fran&#xe7;ais</new_value>
    </audit_detail></audit>
EOF;

$xmlData = simplexml_load_string($testxml);

有人可以帮忙解释一下吗?

Edit #1 - 我现在使用 DOM 来构建 XML 文档并且已经摆脱了错误。这里的功能:

$dom = new DomDocument();
$root = $dom->appendChild($dom->createElement('audit'));
$xmlCount = 0;

if($role_fra != $curr['role']['role_fra']){
   $root->appendChild(ed_audit_node($dom, 'role_fra', $role_fra, $curr['role']['role_fra'])); 
   $xmlCount++;
}

...

function ed_audit_node($dom, $field, $new, $old){

    //create audit_detail node
    $ad = $dom->createElement('audit_detail');

    $fn = $dom->createElement('fieldname');
    $fn->appendChild($dom->createTextNode($field));
    $ad->appendChild($fn);

    $ov = $dom->createElement('old_value');
    $ov->appendChild($dom->createTextNode($old));
    $ad->appendChild($ov);

    $nv = $dom->createElement('new_value');
    $nv->appendChild($dom->createTextNode($new));
    $ad->appendChild($nv);

    //append to document
    return $ad;
}

if($xmlCount != 0){
    ed_audit_insert($ed,$dom->saveXML());   
}

但是,我认为我现在遇到了显示问题,因为此文本“Roééleç sé en franêais”(new_value)显示为:

显示问题:

在我的 HTML 文档中,我有以下内容类型声明(不幸的是,我没有在此处进行更改):

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
...
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

我已经尝试将 iconv() 转换为 ISO-8859-1,但是,在进行转换时,大多数特殊字符都被删除了。剩下的就是使用这个命令“Ro”:

iconv('UTF-8','ISO-8859-1',$node->new_value);

iconv 输出:

db 中的字段是:utf8_general_ci。但是,连接字符集将是默认值。

不太清楚从这里去哪里......

编辑 #2 - 我尝试了 utf8_decode 看看是否没有帮助,但没有。

utf8_decode($a->new_value);

输出:

我还注意到我在数据库中的字段确实包含 UTF-8。哪个好。

【问题讨论】:

  • 您存储xml的数据库中的列编码是什么?

标签: php xml parsing simplexml


【解决方案1】:

&amp;#xe7; 是“ç”时,您的编码是 Windows-1252(或者可能是 ISO-8859-1),而不是 UTF-8。

【讨论】:

  • 卫生署!我确实在 ISO-8859-1 字符表上翻译了这些值……叹息。那么这意味着我没有从数据库中返回 UTF-8。无需进入配置文件的最佳方法是什么?我读到了关于集合名称“utf-8”的信息。但是,只要我有它,我的 select 语句就会失败...
  • @Tekius:您目前正在使用字符串连接(一个 PHP heredoc)来构建您的 XML。不要那样做。使用 DOM 构建您的 XML。可能需要多几行代码,但不会遇到字符编码问题。
  • 感谢您的建议,这似乎已经摆脱了错误。但是,请参阅我的编辑,因为我现在遇到了这些特殊字符的显示问题。我已经尝试了一些事情,但问题仍然没有解决。谢谢!
  • @Tekius:恐怕MySQL和PHP之间的字符编码问题不是我的专业领域。也许您可以提出一个新问题来更详细地描述该问题并将其简化为原始形式,以便新问题得到一些关注。我可能会首先检查数据库实际存储的内容(选择单个字符的字符代码)以及这是否是正确的 UTF-8。然后检查 PHP 接收到的内容(再次输入字符代码)。然后检查这是否与 Content-Type 标头一致。然后浏览器收到什么(通过 FireBug 或 WireShark)。
猜你喜欢
  • 2011-01-31
  • 2013-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
相关资源
最近更新 更多