// April 18, 2017
How to close HTML tags in PHP
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 . "...";
}
}