3v4l.org

run code in 300+ PHP versions simultaneously
<?php $html = 'this is just some example text.'; $terms = array( 'example'=>'explanation about example' ); // sort by reverse order of key size // (to be sure that the longest string always wins instead of the first in the pattern) uksort($terms, function ($a, $b) { $diff = mb_strlen($b) - mb_strlen($a); return ($diff) ? $diff : strcmp($a, $b); }); // build the pattern inside a capture group (to have delimiters in the results with the PREG_SPLIT_DELIM_CAPTURE option) $pattern = '~\b(' . implode('|', array_map(function($i) { return preg_quote($i, '~'); }, array_keys($terms))) . ')\b~i'; // prevent eventual html errors to be displayed $libxmlInternalErrors = libxml_use_internal_errors(true); // determine if the html string have a root html element already, if not add a fake root. $dom = new DOMDocument; $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $fakeRootElement = false; if ( $dom->documentElement->nodeName !== 'html' ) { $dom->loadHTML("<div>$html</div>", LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED); $fakeRootElement = true; } libxml_use_internal_errors($libxmlInternalErrors); // find all text nodes (not already included in a link or between other unwanted tags) $xp = new DOMXPath($dom); $textNodes = $xp->query('//text()[not(ancestor::a)][not(ancestor::style)][not(ancestor::script)]'); // replacement foreach ($textNodes as $textNode) { $parts = preg_split($pattern, $textNode->nodeValue, -1, PREG_SPLIT_DELIM_CAPTURE); $fragment = $dom->createDocumentFragment(); foreach ($parts as $k=>$part) { if ($k&1) { $anchor = $dom->createElement('a', $part); $anchor->setAttribute('class', 'text-info'); $anchor->setAttribute('data-toggle', 'tooltip'); $anchor->setAttribute('data-original-title', $terms[strtolower($part)]); $fragment->appendChild($anchor); } else { $fragment->appendChild($dom->createTextNode($part)); } } $textNode->parentNode->replaceChild($fragment, $textNode); } // building of the result string $result = ''; if ( $fakeRootElement ) { foreach ($dom->documentElement->childNodes as $childNode) { $result .= $dom->saveHTML($childNode); } } else { $result = $dom->saveHTML(); } echo $result;
Output for git.master, git.master_jit, rfc.property-hooks
this is just some <a class="text-info" data-toggle="tooltip" data-original-title="explanation about example">example</a> text.

This tab shows result from various feature-branches currently under review by the php developers. Contact me to have additional branches featured.

Active branches

Archived branches

Once feature-branches are merged or declined, they are no longer available. Their functionality (when merged) can be viewed from the main output page


preferences:
35.38 ms | 405 KiB | 5 Q