/**
- * Fixhtmltag
- *
- * HTML tag repair function, this function can fix HTML tags that are not properly closed
- *
- * Due to too many uncertainties, there are two modes of "nested closed mode" and
- * "Close-up mode" should suffice.
- *
- * These two patterns are the two nouns I created to explain the implementation of this function,
- * Just know what you mean.
- * 1, nested closed mode, NEST, as the default closed way. That's "Hello."
- * Such HTML code will be modified to "hello"
- * 2, close in close mode, this mode will be shaped like "
How are you doing Why not
- * Closed "code modified to"
How are you doing Why isn't it closed? "
- *
- * in nested closed mode (default, no special parameters required), you can pass in the nearest closed
- * Tag name, in this way will be similar to "
How are you doing I'm good, too. "Convert to
- * "
How are you doing I'm fine. "In the form.
- * The index needs to be written as follows, and settings that do not need to be modified can be omitted
- *
- * $param = Array (
- * ' html ' + = ',//required
- * options ' = = Array (
- * ' tagarray ' = = Array ();
- * ' type ' = ' NEST ',
- * ' length ' = null,
- * ' lowertag ' = TRUE,
- * ' xhtmlfix ' = TRUE,
- * )
- * );
- * Fixhtmltag ($param);
- *
- * The above index corresponds to the following value meaning
- * String $html The HTML code to be modified
- * Array $tagArray when nested mode is required, the nearest closed tag
- * String $type mode name, currently supports NEST and close two modes, if set to close, the parameter $tagArray settings will be ignored, and all the labels close to the nearest
- * INI $length If you want to truncate a certain length, you can assign a value here, which refers to the length of the string
- * BOOL $lowerTag whether to convert all tags in code to lowercase, by default true
- * BOOL $XHtmlFix whether to process labels that do not conform to the XHTML specification and will
Converted to
- *
- * @author It Tumbler
- * @version 0.2
- * @link http://bbs.it-home.org It Tumbler
- * @link http://enenba.com/?post=19 XXX
- * @param arrays $param array parameters, you need to assign a specific index
- * @return string $result the processed HTML code
- * @since 2012-04-14
- */
- function Fixhtmltag ($param = Array ()) {
- Default values for parameters
- $html = ";
- $tagArray = Array ();
- $type = ' NEST ';
- $length = null;
- $lowerTag = TRUE;
- $XHtmlFix = TRUE;
First, get a one-dimensional array, $html and $options (if parameters are provided)
- Extract ($param);
If there is an options, extract the relevant variables
- if (Isset ($options)) {
- Extract ($options);
- }
$result = "; The final HTML code to return
- $tagStack = Array (); Tag stacks, implemented with Array_push () and Array_pop () simulations
- $contents = Array (); Used to store HTML tags
- $len = 0; The initial length of the string
Sets the closing tag $isClosed, which is true by default, if Close is required, the value is false after the start tag is successfully matched and true after successful closing
- $isClosed = true;
All labels to be processed are converted to lowercase
- $tagArray = Array_map (' Strtolower ', $tagArray);
"Legal" single-closed label
- $singleTagArray = Array (
- '
- '
- '
- '
- '
- '
- ');
Verify matching mode $type, default to NEST mode
- $type = Strtoupper ($type);
- if (!in_array ($type, Array (' NEST ', ' CLOSE '))) {
- $type = ' NEST ';
- }
Place the strings in the original HTML tags and tags in an array with a pair of < and > delimiters
- $contents = Preg_split ("/(<[^>]+?>)/si", $html,-1, Preg_split_no_empty | Preg_split_delim_capture);
foreach ($contents as $tag) {
- if (' = = Trim ($tag)) {
- $result. = $tag;
- Continue
- }
A single closed label that matches a standard, such as
- if (Preg_match ("/< (\w+) [^\/>]*?\/>/si", $tag)) {
- $result. = $tag;
- Continue
- }
Match the start tag, if it's a single label, out of the stack
- else if (Preg_match ("/< (\w+) [^\/>]*?>/si", $tag, $match)) {
- If the previous label is not closed and the previous label belongs to the nearest closed type
- Then closed, the last label out of the stack
If the label is not closed
- if (false = = = $isClosed) {
- Close Close mode, closing all labels directly to the nearest
- if (' CLOSE ' = = $type) {
- $result. = ' ;
- Array_pop ($tagStack);
- }
- Default nesting mode, the label provided by the nearest closing parameter
- else {
- if (In_array (End ($tagStack), $tagArray)) {
- $result. = ' ;
- Array_pop ($tagStack);
- }
- }
- }
If the argument $lowerTag true, the label name is converted to lowercase
- $matchLower = $lowerTag = = TRUE? Strtolower ($match [1]): $match [1];
$tag = Str_replace (' < '. $match [1], ' < '. $matchLower, $tag);
- Start a new label combination
- $result. = $tag;
- Array_push ($tagStack, $matchLower);
If a single label is a contract, it is closed and the stack is
- foreach ($singleTagArray as $singleTag) {
- if (Stripos ($tag, $singleTag)!== false) {
- if ($XHtmlFix = = TRUE) {
- $tag = Str_replace (' > ', '/> ', $tag);
- }
- Array_pop ($tagStack);
- }
- }
Close mode, state becomes unclosed
- if (' CLOSE ' = = $type) {
- $isClosed = false;
- }
- Default nesting mode, if the label is in the provided $tagArray, the state changes to unclosed
- else {
- if (In_array ($matchLower, $tagArray)) {
- $isClosed = false;
- }
- }
- Unset ($matchLower);
- }
Match the closing tag, if appropriate, out of the stack
- else if (Preg_match ("/<\/(\w+) [^\/>]*?>/si", $tag, $match)) {
If the argument $lowerTag true, the label name is converted to lowercase
- $matchLower = $lowerTag = = TRUE? Strtolower ($match [1]): $match [1];
if (end ($tagStack) = = $matchLower) {
- $isClosed = true; Match complete, label closed
- $tag = Str_replace (' $result. = $tag;
- Array_pop ($tagStack);
- }
- Unset ($matchLower);
- }
Match comments, connect directly $result
- else if (Preg_match ("/ /si", $tag)) {
- $result. = $tag;
- }
Put a string into the $result, by the way the truncation operation
- 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
- }
- }
- }
If you also have an unclosed label in the stack connected to the $result
- while (!empty ($tagStack)) {
- $result. = ' ;
- }
- return $result;
- }
- ?>
Copy Code |