使用DOMDocument替换并返回部分HTML,而不添加body,doctype等

时间:2017-07-10 09:11:39

标签: php html laravel domdocument

我想在部分文档HTML文档上运行一些替换。比方说,我想在src标记的img参数上添加一些内容。

(示例)替换:

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

人:

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

我确实想使用DOMDocument来实现这一点,所以我编写了这样的代码:

$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());

但它返回:

<!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>

这次回归有几个问题:

  • 它使用了一个奇怪的doctype:HTML 4.0
  • 它确实添加了doctype,html标记和正文标记。

我知道DOMDocument添加doctype,html和body标签是“正常的”,但是可以避免这种吗?无论如何“只是”恢复我的HTML切片,只有我执行的替换?使用正则表达式不是一种选择,因为在任何地方都说它是不好的做法。

旁注:我使用Laravel,所以如果Laravel开箱即用,它也可能很棒!

2 个答案:

答案 0 :(得分:2)

您可以使用loadHTML()中提供的额外选项来实现您的目标。检查options参数。有关libxml常量here的详细信息。并注意它自PHP 5.4以来可用。像:

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

更新

如果您看到UTF-8字符被更改为某些奇数字符,那么使用mb_convert_encoding可以解决此问题,例如:

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

答案 1 :(得分:0)

如果您想使用laravel选项,那么您可以调用您拥有的部分并让它为您返回html:

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