2

I would like to take a block of code stored in a variable and replace the src of any image tags in there without disturbing the rest of the code block.

For example : the block of code might read :

<a href="http://mylink.com"><img src="image1.jpg"></a>

I would like to change that to (using PHP) :

<a href="http://mylink.com"><img src="altimage.jpg"></a>

I am currently using a solution I found using the PHP DOM module to change the image tag but the function returns just the changed img tag HTML without the rest of the HTML.

The function I am calling is as follows :

function replace_img_src($original_img_tag, $new_src_url) {
    $doc = new DOMDocument();
    $doc->loadHTML($original_img_tag);
$tags = $doc->getElementsByTagName('img');
if(count($tags) > 0)
{
       $tag = $tags->item(0);
       $tag->setAttribute('src', $new_src_url);
       return $doc->saveXML($tag);
}

return false;
}

This, of course, just returns the changed img tag but strips the other HTML (such as the A tag) - I am passing the entire block of code to the function. (BTW - It's good for me to have the false return for no image tags as well).

What am I missing here please ?

Many thanks in advance for any help.

Chris Jones
  • 405
  • 1
  • 6
  • 17

1 Answers1

2

You need to use return $doc->saveXML(); instead of return $doc->saveXML($tag);. See the documentation of saveXML:

saveXML ([ DOMNode $node [, int $options ]] )

node: Use this parameter to output only a specific node without XML declaration rather than the entire document.

Community
  • 1
  • 1
ByteHamster
  • 4,884
  • 9
  • 38
  • 53
  • That does work ByteHamster but it puts an HTML wrapper (and doctype) around the code. I just read another SO post that explains the wrapper is actually added at LOAD time but can be disabled in loadHTML with LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD parameters but this is only implemented in PHP 5.4 and I am stuck with 5.3.x at the moment. A workaround is to use loadXML and then saveHTML but it isn't ideal. The post was here for reference : http://stackoverflow.com/questions/4879946/domdocument-savehtml-without-html-wrapper – Chris Jones Feb 24 '15 at 17:02
  • What about using `saveXML` and stripping the first line afterwards? – ByteHamster Feb 24 '15 at 17:05
  • Awesome :) loadXML and saveXML and stripping the first line works perfectly - Thank you! – Chris Jones Feb 24 '15 at 17:11
  • Actually - there is an issue with that. If the string contains no HTML (ie: something like "hello there") then the loadXML doesn't like it. In fact, irrespective of whether I use loadHTML or loadXML, then count($tags) is always 1 for the string "hello there" as generated by : $tags = $doc->getElementsByTagName('img'); – Chris Jones Feb 24 '15 at 17:53
  • Ok - solved that by using $tags->length instead of count($tags) lol – Chris Jones Feb 24 '15 at 18:06