3v4l.org

run code in 300+ PHP versions simultaneously
<?php function truncateHTML($html, $limit = 20) { static $wrapper = null; static $wrapperLength = 0; // trim unwanted CR/LF characters $html = trim($html); // Remove HTML comments $html = preg_replace("~<!--.*?-->~", '', $html); // If $html in in plain text if ((strlen(strip_tags($html)) > 0) && strlen(strip_tags($html)) == strlen($html)) { return substr($html, 0, $limit); } // If $html doesn't have a root element elseif (is_null($wrapper)) { if (!preg_match("~^\s*<[^\s!?]~", $html)) { // Defining a tag as our HTML wrapper $wrapper = 'div'; $htmlWrapper = "<$wrapper></$wrapper>"; $wrapperLength = strlen($htmlWrapper); $html = preg_replace("~><~", ">$html<", $htmlWrapper); } } // Calculating total length $totalLength = strlen($html); // If our input length is less than limit, we are done. if ($totalLength <= $limit) { if ($wrapper) { return preg_replace("~^<$wrapper>|</$wrapper>$~", "", $html); } return strlen(strip_tags($html)) > 0 ? $html : ''; } // Initializing a DOM object to hold our HTML $dom = new DOMDocument; $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // Initializing a DOMXPath object to query on our DOM $xpath = new DOMXPath($dom); // Query last node (this does not include comment or text nodes) $lastNode = $xpath->query("./*[last()]")->item(0); // While manipulating, when there is no HTML element left if ($totalLength > $limit && is_null($lastNode)) { if (strlen(strip_tags($html)) >= $limit) { $textNode = $xpath->query("//text()")->item(0); if ($wrapper) { $textNode->nodeValue = substr($textNode->nodeValue, 0, $limit ); $html = $dom->saveHTML(); return preg_replace("~^<$wrapper>|</$wrapper>$~", "", $html); } else { $lengthAllowed = $limit - ($totalLength - strlen($textNode->nodeValue)); if ($lengthAllowed <= 0) { return ''; } $textNode->nodeValue = substr($textNode->nodeValue, 0, $lengthAllowed); $html = $dom->saveHTML(); return strlen(strip_tags($html)) > 0 ? $html : ''; } } else { $textNode = $xpath->query("//text()")->item(0); $textNode->nodeValue = substr($textNode->nodeValue, 0, -(($totalLength - ($wrapperLength > 0 ? $wrapperLength : 0)) - $limit)); $html = trim($dom->saveHTML()); return strlen(strip_tags($html)) > 0 ? $html : ''; } } // If we have a text node after our last HTML element elseif ($nextNode = $lastNode->nextSibling) { if ($nextNode->nodeType === 3 /* DOMText */) { $nodeLength = strlen($nextNode->nodeValue); // If by removing our text node total length will be greater than limit if (($totalLength - ($wrapperLength > 0 ? $wrapperLength : 0)) - $nodeLength >= $limit) { // We should remove it $nextNode->parentNode->removeChild($nextNode); $html = $dom->saveHTML(); return truncateHTML($html, $limit); } // If by removing our text node total length will be less than limit else { // We should truncate our text to fit the limit $nextNode->nodeValue = substr($nextNode->nodeValue, 0, ($limit - (($totalLength - ($wrapperLength > 0 ? $wrapperLength : 0)) - $nodeLength))); $html = $dom->saveHTML(); // Caring about custom wrapper if ($wrapper) { return preg_replace("~^<$wrapper>|</$wrapper>$~", "", $html); } return $html; } } } // If current node is an HTML element elseif ($lastNode->nodeType === 1 /* DOMElement */) { $nodeLength = strlen($lastNode->nodeValue); // If by removing current HTML element total length will be greater than limit if (($totalLength - ($wrapperLength > 0 ? $wrapperLength : 0)) - $nodeLength >= $limit) { // We should remove it $lastNode->parentNode->removeChild($lastNode); $html = $dom->saveHTML(); return truncateHTML($html, $limit); } // If by removing current HTML element total length will be less than limit else { // We should truncate our node value to fit the limit $lastNode->nodeValue = substr($lastNode->nodeValue, 0, ($limit - (($totalLength - ($wrapperLength > 0 ? $wrapperLength : 0)) - $nodeLength))); $html = $dom->saveHTML(); if ($wrapper) { return preg_replace("~^<$wrapper>|</$wrapper>$~", "", $html); } return $html; } } } $html = <<< HTML <div>some data sdfasdfasdfasdffrom <span class="first">blahblah test</span> was <span class="second">good</span>test<p> something</p><span class="text">hola</span><!-- comment --></div> HTML; echo truncateHTML($html, 20);

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.40.0160.00319.46
8.3.30.0060.00919.40
8.3.20.0080.00020.88
8.3.10.0110.00022.31
8.3.00.0040.00422.34
8.2.170.0110.01122.96
8.2.160.0170.00719.78
8.2.150.0040.00424.18
8.2.140.0040.00724.66
8.2.130.0050.00321.41
8.2.120.0040.00426.35
8.2.110.0040.00721.25
8.2.100.0040.00818.59
8.2.90.0040.00419.72
8.2.80.0060.00318.66
8.2.70.0030.00718.13
8.2.60.0030.00618.54
8.2.50.0060.00318.43
8.2.40.0030.00521.09
8.2.30.0040.00421.37
8.2.20.0040.00618.66
8.2.10.0030.00618.54
8.2.00.0000.00818.57
8.1.270.0000.00823.99
8.1.260.0040.00426.35
8.1.250.0060.00328.09
8.1.240.0060.00324.34
8.1.230.0070.00419.80
8.1.220.0080.00018.41
8.1.210.0040.00418.77
8.1.200.0030.00618.10
8.1.190.0060.00317.97
8.1.180.0030.00518.14
8.1.170.0050.00319.28
8.1.160.0060.00319.56
8.1.150.0080.00021.14
8.1.140.0050.00320.07
8.1.130.0040.00419.43
8.1.120.0040.00418.16
8.1.110.0000.00818.15
8.1.100.0030.00618.03
8.1.90.0030.00618.19
8.1.80.0030.00518.10
8.1.70.0040.00418.17
8.1.60.0000.00818.28
8.1.50.0000.00818.11
8.1.40.0030.00618.17
8.1.30.0030.00518.37
8.1.20.0050.00318.38
8.1.10.0040.00418.23
8.1.00.0000.00818.18
8.0.300.0070.00218.77
8.0.290.0030.00617.38
8.0.280.0000.00718.95
8.0.270.0000.00717.82
8.0.260.0050.00317.51
8.0.250.0000.00817.75
8.0.240.0050.00517.76
8.0.230.0100.00017.73
8.0.220.0020.00517.56
8.0.210.0000.00917.51
8.0.200.0000.00717.71
8.0.190.0000.00917.73
8.0.180.0040.00417.64
8.0.170.0000.00817.61
8.0.160.0070.00017.70
8.0.150.0020.00517.46
8.0.140.0040.00417.56
8.0.130.0060.00014.11
8.0.120.0030.00617.58
8.0.110.0000.00817.55
8.0.100.0040.00417.59
8.0.90.0040.00417.45
8.0.80.0100.01017.70
8.0.70.0040.00417.48
8.0.60.0000.00917.75
8.0.50.0040.00417.47
8.0.30.0050.01317.63
8.0.20.0120.00817.89
8.0.10.0000.00717.67
8.0.00.0130.01017.50
7.4.330.0030.00315.66
7.4.320.0060.00017.25
7.4.300.0000.00717.28
7.4.290.0000.00717.30
7.4.280.0030.00617.36
7.4.270.0040.00417.34
7.4.260.0040.00417.27
7.4.250.0000.00817.30
7.4.240.0000.00817.31
7.4.230.0000.00817.29
7.4.220.0100.01017.19
7.4.210.0060.01017.20
7.4.200.0000.00717.42
7.4.160.0110.00617.31
7.4.150.0160.00317.40
7.4.140.0150.00917.86
7.4.130.0070.01217.15
7.4.120.0120.01017.37
7.4.110.0150.01117.23
7.4.100.0070.01117.18
7.4.90.0120.00617.14
7.4.80.0090.01219.39
7.4.70.0030.01417.03
7.4.60.0100.00717.24
7.4.50.0120.00817.05
7.4.40.0120.01217.22
7.4.30.0160.00317.26
7.4.00.0060.00915.31
7.3.330.0000.00513.98
7.3.320.0000.00614.04
7.3.310.0090.00016.99
7.3.300.0000.00717.07
7.3.290.0090.00817.12
7.3.280.0090.00817.11
7.3.270.0090.00917.40
7.3.260.0110.00917.12
7.3.250.0110.00917.26
7.3.240.0090.00917.29
7.3.230.0040.01417.14
7.3.210.0090.00917.02
7.3.200.0090.00917.02
7.3.190.0060.01217.32
7.3.180.0070.01117.42
7.3.170.0110.01017.42
7.3.160.0100.00717.35
7.2.330.0110.00717.45
7.2.320.0030.01617.27
7.2.310.0070.01517.41
7.2.300.0140.01017.35
7.2.290.0110.00817.36
7.2.60.0110.00317.43
7.2.00.0030.01319.91
7.1.200.0030.00716.00
7.1.100.0000.00918.31
7.1.70.0090.00917.55
7.1.60.0190.01235.67
7.1.50.0220.01235.18
7.1.40.0280.01235.05
7.1.30.0270.01935.09
7.1.20.0270.01235.18
7.1.10.0110.01017.03
7.1.00.0100.01317.31
7.0.200.0070.01417.11
7.0.190.0070.01117.07
7.0.180.0080.01516.88
7.0.170.0060.01116.60
7.0.160.0040.01716.86
7.0.150.0080.00916.65
7.0.140.0050.01716.80
7.0.130.0060.01716.79
7.0.120.0120.01016.79
7.0.110.0040.01616.72
7.0.100.0100.01016.73
7.0.90.0030.01816.79
7.0.80.0080.01416.77
7.0.70.0100.00716.71
7.0.60.0080.00816.57
7.0.50.0100.01016.76
7.0.40.0120.01016.86
7.0.30.0140.00817.05
7.0.20.0090.01316.70
7.0.10.0110.00816.80
7.0.00.0030.01816.96

preferences:
50.6 ms | 400 KiB | 5 Q