您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關利用PHP怎么修復未正常關閉的HTML標簽,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
具體方法如下:
<?php /** * fixHtmlTag * * HTML標簽修復函數,此函數可以修復未正確閉合的 HTML 標簽 * * 由于不確定性因素太多,暫時提供兩種模式“嵌套閉合模式”和 * “就近閉合模式”,應該夠用了。 * * 這兩種模式是我為了解釋清楚此函數的實現而創造的兩個名詞, * 只需明白什么意思就行。 * 1,嵌套閉合模式,NEST,為默認的閉合方式。即 "<body><div>你好" * 這樣的 html 代碼會被修改為 "<body><div>你好</div></body>" * 2,就近閉合模式,CLOSE,這種模式會將形如 "<p>你好<p>為什么沒有 * 閉合呢" 的代碼修改為 "<p>你好</p><p>為什么沒有閉合呢</p>" * * 在嵌套閉合模式(默認,無需特殊傳參)下,可以傳入需要就近閉合的 * 標簽名,通過這種方式將類似 "<body><p>你好</p><p>我也好" 轉換為 * "<body><p>你好</p><p>我也好</p></body>"的形式。 * 傳參時索引需要按照如下方式寫,不需要修改的設置可以省略 * * $param = array( * 'html' => '', //必填 * 'options' => array( * 'tagArray' => array(); * 'type' => 'NEST', * 'length' => null, * 'lowerTag' => TRUE, * 'XHtmlFix' => TRUE, * ) * ); * fixHtmlTag($param); * * 上面索引對應的值含義如下 * string $html 需要修改的 html 代碼 * array $tagArray 當為嵌套模式時,需要就近閉合的標簽數組 * string $type 模式名,目前支持 NEST 和 CLOSE 兩種模式,如果設置為 CLOSE,將會忽略參數 $tagArray 的設置,而全部就近閉合所有標簽 * ini $length 如果希望截斷一定長度,可以在此賦值,此長度指的是字符串長度 * bool $lowerTag 是否將代碼中的標簽全部轉換為小寫,默認為 TRUE * bool $XHtmlFix 是否處理不符合 XHTML 規范的標簽,即將 <br> 轉換為 <br /> * * @author IT不倒翁 <itbudaoweng@gmail.com> * @version 0.2 * @link http://yungbo.com IT不倒翁 * @link http://enenba.com/?post=19 某某 * @param array $param 數組參數,需要賦予特定的索引 * @return string $result 經過處理后的 html 代碼 * @since 2012-04-14 */ function fixHtmlTag($param = array()) { //參數的默認值 $html = ''; $tagArray = array(); $type = 'NEST'; $length = null; $lowerTag = TRUE; $XHtmlFix = TRUE; //首先獲取一維數組,即 $html 和 $options (如果提供了參數) extract($param); //如果存在 options,提取相關變量 if (isset($options)) { extract($options); } $result = ''; //最終要返回的 html 代碼 $tagStack = array(); //標簽棧,用 array_push() 和 array_pop() 模擬實現 $contents = array(); //用來存放 html 標簽 $len = 0; //字符串的初始長度 //設置閉合標記 $isClosed,默認為 TRUE, 如果需要就近閉合,成功匹配開始標簽后其值為 false,成功閉合后為 true $isClosed = true; //將要處理的標簽全部轉為小寫 $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 標簽和標簽內的字符串放到數組中 $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); } //默認的嵌套模式,就近閉合參數提供的標簽 else { if (in_array(end($tagStack), $tagArray)) { $result .= '</' . end($tagStack) . '>'; array_pop($tagStack); } } } //如果參數 $lowerTag 為 TRUE 則將標簽名轉為小寫 $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); } } //就近閉合模式,狀態變為未閉合 if ('CLOSE' == $type) { $isClosed = false; } //默認的嵌套模式,如果標簽位于提供的 $tagArray 里,狀態改為未閉合 else { if (in_array($matchLower, $tagArray)) { $isClosed = false; } } unset($matchLower); } //匹配閉合標簽,如果合適則出棧 else if (preg_match("/<\/(\w+)[^\/>]*?>/si", $tag, $match)) { //如果參數 $lowerTag 為 TRUE 則將標簽名轉為小寫 $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; } } } //如果還有將棧內的未閉合的標簽連接到 $result while (!empty($tagStack)) { $result .= '</' . array_pop($tagStack) . '>'; } return $result; }
關于利用PHP怎么修復未正常關閉的HTML標簽就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。