使用DOMDocument对HTML进行代码段处理会输出无效字符


Snipping HTML with DOMDocument outputs invalid characters

我在PHP中使用DOMDocument类来剪切几行文本。这里的文本是由所见即所得编辑器输入的一大块HTML。

我用来做的代码是这样的:

$body_string .= '<p class="summary">';
$domd = new DOMDocument();
$domd->encoding = 'utf-8';
libxml_use_internal_errors(true);
$domd->loadHTML(utf8_decode($post['content']));
libxml_use_internal_errors(false);
$domx = new DOMXPath($domd);
$items = $domx->query("//p[position() = 1] | //div[position() = 1]");
$body_string .= substr($items->item(0)->textContent, 0, 230);
$body_string .= '</p>

但是,当字符串包含省略号或大引号等特殊字符时,它们就会变成问号。

这样的文本:

我们知道,TED演讲有时会让人觉得有点…夸大其词。在那里是一大堆精彩的演讲;他们中的一些人哪儿也不去,似乎也不去给你的生活增加很多。更糟糕的是TED演讲,很难说出

变成这样:

我们知道,TED演讲有时会有点感觉?夸大其词。在那里是一大堆精彩的演讲;他们中的一些人哪儿也不去?似乎没有给你的生活增加很多。让事情变得更糟?有很多TED演讲?很难说

只有当我使用DOMDocument类时才会发生这种情况。没有它,字符就不会转换成问号。

我该怎么解决这个问题?HTML文档在<head> 中已有一个<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

似乎无法复制那个,而是尝试这个解决方法:

$body_string .= '<p class="summary">';
$domd = new DOMDocument('1.0', 'utf-8');
libxml_use_internal_errors(true);
$domd->loadHTML(mb_convert_encoding($post['content'], 'HTML-ENTITIES', 'UTF-8'));
libxml_clear_errors();
$domx = new DOMXPath($domd);
$items = $domx->query("//p[position() = 1] | //div[position() = 1]");
$body_string .= substr($items->item(0)->textContent, 0, 230);
$body_string .= '</p>

样本输出

最接近可复制的东西

设置DOMDocument::encoding仅适用于在将DOMDocument打印为字符串时更改编码,因此在此处没有任何效果。

类似地,在DOMDocument构造函数中设置"utf-8"也没有效果,因为它只在从头开始创建新文档时使用,而在解析现有文档时不使用。

HTML解析器需要知道发布内容的编码是什么,如下所示:

$domd = new DOMDocument();
libxml_use_internal_errors(true);
$domd->loadHTML('<meta charset="utf-8">' . $post['content']);
libxml_use_internal_errors(false);