rap-2-h
rap-2-h

Reputation: 32058

Replace and return partial HTML with DOMDocument without adding body, doctype, etc

I want to operate some replacement on a partial document HTML document. Let's say, I want to add something on the src argument of img tags.

(Example) Replace:

<p>hello</p><img src="REPLACE" /><p></p>

By:

<p>hello</p><img src="http://example.org/image.jpeg" /><p></p>

I did want to use DOMDocument to achieve this, so I coded something like this:

$doc = new \DOMDocument( '1.0', 'utf-8');
$doc->loadHTML('<p>hello</p><img src="REPLACE" /><p></p>');
$tags = $doc->getElementsByTagName('img');
foreach ($tags as $tag) {
    $tag->setAttribute('src', 'http://example.org/image.jpeg');
}
var_dump($doc->saveHTML());

But it returns:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
    <p>hello</p><img src="http://example.org/image.jpeg"><p></p>
</body></html>

There are several problems with this return:

I know it's "normal" that DOMDocument add doctype, html and body tag, but can I avoid this? Is there anyway to "just" recover my HTML slice, with only the replacement I performed? Using regex is not an option, because there post everywhere saying it's bad practice.

Side note: I use Laravel, so if there is something out of the box for Laravel, it could be great too!

Upvotes: 1

Views: 826

Answers (2)

Sudhir Bastakoti
Sudhir Bastakoti

Reputation: 100205

you can use extra options available in loadHTML() to achieve what you want. Check the options parameter. Detail about the libxml constants here. And note that its available since PHP 5.4. Like:

...
$doc->loadHTML('<p>hello</p><img src="REPLACE" /><p></p>',
    LIBXML_HTML_NOIMPLIED | 
    LIBXML_HTML_NODEFDTD);
...
$doc->saveHTML();

Update

If you see UTF-8 characters being changed to some odd characters, then using mb_convert_encoding can fix this, like:

$doc->loadHTML(
    mb_convert_encoding('<p>hello</p><img src="REPLACE" /><p></p>', 'HTML-ENTITIES', 'UTF-8'), 
    LIBXML_HTML_NOIMPLIED | 
    LIBXML_HTML_NODEFDTD 
); 

Upvotes: 2

zFeeds
zFeeds

Reputation: 1

If you want to use laravel option then you can just call the partial that you have and have it return the html for you:

$src = "http://example.org/image.jpeg"
return view('path_to_partial', compact('src'))->render();

Upvotes: -1

Related Questions