Coding & Camembert
// April 18, 2017

How to close HTML tags in PHP

Share

Ever needed to close a bunch of open HTML tags from a string you are manipulating in PHP? I have!

Specifically in WordPress, I was using the_excerpt() function and needed to allow some tags in the excerpt, unfortunately I ended up having a bunch of un-closed tags that broke my layout. To solve this, I created a function that checks every character in the text for tags.

Once an open tag is found, it is added to an array. When the closing tag appears, I remove the associated tag from the array. The process continues until the loop goes through all of the text. Finally, if there are open tags still store in the array, I reverse the array and return the closing tags.

 

function closing_tags($str) {
    // Check the length of the string
    $strlen = strlen($str);
    // Initialize the variables
    $add_tag = false;
    $rm_tag = false;
    $add_tmp = '';
    $rm_tmp = '';
    $tag_arr[] = '';
    $closing_text = '';

    // Loop through all the characters using the string length
    for ($i = 0; $i <= $strlen; $i++) {
        // Get the character at the current pointer location
        $char = substr($str, $i, 1);

        // Check if it's a open tag <>
        if ($char === '<') {
            $add_tag = true;
            $add_tmp = '';
        }
        // Check if it's a closing tag </>
        else if ($char === '/') {
            $add_tag = false;
            $rm_tag = true;
        }
        // Check if end of the tag or a space in the tag (tag attributes are not needed)
        // If the end of an open tag, add it to the array
        // If the end of a closing tag, find the open tag in the array and remove it
        else if ($char === ' ' || $char === '>') {
            if ($add_tag) {
                $add_tag = false;
                $tag_arr[] = $add_tmp;
            }
            else if ($rm_tag) {
                $rm_tag = false;
                array_splice($tag_arr, array_search($rm_tmp, $tag_arr));
            }
        }
        // If tags haven't ended, keep appending the character to create the tag
        else if ($add_tag) {
            $add_tmp.= $char;
        }
        else if ($rm_tag) {
            $rm_tmp.= $char;
        }
    }

    // Count how many open tags there are
    $arr_size = count($tag_arr);

    // If there are open tags, reverse the array and output them
    // Otherwise, return the original string
    if ($arr_size > 0) {
        $reversed = array_reverse($tag_arr);
        for ($j = 0; $j < $arr_size; $j++) {
            $closing_text.= "</" . $reversed[$j] . ">";
        }

        return $str . "..." . $closing_text;
    }
    else {
        return $str . "...";
    }
}
Share