利用PHP 修復HTML 標籤閉合問題(檢查並補全)
這兩天在研究Typecho 文章內容部分展示問題(後續可能會運用到ArmxMod for Typecho 主題),由於在進行根據字數裁切時,PHP 並不會去判斷到底裁的位置有沒有問題,很有可能就把HTML 標籤裁了,還裁的不完全,就造成頁面在展示的時候,佈局混亂(目前這個問題在大家開發主題時做文章摘要比較容易出現),故在完成裁切後,應當對輸出進行修復,補齊標籤缺失的部分。
問題
比如正常的HTML 代碼如下:
<p>这两天在研究 Typecho 文章内容部分展示问题(后续可能会运用到<a href="https://vircloud.net/default/change-theme.html">ArmxMod for Typecho</a> 主题</p>
經過裁切後,輸出的HTML 如下:
<p>这两天在研究 Typecho 文章内容部分展示问题(后续可能会运用到<a href="https://vircloud.net/default/change-theme.html">
顯然裁切後的HTML 是不完整的,瀏覽器在顯示時輸出的頁面完全變樣了。
修復
function fixPost($post){
$post = preg_replace('/<[^>]*$/','',$post);
preg_match_all('#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $post, $result);
if($result){
$opentags = $result[1];
preg_match_all('#</([a-z]+)>#iU', $post, $result);
if($result){
$closetags = $result[1];
$len_opened = count($opentags);
if (count($closetags) == $len_opened) {
return $post; //没有未关闭标签
}
$opentags = array_reverse($opentags);
$sc = array('br','input','img','hr','meta','link'); //跳过这些标签
for ($i=0; $i < $len_opened; $i++) {
$ot = strtolower($opentags[$i]);
if (!in_array($opentags[$i], $closetags) && !in_array($ot,$sc)) {
$post .= '</'.$opentags[$i].'>'; //补齐标签
}
else {
unset($closetags[array_search($opentags[$i], $closetags)]);
}
}
}
}
return $post;
}
$post='<p>这两天在研究 Typecho 文章内容部分展示问题(后续可能会运用到<a href="https://vircloud.net/default/change-theme.html">';
echo fixPost($post);
結果
經過修復後,輸出為:
<p>这两天在研究 Typecho 文章内容部分展示问题(后续可能会运用到<a href="https://vircloud.net/default/change-theme.html"></a></p>
可以看到標籤已經都成功補全閉合了。
需要注意的是,文字缺失部分不會補齊,只會補齊標籤,而且如果本身標籤就是不完整的(無法判斷到底是不是標籤),那麼也會被忽略,比如如果裁切後輸出是:
<p>这两天在研究 Typecho 文章内容部分展示问题(后续可能会运用到<a href="