Чистка HTML строки от ненужных тегов на PHP
При получении HTML страницы, её разбора с помощью известных библиотек, как правило требуется очистить полученный html код от ненужных тегов. Конечно, в PHP есть универсальная функция strip_tags(), но она позволяет только вычистить код от самих тегов и оставляет содержимое как неформатированный текст. Так же функция позволяет оставить в коде теги указанные во втором параметре. Например если нам нужно оставить в коде заголовки и ссылки.
$html_result = strip_tags($textStr, '<h1><h2><h3><h4><h5><h6><a>');
Удаление тегов с внутренним содержимым и инверсией.
В зависимости от поставленной задачи по обработе HTML кода может потребоваться удалить или наоборот оставить некоторые теги с внутренним содержимым. Для этого написано практичное решение на основе регулярных выражений. В большинстве случаев его хватает для поставленной задачи по обработке строкового html кода.
function strip_tags_content($text, $tags = '', $invert = FALSE) {
preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags);
$tags = array_unique($tags[1]);
if(is_array($tags) AND count($tags) > 0) {
if($invert == FALSE) {
return preg_replace('@<(?!(?:'. implode('|', $tags) .')\b)(\w+)\b.*?>.*?{C}@si', '', $text);
}
else {
return preg_replace('@<('. implode('|', $tags) .')\b.*?>.*?{C}@si', '', $text);
}
}
elseif($invert == FALSE) {
return preg_replace('@<(\w+)\b.*?>.*?{C}@si', '', $text);
}
return $text;
}
//Исходная строка:
$text = 'sample text with
tags
';
//Результат для strip_tags($text):
//sample text with tags
//Результат для strip_tags_content($text):
//text with
//Результат для strip_tags_content($text, ''):
//sample text with
//Результат для strip_tags_content($text, '', TRUE);
//text with
tags
PHP функция для удаления определенных HTML-тегов и атрибутов
Эта функция использует PHP библиотеку DOMDocument, чтобы создать объектную модель документа и удалить всё кроме тегов и атрибутов, которые необходимо сохранить.
Такое решение позволяет использовать регулярное выражение избирательно для выбранных типов данных, по этому не придётся искать заданные атрибуты в HTML строке. Задача поиска тегов и атрибутов осуществляется с помощью XPath методов PHP DOMDocument.
Функция удаления HTML тегов принимает в качестве аргументов строку для “очистки” и два массива в качестве параметров; массивы — список разрешенных тегов и список допустимых атрибутов. Если атрибуты “href” или “src” разрешены, функция проверяет: если значение атрибута – это код JavaScript, то изменяет его на “#”:
<?php
function stripTagsAttributes($html, $allowedTags = array(), $allowedAttributes = array('(?:a^)')) {
if (!empty($html)) {
$theTags = count($allowedTags) ? '<' . implode('><', $allowedTags) . '>' : '';
$theAttributes = '%' . implode('|', $allowedAttributes) . '%i';
$dom = @DOMDocument::loadHTML(
mb_convert_encoding(
strip_tags(
$html,
$theTags
),
'HTML-ENTITIES',
'UTF-8'
)
);
$xpath = new DOMXPath($dom);
$tags = $xpath->query('//*');
foreach ($tags as $tag) {
$attrs = array();
for ($i = 0; $i < $tag->attributes->length; $i++) {
$attrs[] = $tag->attributes->item($i)->name;
}
foreach ($attrs as $attribute) {
if (!preg_match($theAttributes, $attribute)) {
$tag->removeAttribute($attribute);
} elseif (preg_match('%^(?:href|src)$%i', $attribute) and preg_match('%^javascript:%i', $tag->getAttribute($attribute))) {
$tag->setAttribute($attribute, '#');
}
}
}
return (
trim(
strip_tags(
html_entity_decode(
$dom->saveHTML()
),
$theTags
)
)
);
}
}
?>
Перед тем, как с помощью PHP убрать HTML теги, расскажу о нескольких проблемах, связанных с использованием DOMDocument:
и
- Если вы парсите фрагмент кода вместо всей страницы, и в нем нет тега кодировки символов, то DOMDocument будет считать, что текст закодирован в ISO-8859 вместо UTF-8. Поэтому, прежде чем загрузить фрагмент кода, эта функция использует mb_convert_encoding, чтобы преобразовать любые символы Unicode в объекты HTML. Затем использует html_entity_decode, чтобы преобразовать объекты назад в символы, когда парсинг завершится;
- Когда вы парсите HTML- фрагмент, DOMDocument всегда добавляет DOCTYPE,
Два массива тегов и атрибутов похожи на комментарии. Заметьте, что последний элемент в массиве $commentAttributes — простое регулярное выражение, которое соответствует любому типу данных атрибута:
<?php
$commentTags = array(
'b',
'i',
'a',
'strong',
'em',
'blockquote',
'div',
'p',
'br',
'strike',
'del',
'sup',
'sub',
'code',
'pre',
'span',
'img',
'button',
);
$commentAttributes = array(
'href',
'rel',
'target',
'src',
'width',
'height',
'class',
'data-S*'
);
?>
Кстати, при удалении HTML тегов из PHP соблюдаются дополнительные меры санитизации (где добавлены комментарии). Например, изображения могут быть встроены только в комментарии, если они загружены и размещены на сайте, иначе они превращаются в ссылки на внешние изображения. Это необходимо для предотвращения распространения изображений, содержащих вредоносный код, порно и т. д.
Дата публикации: