溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

利用PHP怎么修復(fù)未正常關(guān)閉的HTML標簽

發(fā)布時間:2020-12-14 15:21:32 來源:億速云 閱讀:191 作者:Leah 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細講解有關(guān)利用PHP怎么修復(fù)未正常關(guān)閉的HTML標簽,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

具體方法如下:

<?php 
/** 
* fixHtmlTag 
* 
* HTML標簽修復(fù)函數(shù),此函數(shù)可以修復(fù)未正確閉合的 HTML 標簽 
* 
* 由于不確定性因素太多,暫時提供兩種模式“嵌套閉合模式”和 
* “就近閉合模式”,應(yīng)該夠用了。 
* 
* 這兩種模式是我為了解釋清楚此函數(shù)的實現(xiàn)而創(chuàng)造的兩個名詞, 
* 只需明白什么意思就行。 
* 1,嵌套閉合模式,NEST,為默認的閉合方式。即 "<body><div>你好" 
* 這樣的 html 代碼會被修改為 "<body><div>你好</div></body>" 
* 2,就近閉合模式,CLOSE,這種模式會將形如 "<p>你好<p>為什么沒有 
* 閉合呢" 的代碼修改為 "<p>你好</p><p>為什么沒有閉合呢</p>" 
* 
* 在嵌套閉合模式(默認,無需特殊傳參)下,可以傳入需要就近閉合的 
* 標簽名,通過這種方式將類似 "<body><p>你好</p><p>我也好" 轉(zhuǎn)換為 
* "<body><p>你好</p><p>我也好</p></body>"的形式。 
* 傳參時索引需要按照如下方式寫,不需要修改的設(shè)置可以省略 
* 
* $param = array( 
* 'html' => '', //必填 
* 'options' => array( 
* 'tagArray' => array(); 
* 'type' => 'NEST', 
* 'length' => null, 
* 'lowerTag' => TRUE, 
* 'XHtmlFix' => TRUE, 
* ) 
* ); 
* fixHtmlTag($param); 
* 
* 上面索引對應(yīng)的值含義如下 
* string $html 需要修改的 html 代碼 
* array $tagArray 當(dāng)為嵌套模式時,需要就近閉合的標簽數(shù)組 
* string $type 模式名,目前支持 NEST 和 CLOSE 兩種模式,如果設(shè)置為 CLOSE,將會忽略參數(shù) $tagArray 的設(shè)置,而全部就近閉合所有標簽 
* ini $length 如果希望截斷一定長度,可以在此賦值,此長度指的是字符串長度 
* bool $lowerTag 是否將代碼中的標簽全部轉(zhuǎn)換為小寫,默認為 TRUE 
* bool $XHtmlFix 是否處理不符合 XHTML 規(guī)范的標簽,即將 <br> 轉(zhuǎn)換為 <br /> 
* 
* @author IT不倒翁 <itbudaoweng@gmail.com> 
* @version 0.2 
* @link http://yungbo.com IT不倒翁 
* @link http://enenba.com/?post=19 某某 
* @param array $param 數(shù)組參數(shù),需要賦予特定的索引 
* @return string $result 經(jīng)過處理后的 html 代碼 
* @since 2012-04-14 
*/ 
function fixHtmlTag($param = array()) { 
//參數(shù)的默認值 
$html = ''; 
$tagArray = array(); 
$type = 'NEST'; 
$length = null; 
$lowerTag = TRUE; 
$XHtmlFix = TRUE; 
//首先獲取一維數(shù)組,即 $html 和 $options (如果提供了參數(shù)) 
extract($param); 
//如果存在 options,提取相關(guān)變量 
if (isset($options)) { 
extract($options); 
} 
$result = ''; //最終要返回的 html 代碼 
$tagStack = array(); //標簽棧,用 array_push() 和 array_pop() 模擬實現(xiàn) 
$contents = array(); //用來存放 html 標簽 
$len = 0; //字符串的初始長度 
//設(shè)置閉合標記 $isClosed,默認為 TRUE, 如果需要就近閉合,成功匹配開始標簽后其值為 false,成功閉合后為 true 
$isClosed = true; 
//將要處理的標簽全部轉(zhuǎn)為小寫 
$tagArray = array_map('strtolower', $tagArray); 
//“合法”的單閉合標簽 
$singleTagArray = array( 
'<meta', 
'<link', 
'<base', 
'<br', 
'<hr', 
'<input', 
'<img' 
); 
//校驗匹配模式 $type,默認為 NEST 模式 
$type = strtoupper($type); 
if (!in_array($type, array('NEST', 'CLOSE'))) { 
$type = 'NEST'; 
} 
//以一對 < 和 > 為分隔符,將原 html 標簽和標簽內(nèi)的字符串放到數(shù)組中 
$contents = preg_split("/(<[^>]+?>)/si", $html, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 
foreach ($contents as $tag) { 
if ('' == trim($tag)) { 
$result .= $tag; 
continue; 
} 
//匹配標準的單閉合標簽,如<br /> 
if (preg_match("/<(\w+)[^\/>]*?\/>/si", $tag)) { 
$result .= $tag; 
continue; 
} 
//匹配開始標簽,如果是單標簽則出棧 
else if (preg_match("/<(\w+)[^\/>]*?>/si", $tag, $match)) { 
//如果上一個標簽沒有閉合,并且上一個標簽屬于就近閉合類型 
//則閉合之,上一個標簽出棧 
//如果標簽未閉合 
if (false === $isClosed) { 
//就近閉合模式,直接就近閉合所有的標簽 
if ('CLOSE' == $type) { 
$result .= '</' . end($tagStack) . '>'; 
array_pop($tagStack); 
} 
//默認的嵌套模式,就近閉合參數(shù)提供的標簽 
else { 
if (in_array(end($tagStack), $tagArray)) { 
$result .= '</' . end($tagStack) . '>'; 
array_pop($tagStack); 
} 
} 
} 
//如果參數(shù) $lowerTag 為 TRUE 則將標簽名轉(zhuǎn)為小寫 
$matchLower = $lowerTag == TRUE ? strtolower($match[1]) : $match[1]; 
$tag = str_replace('<' . $match[1], '<' . $matchLower, $tag); 
//開始新的標簽組合 
$result .= $tag; 
array_push($tagStack, $matchLower); 
//如果屬于約定的的單標簽,則閉合之并出棧 
foreach ($singleTagArray as $singleTag) { 
if (stripos($tag, $singleTag) !== false) { 
if ($XHtmlFix == TRUE) { 
$tag = str_replace('>', ' />', $tag); 
} 
array_pop($tagStack); 
} 
} 
//就近閉合模式,狀態(tài)變?yōu)槲撮]合 
if ('CLOSE' == $type) { 
$isClosed = false; 
} 
//默認的嵌套模式,如果標簽位于提供的 $tagArray 里,狀態(tài)改為未閉合 
else { 
if (in_array($matchLower, $tagArray)) { 
$isClosed = false; 
} 
} 
unset($matchLower); 
} 
//匹配閉合標簽,如果合適則出棧 
else if (preg_match("/<\/(\w+)[^\/>]*?>/si", $tag, $match)) { 
//如果參數(shù) $lowerTag 為 TRUE 則將標簽名轉(zhuǎn)為小寫 
$matchLower = $lowerTag == TRUE ? strtolower($match[1]) : $match[1]; 
if (end($tagStack) == $matchLower) { 
$isClosed = true; //匹配完成,標簽閉合 
$tag = str_replace('</' . $match[1], '</' . $matchLower, $tag); 
$result .= $tag; 
array_pop($tagStack); 
} 
unset($matchLower); 
} 
//匹配注釋,直接連接 $result 
else if (preg_match("/<!--.*?-->/si", $tag)) { 
$result .= $tag; 
} 
//將字符串放入 $result ,順便做下截斷操作 
else { 
if (is_null($length) || $len + mb_strlen($tag) < $length) { 
$result .= $tag; 
$len += mb_strlen($tag); 
} else { 
$str = mb_substr($tag, 0, $length - $len + 1); 
$result .= $str; 
break; 
} 
} 
} 
//如果還有將棧內(nèi)的未閉合的標簽連接到 $result 
while (!empty($tagStack)) { 
$result .= '</' . array_pop($tagStack) . '>'; 
} 
return $result; 
}

關(guān)于利用PHP怎么修復(fù)未正常關(guān)閉的HTML標簽就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI