我在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);