3v4l.org

run code in 300+ PHP versions simultaneously
<?php function printTruncated($maxLength, $html, $isUtf8=true) { $printedLength = 0; $position = 0; $tags = array(); // For UTF-8, we need to count multibyte sequences as one character. $re = $isUtf8 ? '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;|[\x80-\xFF][\x80-\xBF]*}' : '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}'; while ($printedLength < $maxLength && preg_match($re, $html, $match, PREG_OFFSET_CAPTURE, $position)) { list($tag, $tagPosition) = $match[0]; // Print text leading up to the tag. $str = substr($html, $position, $tagPosition - $position); if ($printedLength + strlen($str) > $maxLength) { print(substr($str, 0, $maxLength - $printedLength)); $printedLength = $maxLength; break; } print($str); $printedLength += strlen($str); if ($printedLength >= $maxLength) break; if ($tag[0] == '&' || ord($tag) >= 0x80) { // Pass the entity or UTF-8 multibyte sequence through unchanged. print($tag); $printedLength++; } else { // Handle the tag. $tagName = $match[1][0]; if ($tag[1] == '/') { // This is a closing tag. $openingTag = array_pop($tags); assert($openingTag == $tagName); // check that tags are properly nested. print($tag); } else if ($tag[strlen($tag) - 2] == '/') { // Self-closing tag. print($tag); } else { // Opening tag. print($tag); $tags[] = $tagName; } } // Continue after the tag. $position = $tagPosition + strlen($tag); } // Print any remaining text. if ($printedLength < $maxLength && $position < strlen($html)) print(substr($html, $position, $maxLength - $printedLength)); // Close any open tags. while (!empty($tags)) printf('</%s>', array_pop($tags)); } printTruncated(10, '<b>&lt;Hello&gt;</b> <img src="world.png" alt="" /> world!'); print("\n"); printTruncated(10, '<table><tr><td>Heck, </td><td>throw</td></tr><tr><td>in a</td><td>table</td></tr></table>'); print("\n"); printTruncated(10, "<em><b>Hello</b>&#20;w\xC3\xB8rld!</em>"); print("\n"); printTruncated(500, "<div>AAAAAAAAA</div> <div><ol><li>xxxxxxxxxxxxxxx</li><li>yyyyyyyy<b>yyyyyyyyy</b>yyyyyyyy</li><li>zzzzzzz</li></ol>ccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc </div>"); print("\n");
Output for 8.0.0 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.4, 8.3.6
<b>&lt;Hello&gt;</b> <img src="world.png" alt="" /> w <table><tr><td>Heck, </td><td>thro</td></tr></table> <em><b>Hello</b>&#20;wørl</em> <div>AAAAAAAAA</div> <div><ol><li>xxxxxxxxxxxxxxx</li><li>yyyyyyyy<b>yyyyyyyyy</b>yyyyyyyy</li><li>zzzzzzz</li></ol>ccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc Fatal error: Uncaught AssertionError: assert($openingTag == $tagName) in /in/qlQjQ:46 Stack trace: #0 /in/qlQjQ(46): assert(false, 'assert($opening...') #1 /in/qlQjQ(83): printTruncated(500, '<div>AAAAAAAAA<...') #2 {main} thrown in /in/qlQjQ on line 46
Process exited with code 255.
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 <b>&lt;Hello&gt;</b> <img src="world.png" alt="" /> w <table><tr><td>Heck, </td><td>thro</td></tr></table> <em><b>Hello</b>&#20;wørl</em> <div>AAAAAAAAA</div> <div><ol><li>xxxxxxxxxxxxxxx</li><li>yyyyyyyy<b>yyyyyyyyy</b>yyyyyyyy</li><li>zzzzzzz</li></ol>ccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc Fatal error: Uncaught AssertionError: assert($openingTag == $tagName) in /in/qlQjQ:46 Stack trace: #0 /in/qlQjQ(46): assert(false, 'assert($opening...') #1 /in/qlQjQ(83): printTruncated(500, '<div>AAAAAAAAA<...') #2 {main} thrown in /in/qlQjQ on line 46
Process exited with code 255.
Output for 7.0.0 - 7.0.20, 7.1.0 - 7.1.33, 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33
<b>&lt;Hello&gt;</b> <img src="world.png" alt="" /> w <table><tr><td>Heck, </td><td>thro</td></tr></table> <em><b>Hello</b>&#20;wørl</em> <div>AAAAAAAAA</div> <div><ol><li>xxxxxxxxxxxxxxx</li><li>yyyyyyyy<b>yyyyyyyyy</b>yyyyyyyy</li><li>zzzzzzz</li></ol>ccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc Warning: assert(): assert($openingTag == $tagName) failed in /in/qlQjQ on line 46 </div></br></br></div>
Output for 4.3.3 - 4.3.11, 4.4.0 - 4.4.9, 5.0.0 - 5.0.5, 5.1.0 - 5.1.6, 5.2.0 - 5.2.17, 5.3.0 - 5.3.29, 5.4.0 - 5.4.45, 5.5.0 - 5.5.36, 5.6.0 - 5.6.28
<b>&lt;Hello&gt;</b> <img src="world.png" alt="" /> w <table><tr><td>Heck, </td><td>thro</td></tr></table> <em><b>Hello</b>&#20;wørl</em> <div>AAAAAAAAA</div> <div><ol><li>xxxxxxxxxxxxxxx</li><li>yyyyyyyy<b>yyyyyyyyy</b>yyyyyyyy</li><li>zzzzzzz</li></ol>ccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc Warning: assert(): Assertion failed in /in/qlQjQ on line 46 </div></br></br></div>
Output for 4.3.0 - 4.3.2
Warning: Wrong parameter count for preg_match() in /in/qlQjQ on line 14 <b>&lt;Hel Warning: Wrong parameter count for preg_match() in /in/qlQjQ on line 14 <table><tr Warning: Wrong parameter count for preg_match() in /in/qlQjQ on line 14 <em><b>Hel Warning: Wrong parameter count for preg_match() in /in/qlQjQ on line 14 <div>AAAAAAAAA</div> <div><ol><li>xxxxxxxxxxxxxxx</li><li>yyyyyyyy<b>yyyyyyyyy</b>yyyyyyyy</li><li>zzzzzzz</li></ol>ccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc<br> cccccccccccccccccccccccccccccccccccccccc </div>

preferences:
281.08 ms | 406 KiB | 391 Q