PHP自动修复内容里未闭合的HTML标签

远昔 代码记录 2025-09-28 295 0

今天在文章管理过程中,突然发现部分文章遇到HTML标签不完整或丢失的情况,这可能导致页面显示异常。为此,我写了一个简单高效的PHP函数,能够自动检测并修复未闭合的HTML标签。

上代码:

function fixHtmlTags($html) {
    if (empty(trim($html))) return $html;
    
    $stack = [];
    $selfClosingTags = ['img', 'br', 'hr', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed'];
    
    // 修复标签内部属性未闭合的情况(如 <p class="a>)
    $html = preg_replace_callback('/<([a-z][a-z0-9]*)([^>]*)$/i', function($matches) use ($selfClosingTags) {
        $tagName = strtolower($matches[1]);
        $attributes = $matches[2];
        
        // 检查属性中是否有未闭合的引号
        if (preg_match('/=("[^"]*$|\'[^\']*$)/', $attributes)) {
            // 修复未闭合的属性值
            $attributes = rtrim($attributes) . '"';
        }
        
        // 对于自闭合标签使用 />,其他使用 >
        if (in_array($tagName, $selfClosingTags)) {
            return "<$tagName$attributes />";
        } else {
            return "<$tagName$attributes>";
        }
    }, $html);
    
    // 修复未写完的标签(如 <p class="a)
    if (preg_match('/<([a-z][a-z0-9]*)(?:\s+[^>]*)?$/i', $html, $matches)) {
        $tagName = strtolower($matches[1]);
        $html .= in_array($tagName, $selfClosingTags) ? ' />' : '>';
    }
    
    // 匹配所有HTML标签
    preg_match_all('/<(\/?)([a-z][a-z0-9]*)(?:[^>]*)?>/i', $html, $matches, PREG_SET_ORDER);
    
    foreach ($matches as $match) {
        $isClosing = ($match[1] === '/');
        $tagName = strtolower($match[2]);
        
        if (in_array($tagName, $selfClosingTags)) continue;
        
        if ($isClosing) {
            if (!empty($stack) && end($stack) === $tagName) {
                array_pop($stack);
            }
        } else {
            $stack[] = $tagName;
        }
    }
    
    // 为栈中剩余的未闭合标签添加闭合标签
    $result = $html;
    while (!empty($stack)) {
        $tag = array_pop($stack);
        $result .= "</$tag>";
    }
    
    return $result;
}

评论

发表评论:

挤眼 亲亲 咆哮 开心 想想 可怜 糗大了 委屈 哈哈 小声点 右哼哼 左哼哼 疑问 坏笑 赚钱啦 悲伤 耍酷 勾引 厉害 握手 耶 嘻嘻 害羞 鼓掌 馋嘴 抓狂 抱抱 围观 威武 给力
提交评论

清空信息
关闭评论