为什么这个代码:
$doc = new DOMDocument();
$doc->loadHTML($this->content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$imgNodes = $doc->getElementsByTagName('img');
if ($imgNodes->length > 0) {
$inlineImage = new Image();
$inlineImage->setPublicDir($publicDirPath);
foreach ($imgNodes as $imgNode) {
$inlineImage->setUri($imgNode->getAttribute('src'));
$inlineImage->setName(basename($inlineImage->getUri()));
if ($inlineImage->getUri() != $dstPath.$inlineImage->getName()) {
$inlineImage->move($dstPath);
$imgNode->setAttribute('src', $dstPath.'/'.$inlineImage->getName());
}
}
$this->content = $doc->saveHtml();
}
Run Code Online (Sandbox Code Playgroud)
在这段代码上执行:
<p><img alt="fluid cat" src="/images/tmp/fluid-cat.jpg"></p><p><img alt="pandas" src="/images/tmp/pandas.jpg"></p>
Run Code Online (Sandbox Code Playgroud)
导致此代码:
<p><img alt="fluid cat" src="/images/full/2016-09/fluid-cat.jpg"><p><img alt="pandas" src="/images/full/2016-09/pandas.jpg"></p></p>
Run Code Online (Sandbox Code Playgroud)
为什么它将两个img标签放在第一个p块中?
您的html示例没有包含所有内容的根元素.当LIBXML解析html以构建DOM树时,它假定第一个遇到的标记是根元素.结果,第一个标签</p>被视为一个孤儿结束标签(因为它后面有内容)并被自动删除,并</p>在最后添加一个标签以关闭根元素.
要在使用html部件(不是整个html文档)时避免这些自动修复,您需要添加一个假的根元素.最后,要生成结果字符串,您需要保存此伪根元素的每个子节点.例:
$html = '<p><img alt="fluid cat" src="/images/tmp/fluid-cat.jpg"></p><p><img alt="pandas" src="/images/tmp/pandas.jpg"></p>';
$doc = new DOMDocument;
$doc->loadHTML( '<div>' . $html . '</div>', LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
# ^-----------------^----- fake root element
$root = $doc->documentElement;
$result = '';
foreach($root->childNodes as $childNode) {
$result .= $doc->saveHTML($childNode);
}
echo $result;
Run Code Online (Sandbox Code Playgroud)