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

PHP 截取含 HTML 標簽字符串函數:自動閉合標簽、支援錨點截斷、多字節安全

     編輯:PHP 相關知識

函數功能

  • 安全截取含 HTML 的字串,避免標簽未閉合破壞佈局。
  • 自動補全未閉合標簽(按逆序補全)。
  • 支援指定長度(中英各算 1 字符)、超出部分替換字串(如 ...)。
  • 支援錨點標記 <!-- break --> 優先截斷。
  • 正確處理 UTF-8 多字節字符(中文 3 字節)。

完整函數代碼

function cut_html_str($str, $lenth, $replace='', $anchor='') {
    $_lenth = mb_strlen($str, "utf-8");
    if ($_lenth <= $lenth) return $str;
    $strlen_var = strlen($str);
    if (strpos($str, '<') === false) return mb_substr($str, 0, $lenth);
    if ($e = strpos($str, $anchor)) return mb_substr($str, 0, $e);

    $html_tag = 0;
    $result = '';
    $html_array = array('left'=>array(), 'right'=>array());
    for ($i = 0; $i < $strlen_var; ++$i) {
        if (!$lenth) break;
        $current_var = substr($str, $i, 1);
        if ($current_var == '<') {
            $html_tag = 1;
            $html_array_str = '';
        } elseif ($html_tag == 1) {
            if ($current_var == '>') {
                $html_array_str = trim($html_array_str);
                if (substr($html_array_str, -1) != '/') {
                    $f = substr($html_array_str, 0, 1);
                    if ($f == '/') {
                        $html_array['right'][] = str_replace('/', '', $html_array_str);
                    } elseif ($f != '?') {
                        if (strpos($html_array_str, ' ') !== false) {
                            $html_array['left'][] = strtolower(current(explode(' ', $html_array_str, 2)));
                        } else {
                            $html_array['left'][] = strtolower($html_array_str);
                        }
                    }
                }
                $html_array_str = '';
                $html_tag = 0;
            } else {
                $html_array_str .= $current_var;
            }
        } else {
            --$lenth;
            $ord_var_c = ord($str{$i});
            switch (true) {
                case (($ord_var_c & 0xE0) == 0xC0): $result .= substr($str, $i, 2); $i += 1; break;
                case (($ord_var_c & 0xF0) == 0xE0): $result .= substr($str, $i, 3); $i += 2; break;
                case (($ord_var_c & 0xF8) == 0xF0): $result .= substr($str, $i, 4); $i += 3; break;
                case (($ord_var_c & 0xFC) == 0xF8): $result .= substr($str, $i, 5); $i += 4; break;
                case (($ord_var_c & 0xFE) == 0xFC): $result .= substr($str, $i, 6); $i += 5; break;
                default: $result .= $current_var;
            }
        }
    }
    if ($html_array['left']) {
        $html_array['left'] = array_reverse($html_array['left']);
        foreach ($html_array['left'] as $index => $tag) {
            $key = array_search($tag, $html_array['right']);
            if ($key !== false) unset($html_array['right'][$key]);
            else $result .= '';
        }
    }
    return $result.$replace;
}

使用示例

$html = '

標題內容很長...

'; echo cut_html_str($html, 10, '...'); // 輸出:

標題內...

(自動補全

) $html_with_break = '摘要內容詳細內容'; echo cut_html_str($html_with_break, 100, '...'); // 輸出: 摘要內容 (遇到錨點優先截斷)

核心邏輯解析

  1. 雙計數器:mb_strlen 計視覺長度,strlen 遍歷字節。
  2. 狀態機識別標簽:進入 < 後收集至 >,分類記錄左標簽(需閉合)與右標簽(已閉合)。
  3. 屬性過濾:

    只記錄 h2。

  4. 逆序補全:array_reverse 確保內層標簽先閉合(符合 HTML 嵌套規範)。
  5. 多字節安全:ord 判斷 UTF-8 首字節標記位,一次複製 2-6 字節,避免截斷多字節字符。

局限與改進

  • 不支援 `
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved