...)。<!-- break --> 優先截斷。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 .= ''.$tag.'>';
}
}
return $result.$replace;
}
$html = '標題內容很長...
'; echo cut_html_str($html, 10, '...'); // 輸出:標題內...
(自動補全 ) $html_with_break = '摘要內容詳細內容'; echo cut_html_str($html_with_break, 100, '...'); // 輸出: 摘要內容 (遇到錨點優先截斷)
mb_strlen 計視覺長度,strlen 遍歷字節。< 後收集至 >,分類記錄左標簽(需閉合)與右標簽(已閉合)。 只記錄 h2。array_reverse 確保內層標簽先閉合(符合 HTML 嵌套規範)。ord 判斷 UTF-8 首字節標記位,一次複製 2-6 字節,避免截斷多字節字符。