如何防止 DOMDocument 转换为 unicode

How to prevent DOMDocument from converting   to unicode

我正在尝试获取 PHP 中 DOMElement 的内部 HTML。标记示例:

<div>...</div>
<div id="target"><p>Here's some &nbsp; <em>funny</em> &nbsp; text</p></div>
<div>...</div>
<div>...</div>

将上面的字符串输入变量$html,我正在做:

$doc = new DOMDocument();
@$doc->loadHTML("<html><body>$html</body></html>");
$node = $doc->getElementById('target')
$markup = '';
foreach ($node->childNodes as $child) {
  $markup .= $child->ownerDocument->saveXML($child);
}

生成的 $markup 字符串如下所示(转换为 JSON 以显示不可见字符):

"<p>Here's some \u00a0 <em>funny<\/em> \u00a0 text<\/p>"

所有 &nbsp; 个字符都已转换为 Unicode 不间断空格,这破坏了我的应用程序。

在我的理想世界中,有一种方法可以在目标 div 中按原样 检索 HTML 的原始字符串,而无需 DomDocument 对它做任何事情。这似乎是不可能的,所以下一个最好的办法就是以某种方式关闭这个字符转换。到目前为止我已经尝试过:

最后我求助于这个 hack,它有效但感觉不是正确的解决方案。

$markup = str_replace("\xc2\xa0", '&nbsp;', $markup);

肯定有更好的方法吗?

您可以使用 mb_convert_encoding() 将 Unicode 字符转换为它们的实体,而无需触及括号等:

<?php
$html = '
<div>...</div>
<div id="target"><p>Here\'s some &nbsp; <em>funny</em> &nbsp; text</p></div>
<div>...</div>
<div>...</div>
';

$doc = new DOMDocument();
libxml_use_internal_errors();
$doc->loadHTML("<html><body>$html</body></html>");
$node = $doc->getElementById('target');
$markup = '';
foreach ($node->childNodes as $child) {
  $markup .= $child->ownerDocument->saveHTML($child);
}

$markup = mb_convert_encoding($markup, 'HTML-ENTITIES', 'UTF-8');
echo $markup;

输出:

<p>Here's some &nbsp; <em>funny</em> &nbsp; text</p>

这个问题我也运行了,基本上已经described here了。

提供的解决方案对我有用,但只有&nbsp;字符失败,所以我来了。 miken32 提供的解决方案对我不起作用,至少在保存时无效,但在加载 html 时无效。解决方案是:

$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));

链接的 Whosebug 问题中也描述了此解决方案,this blog post 帮助我解决了问题。