PHP Token replaces html objects
I want to make certain words / lines as links if found in the text. I have a piece of code from php.bet that does this, but also removes the start and end tags from <a href="http://www.domain.com/index.php" title="Home">go to homepage</a>
. Can you help solve this problem?
Here's a piece of code:
<?php
$str_in = '<p>Hi there worm! You have a disease!</p><a href="http://www.domain.com/index.php" title="Home">go to homepage</a>';
$replaces= array(
'worm' => 'http://www.domain.com/index.php/worm.html',
'disease' => 'http://www.domain.com/index.php/disease.html'
);
function addLinks($str_in, $replaces)
{
$str_out = '';
$tok = strtok($str_in, '<>');
$must_replace = (substr($str_in, 0, 1) !== '<');
while ($tok !== false) {
if ($must_replace) {
foreach ($replaces as $tag => $href) {
if (preg_match('/\b' . $tag . '\b/i', $tok)) {
$tok = preg_replace(
'/\b(' . $tag . ')\b/i',
'<a title="' . $tag . '" href="' . $href . '">\1</a>',
$tok,
1);
unset($replaces[$tag]);
}
}
} else {
$tok = "<$tok>";
}
$str_out .= $tok;
$tok = strtok('<>');
$must_replace = !$must_replace;
}
return $str_out;
}
echo addLinks($str_in, $replaces);
Result:
Hello worm! You have a disease!
a href = "http://www.domain.com/index.php" title = "Home" / a
The words "worm" and "disease" are converted to such links as desired, but the rest ...
Thank you so much!
source to share
This pair of functions should do what you want without the hassle of parsing HTML with regex or str_replace
.
function process($node, $replaceRules)
{
if($node->hasChildNodes()) {
$nodes = array();
foreach ($node->childNodes as $childNode) {
$nodes[] = $childNode;
}
foreach ($nodes as $childNode) {
if ($childNode instanceof DOMText) {
$text = preg_replace(
array_keys($replaceRules),
array_values($replaceRules),
$childNode->wholeText);
$node->replaceChild(new DOMText($text),$childNode);
}
else {
process($childNode, $replaceRules);
}
}
}
}
function addLinks($str_in, $replaces)
{
$replaceRules = array();
foreach($replaces as $k=>$v) {
$k = '/\b(' . $k . ')\b/i';
$v = '<a href="' . $v . '">$1</a>';
$replaceRules[$k] = $v;
}
$doc = new DOMDocument;
$doc->loadHTML($str_in);
process($doc->documentElement, $replaceRules);
return html_entity_decode($doc->saveHTML());
}
Note: You don't need to worry if the HTML is not well structured (as in your example); however, the exit will be well structured.
Credit where he owes: The
recursive function process()
that does most of the real work comes from Lukáš Lalinský & rsquo; See s answer to How to replace text in HTML . The function addLinks()
is just a use case that matches your question.
source to share
Not sure why you have such a big construct when something like:
$str_out = preg_replace('/(' . preg_quote(implode('|', array_keys($replaces))) . ')/', $replaces[$1], $str_in);
will do the same thing. Of course, using regular expressions to process HTML is a dangerous process . You have to use the DOM with some xpath to do this more reliably.
source to share