【问题标题】:PHP DOMDocument nodeValue dumps literal UTF-8 characters instead of encodedPHP DOMDocument nodeValue 转储文字 UTF-8 字符而不是编码
【发布时间】:2011-03-03 20:28:02
【问题描述】:

我遇到了类似于this question的问题:

nodeValue from DomDocument returning weird characters in PHP

我发现的根本原因可以用 mb_convert_encoding() 来模仿

在我的单元测试中,这终于发现了问题:

$test = mb_convert_encoding('é', "UTF-8");
$this->assertTrue(mb_check_encoding($test,'UTF-8'),'data is UTF-8');
$this->assertTrue($this->rw->checkEncoding($test,'UTF-8'),'data is UTF-8');
$this->assertIdentical($test,html_entity_decode('é',ENT_QUOTES,'UTF-8'),'values match');

UTF-8 数据的原始值似乎即将到来,并且运行 PHP 的系统的基本代码页很可能不是 UTF-8。

一直到解析(使用转储到 DOMDocument 的 HTML5lib 实现),字符串保持干净,UTF-8 友好。仅在使用

提取数据时
$span->nodeValue

我是否看到编码稳定性失败。

我的猜测是 domdocument 导出到 nodeValue 的 htmlentities 捕获使用了编码转换器,但忽略了内联编码值。

鉴于我的问题与 HTML5 有关,我认为这与实现的新颖性直接相关,但它似乎是一个更广泛的问题。除了开头提到的问题之外,我无法通过搜索找到有关 DOMDocument 特定问题的任何信息。

更新

以前进的名义,我已从 HTML5lib 和 DOMDocument 切换到 Simple HTML DOM,它导出干净的转义 html,然后我可以将其解析回正确的 UTF-8 实体。

另外,我没有尝试过的一个功能是

utf8_decode

因此,对于遇到此问题的其他人来说,这可能是一个解决方案。它解决了我在使用 AJAX/PHP 时遇到的一个相关问题,在 2009 年的这篇博文中找到了解决方案:Overcoming AJaX UTF-8 Encoding Limitation (in PHP)

【问题讨论】:

  • 欢迎来到 SO!一些额外的问题。你所说的“原始价值”是什么意思,你能举一些例子吗?包含é 的脚本文件是什么编码?你能显示正确的值和失败的值吗?您在页面上使用什么输出编码?
  • “原始值”是指最终呈现的值是此函数调用的结果html_entity_decode('é',ENT_QUOTES,'UTF-8') 所以,基本上在源 html 中有一个包含字符 é 的单词的 span,当我使用$span->nodeValue 提取该跨度的内容时,其中$span 是DOMDocument getElementsByTagName() 的结果。我正在尝试在任何地方使用 UTF-8,meta 设置为 UTF-8,根据这个 html:<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  • 因此,html 页面显示 é 并且 nodeValue 的结果是 é 的渲染等效值,据我所知,这相当于 @987654337 时发生的情况@ 在没有默认编码 UTF-8 的系统上运行

标签: php encoding utf-8 character-encoding domdocument


【解决方案1】:

刚刚在 nodeValue 上使用了 utf8_decode,它确实有点工作,有特殊字符无法正确显示的问题。

但是,某些字符仍然存在问题,例如简单的引号 ' 和其他一些字符(例如)

所以使用 $element->nodeValue 将不起作用,但 utf8_decode($element->nodeValue) 将 - 部分。

【讨论】:

  • 啊,是的,在这种情况下,我使用的是法语口音,所以这成了一个主要问题,所有“标准”字母实体都很好,但任何冒险进入 UTF-8 领域的东西都变成了转换不当。我想知道某处是否涉及服务器设置?
【解决方案2】:

函数utf8_decodeutf8_encode 的命名不是很好。它们分别从utf-8 转换为iso-8859-1 和从iso-8859-1 转换为utf-8

mb_convert_encoding 当只使用utf-8 作为参数调用时,通常类似于使用函数utf8_encode。 (通常除非您更改了内部代码页,但您可能 - 希望 - 没有)。

大部分 PHP 函数都希望字符串是 iso-8859-1 编码的。但是,libxml(这是 php 的 xml 解析库的底层库)期望字符串为 utf-8。因此,如果您不小心,您很容易以错误的编码告终。

至于您的测试,第一行可能具有欺骗性。由于您的脚本中有一个文字 é,因此测试会根据您保存文件的编码而改变。请检查您的文本编辑器。

希望能澄清一点。

【讨论】:

  • 当我最初处理这个问题时,我学到了很多关于这些函数的作用:) 我没有更改内部代码页(看到关于那个的警告。)另外值得注意的是,测试您在问题中看到的代码可能是第五个排列。我尝试了几种不同的方法来保存文件(确保 UTF-8、Windows 原生)并触发该字符(hex、ascii、html 实体),我发布的是最后一次尝试。让我想再次测试该代码!感谢您的想法。
猜你喜欢
  • 2012-03-24
  • 2012-07-03
  • 2016-04-04
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
相关资源
最近更新 更多