Как найти все картинки в HTML-тексте на PHP и обернуть их в ссылки
Как найти все изображения в HTML-тексте новости или статьи и обернуть каждое ссылкой на полноразмерную картинку для галереи-лайтбокса: на DOMDocument и на регулярных выражениях.
Задача из практики: в новостях на 1С-Битрикс картинки вставлены прямо в текст, а нужно, чтобы по клику они открывались в полном размере в лайтбоксе (например, fancybox). Для этого каждую картинку надо обернуть ссылкой на её же файл.
Надёжный способ: DOMDocument
function wrapImages(string $html, string $class = 'fancybox'): string
{
if (trim($html) === '') {
return $html;
}
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML('<?xml encoding="utf-8"?><div>' . $html . '</div>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach (iterator_to_array($dom->getElementsByTagName('img')) as $img) {
if ($img->parentNode->nodeName === 'a') {
continue; // уже в ссылке
}
$link = $dom->createElement('a');
$link->setAttribute('href', $img->getAttribute('src'));
$link->setAttribute('class', $class);
$img->parentNode->replaceChild($link, $img);
$link->appendChild($img);
}
$wrapper = $dom->getElementsByTagName('div')->item(0);
$out = '';
foreach ($wrapper->childNodes as $child) {
$out .= $dom->saveHTML($child);
}
return $out;
}
Функция пропускает картинки, которые уже стоят в ссылке, и не ломается на разных порядках атрибутов и кавычках.
Короткий способ: регулярное выражение
$content = preg_replace(
'~(<img\b[^>]*\bsrc=(["\'])([^"\']+)\2[^>]*>)~i',
'<a class="fancybox" href="$3">$1</a>',
$content
);
Подходит для простого и предсказуемого HTML. Если картинки уже бывают обёрнуты ссылками, используйте вариант с DOMDocument.
Где вызывать в Битрикс
В result_modifier.php шаблона компонента новости: $arResult['DETAIL_TEXT'] = wrapImages($arResult['DETAIL_TEXT']);. Результат кешируется вместе с компонентом, и обработка не выполняется на каждом просмотре.