首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 自動生成文章摘要函數:智能截斷 HTML 內容並保證標籤閉合

     編輯:PHP 綜合知識

在 Blog、CMS 列表頁常需顯示文章前段內容,直接 substr 易導致 HTML 標籤未閉合破壞版面。本函數採用堆疊機制追蹤標籤開合,截斷處自動補全未閉合標籤,支援區塊級元素(div、p、table 等)與單一標籤(img、br、hr 等)識別。

核心版本(支援單位元組字串)

define("BRIEF_LENGTH", 800); // 摘要字元上限

function Generate_Brief($text) {
    global $Briefing_Length;
    if(strlen($text) <= BRIEF_LENGTH) return $text;

    $Foremost = substr($text, 0, BRIEF_LENGTH);
    $re = '/<(\/?)(P|DIV|H[1-6]|ADDRESS|PRE|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|OBJECT|A|UL|OL|LI|BASE|META|LINK|HR|BR|PARAM|IMG|AREA|SPAN)[^>]*(>?)/i';
    $Single = '/BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT/i';

    $Stack = array(); $posStack = array();
    preg_match_all($re, $Foremost, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);

    for($i=0; $i<count($matches); $i++) {
        if($matches[$i][1][0] == "") { // 開啟標籤
            $Elem = $matches[$i][2][0];
            if(preg_match($Single, $Elem) && $matches[$i][3][0] != "") continue;
            array_push($Stack, strtoupper($matches[$i][2][0]));
            array_push($posStack, $matches[$i][2][1]);
            if($matches[$i][3][0] == "") break;
        } else { // 關閉標籤
            $StackTop = $Stack[count($Stack)-1];
            $End = strtoupper($matches[$i][2][0]);
            if(strcasecmp($StackTop, $End) == 0) {
                array_pop($Stack); array_pop($posStack);
                if($matches[$i][3][0] == "") $Foremost .= ">";
            }
        }
    }

    $cutpos = array_shift($posStack) - 1;
    $Foremost = substr($Foremost, 0, $cutpos);
    return $Foremost;
}

多位元組版本(UTF-8 專用,支援中文)

function Generate_Brief($text) {
    global $Briefing_Length;
    mb_regex_encoding("UTF-8");
    if(mb_strlen($text) <= BRIEF_LENGTH) return $text;

    $Foremost = mb_substr($text, 0, BRIEF_LENGTH);
    $re = '<(\/?)(P|DIV|H[1-6]|ADDRESS|PRE|TABLE|TR|TD|TH|INPUT|SELECT|TEXTAREA|OBJECT|A|UL|OL|LI|BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT|SPAN)[^>]*(>?)';
    $Single = '/BASE|META|LINK|HR|BR|PARAM|IMG|AREA|INPUT|BR/i';

    $Stack = array(); $posStack = array();
    mb_ereg_search_init($Foremost, $re, 'i');

    while($pos = mb_ereg_search_pos()) {
        $match = mb_ereg_search_getregs();
        if($match[1] == "") {
            $Elem = $match[2];
            if(mb_eregi($Single, $Elem) && $match[3] != "") continue;
            array_push($Stack, mb_strtoupper($Elem));
            array_push($posStack, $pos[0]);
        } else {
            $StackTop = $Stack[count($Stack)-1];
            $End = mb_strtoupper($match[2]);
            if(strcasecmp($StackTop, $End) == 0) {
                array_pop($Stack); array_pop($posStack);
                if($match[3] == "") $Foremost .= ">";
            }
        }
    }

    $cutpos = array_shift($posStack) - 1;
    $Foremost = mb_substr($Foremost, 0, $cutpos, "UTF-8");
    return $Foremost;
}

使用建議

  • 效能考量:正則解析較耗資源,建議在「發布/儲存」時一次生成摘要存入資料庫獨立欄位,前端直接讀取,避免每次請求即時運算。
  • 安全性:摘要欄位僅供顯示,若遭竄改僅影響摘要與原文一致性,不涉及資料完整性,可接受風險。
  • 適用場景:文章列表、RSS 摘要、搜尋結果片段、Meta description 自動生成。
函數針對常見區塊標籤優化,若內容含罕見標籤(如 SVG、Canvas、Web Components),需擴充 $re 模式。生產環境建議搭配 HTML Purifier 先淨化內容再摘要。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved