利用 PHP 修复 HTML 标签闭合问题|检查并补全|

cera cera

这两天在研究 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="

 

cera cloudiplc tengxunyun

相关推荐