Я пытаюсь добавить HTML ко всем ссылкам, которые содержат изображение.
Базовый HTML загружается в DOM выглядит
<div class='content'>
<a href="..."><img src=""></a>
<figure>
<a href="..."><img src=""></a>
<figcaption>Caption</figcaption>
</figure>
</div>
Код:
$content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
$dom = new DOMDocument();
@$dom->loadHTML($content);
// Convert Images
$images = [];
foreach ($dom->getElementsByTagName('img') as $node) {
$images[] = $node;
}
foreach ($images as $node) {
$field_html = $dom->createDocumentFragment(); // create fragment
$field_html->appendXML('<span>11</span>'); // create fragment
$node->parentNode->appendChild($field_html);
}
$newHtml = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
return $newHtml;
Поэтому, когда это обычная ссылка с img, она выдает правильный вывод:
<a href="..."><img src=""><span>11</span></a>
Но когда это цифра, вывод очень странный — ссылка дублируется и вставляется в figcaption
:
<figure>
<a href="..."><img src=""></a>
<figcaption>Caption <a href="..."><span>11</span>
</figcaption>
</figure>
Это потому что DOMDocument не понимает figure
вещь?
Я не смог воспроизвести вашу проблему. Мое предположение было бы неуместным элементом где-то в вашем исходном HTML. Но ваш код может быть немного упрощен.
Нет необходимости помещать ваши узлы изображения в массив, вы можете работать непосредственно с результатами DomDocument::getElementsByTagName()
,
Как уже упоминалось в комментариях, вы можете настроить DomDocument::loadHTML()
не добавлять doctype и подразумеваемые элементы, а не удалять их позже с помощью хитрых манипуляций со строками.
Просто DomDocument::createElement()
может использоваться для элемента, который вы хотите добавить, вместо создания нового объекта.
В заключение, оператор контроля ошибок @
как правило, следует избегать. Вместо, libxml_use_internal_errors()
может использоваться для установки поведения ошибки. Это позволяет вам просматривать сообщения об ошибках с libxml_get_errors()
при желании
$content = <<< HTML
<div class="content">
<a href="..."><img src=""></a>
<figure>
<a href="..."><img src=""></a>
<figcaption>Caption</figcaption>
</figure>
</div>
HTML;
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_use_internal_errors(false);
foreach ($dom->getElementsByTagName('img') as $node) {
$node->parentNode->appendChild($dom->createElement("span", "11"));
}
$newHtml = $dom->saveHTML();
echo $newHtml;
Выход:
<div class="content">
<a href="..."><img src=""><span>11</span></a>
<figure>
<a href="..."><img src=""><span>11</span></a>
<figcaption>Caption</figcaption>
</figure>
</div>
Других решений пока нет …