/ Published in: PHP
suppose you have some html-formatted text of which you would like to show the first 45 characters. This function closes any tags that are not-closed because of cutting the first 45 characters.
Note that tags are also counted when defining the first 45 characters!
Expand |
Embed | Plain Text
<?php function closetags ( $html ) { #put all opened tags into an array $openedtags = $result[1]; #put all closed tags into an array $closedtags = $result[1]; # all tags are closed { return $html; } # close tags for( $i = 0; $i < $len_opened; $i++ ) { { $html .= "</" . $openedtags[$i] . ">"; } else { } } return $html; } $str = "<div>This is some interesting <strong><em>content!</em> And this</strong> line is <em>"; $str .= "abundantly</em> formatted</div>"; $x = closetags ( $snippet ); ?>
Comments
Subscribe to comments
You need to login to post a comment.

This is a v handy script tho one issue is that it closes and , I've str_replace modded it but and works v well
spot the missing words: br tags and img tags
yeah, it doesn't take into account any self-closing tag (like , and )
ah, i meant like br, img and hr
Here's a fix for the "H" tags.
put all opened tags into an array
pregmatchall('##iU', $html, $result);
put all closed tags into an array
pregmatchall('##iU', $html, $result);
Fantastic bit of work. Was half way through my own project when I found this gem and its perfect.
To fix the BR, HR, IMG issue you can just use this extra line after the array_reverse
That will remove those tags from the close creation.
Correction. Add these lines
$openedtags = arraydiff($openedtags, array("img", "hr", "br")); $openedtags = arrayvalues($openedtags);
After
$openedtags = $result[1];
That will resort your array. The first way I mentioned will leave you with empty closing tags.
I found another shortcoming on this script - if you truncated the html before sending it to this function, there's a decent chance you'll end up with a half-tag at the end, like:
<span
at the end instead of : <span>
To make this function account for that, put the following lines at the very beginning:
This goes before: pregmatchall ( "##iU", $html, $result );
This new code strips out the broken tag completely - there would be no intelligent way to restore it, as we wouldn't know what important info was lost with the truncation.
Great function, though! It was just what I needed for a project I'm working on currently.
great, thanks! :)
Here's an amendment to the regular expression to make the thing work really smoothly:
function closetags($html) { pregmatchall('##iU', $html, $result); $closedtags = $result[1]; $lenopened = count($openedtags); if (count($closedtags) == $lenopened) { return $html; } $openedtags = arrayreverse($openedtags); for ($i=0; $i < $lenopened; $i++) { if (!inarray($openedtags[$i], $closedtags)) { $html .= ''; } else { unset($closedtags[arraysearch($openedtags[$i], $closedtags)]); } } return $html; }
You can see that the single tags (img, br, meta...) are excluded from the expression. You could add more by putting them in (separated by a vertical slash).
I've tested this version and it works like a charm. :)
Whoops, here it is again; hopefully the blog will display it more like it should be:
Okay, I'm going to try this again.
Here's the code:
(Don't use either of my previous posts, the blog stripped out some essential characters.)
Sorry, gang, I don't know how to include this code on this blog without it getting hammered.
Let's try this:
Gulp. I'm having massive trouble with this blog format.
See: http://codesnippets.joyent.com/posts/show/959
Thanks Pitje, I was looking at many codes but this one was the closest to the same thing I had in mind. I noticed a few things thought, for e.g. if you open an "a" tag and you close a "b" tag the number of opened/closed tags will be equal and you end up without closing the "a" tag.
Also if you close a tag before opening it it will be also skipped as it thinks it's already closed. I have modified your function a bit and included in my CMS (jCore to close the tags when posting comments, the modified version is:
As you can see I dropped the whole length check and if there are any open tags it will start checking for the closed ones and fix if needed. I did some testings and works just fine, I don't care about half tags as I won't crop the messages and it may be better/faster way to do it but as it gets only executed when comment added to the db it's ok for me.
Thanks again and if you can't see the above code it will be in jCore (0.6) source at: lib/sources/security.class.php line 575: static function closeTags($html)