假设我有一个包含HTML标记的200个字符的字符串。我想显示前50个字符的预览,但不“分裂”标记。换句话说,该片段不应该包含没有</b>
的<b>
。任何服务器端处理都应该在PHP中完成。
以下是使用标准PHP中的DOMDocument快速可靠的解决方案:
function cut_html ($html, $limit) {
$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding("<div>{$html}</div>", "HTML-ENTITIES", "UTF-8"), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
cut_html_recursive($dom->documentElement, $limit);
return substr($dom->saveHTML($dom->documentElement), 5, -6);
}
function cut_html_recursive ($element, $limit) {
if($limit > 0) {
if($element->nodeType == 3) {
$limit -= strlen($element->nodeValue);
if($limit < 0) {
$element->nodeValue = substr($element->nodeValue, 0, strlen($element->nodeValue) + $limit);
}
}
else {
for($i = 0; $i < $element->childNodes->length; $i++) {
if($limit > 0) {
$limit = cut_html_recursive($element->childNodes->item($i), $limit);
}
else {
$element->removeChild($element->childNodes->item($i));
$i--;
}
}
}
}
return $limit;
}
strip_tags()
函数去除标签,然后再截取摘要。DOMDocument::loadHTML($string)
将其转换为DOM,然后遍历树并计算文本节点中的字符数。当达到限制时,用“...”或空字符串替换该节点的其余部分,并在所有后续节点上简单调用$node->parentNode->removeChild($node)
。