0

I have thrown together a little function to find and replace a string within a block of text but it seems to be draining resources. I figure this is because I am trying to run it on a whole HTML page.

All I really want to do is replace all text except the title tag.

Here is my function:

/**
 * Find and replace strings with skip
 *
 * @param string $haystack
 * @param string $needle
 * @param int    $start
 * @param int    $skip
 *
 * @return mixed
 */
function skip_and_replace($haystack, $needle, $start = 0, $skip = 0) {
    $count = 0;
    while ($pos = strpos(($haystack), $needle, $start) !== false) {
        if ($count <= $skip)
            continue;

        substr_replace($haystack, ' M<sup>c</sup>', $pos, strlen($needle));

        $start = $pos+1;

        $count++;
    }

    return $haystack;
}

Can anyone please help with making this function easier on the memory or let me know if there is a better way to achieve my end goal?

Wildcard27
  • 1,437
  • 18
  • 48
  • Could regular expression achieve the same result you are going for? Looping through a whole Page sure has its consequences. What would you like to achieve? That is: which String or parts of string or words or characters are you attempting to replace in the HTML Content? – Poiz May 09 '16 at 22:57
  • It looks like this function has an infinite loop. It just repeatedly gets the position of the $needle in the $haystack and there is nothing to break out of the loop. That's why it is running out of memory. It also doesn't do anything because $haystack isn't passed to `substr_replace` by reference which means it doesn't affect the value of $haystack. – Cave Johnson May 09 '16 at 23:41
  • @Andrew You're absolutely correct about the infinite loop! Can't believe I missed that! I'll update the question now. Can you please explain what you mean by $haystack not being passed by reference? Should I use `&$haystack`? – Wildcard27 May 10 '16 at 00:27
  • Maybe this can help you. Have a look at this [post](http://stackoverflow.com/questions/4886319/replace-text-in-html-page-with-jquery) – Harshad Pawar May 10 '16 at 06:36
  • @HarshadPawar Sorry, this needs to be a PHP resolution. Can nobody help me with this?? There must be a way to do it! – Wildcard27 May 10 '16 at 22:20
  • There's still an infinite loop. – miken32 May 10 '16 at 22:34
  • @miken32 Can you please point out where and what I need to do to fix it? I think I've spent too much time looking at this stupid function! – Wildcard27 May 10 '16 at 22:41
  • You shouldn't be treating HTML like text, but have a look at `if ($count <= $skip) continue;` – miken32 May 10 '16 at 22:42
  • @miken32 Wow. I'm so angry with myself for missing that! Will put the count++ in now. Is there a better way that you can think of to handle HTML? I looks at DOM parsers but they seem too heavy for what I need – Wildcard27 May 10 '16 at 22:45

1 Answers1

2

If you want to replace all but the first instance of a string, this should work. Can't guarantee it will scale well, but it's the first thing that came to mind.

$haystack = "foo bar baz foo bar baz foo bar baz";
$oldtext = "bar";
$newtext = "rab";

$arr = explode($oldtext, $haystack, 2);
$arr[1] = str_replace($oldtext, $newtext, $arr[1]);
$new_string = implode($oldtext, $arr);
miken32
  • 42,008
  • 16
  • 111
  • 154