Освоение функции strip_tags для удаления HTML разметки
При работе с текстовыми данными в PHP часто требуется очистить строку от HTML тегов. Это может быть необходимо для безопасного отображения пользовательского ввода, извлечения чистого текста из HTML документа или подготовки данных для экспорта. Функция strip_tags() предоставляет простое и эффективное решение для удаления HTML и PHP тегов из строки. В этой статье рассматриваются различные способы удаления тегов, их преимущества и ограничения.
Основной способ: функция strip_tags
Функция strip_tags удаляет все HTML и PHP теги из строки, оставляя только текстовое содержимое. Она имеет синтаксис:
strip_tags(string $string, array|string|null $allowed_tags = null): stringPhp маленькие буквы (преобразование строки в нижний регистр в php)
Первый параметр – обрабатываемая строка. Второй необязательный параметр позволяет указать теги, которые не следует удалять. Пример базового использования:
<?php
$html = '<h1>Заголовок</h1><p>Текст с <b>жирным</b> выделением.</p>';
$clean = strip_tags($html);
echo $clean;
?>Character php (символы php)
ЗаголовокТекст с жирным выделением.
Php new line (символ новой строки в php)
Как видно, все теги удалены, текст склеен. Чтобы сохранить определенные теги (например, <p> и <b>), используется второй параметр:
<?php
$html = '<h1>Заголовок</h1><p>Текст с <b>жирным</b> выделением.</p>';
$clean = strip_tags($html, '<p><b>');
echo $clean;
?>Php проверить строку (проверить строку в php)
Заголовок<p>Текст с <b>жирным</b> выделением.</p>
Php пробел (удаление пробелов в php)
В результате тег <h1> удалён, а <p> и <b> остались. Функция strip_tags является предпочтительным способом для удаления тегов благодаря встроенной оптимизации и корректной обработке большинства случаев.
Типичные ошибки и проблемы:
- strip_tags не удаляет текстовое содержимое внутри тегов <script> и <style> – оно остаётся как обычный текст. Для полной очистки от скриптов требуется дополнительная обработка.
- Функция работает только с корректными HTML тегами; некорректная разметка (например, незакрытые теги) может привести к непредсказуемым результатам.
- При использовании разрешённых тегов следует помнить, что strip_tags не проверяет атрибуты – все атрибуты внутри разрешённого тега сохраняются, что может быть небезопасно (XSS).
- Производительность: функция достаточно быстрая, но на очень длинных строках может потребоваться альтернативное решение.
Как удалить HTML теги с помощью регулярных выражений?
Регулярные выражения дают гибкий контроль над удалением. Самый простой шаблон для удаления всех тегов:
<?php
$html = '<h1>Заголовок</h1><p>Текст с <b>жирным</b> выделением.</p>';
$clean = preg_replace('/<[^>]*>/', '', $html);
echo $clean;
?>удалить html теги php (php удалить html теги)
ЗаголовокТекст с жирным выделением.
удалить пробел в строке php (php удалить пробелы в строке)
Шаблон /<[^>]*>/ находит любую последовательность, начинающуюся с <, затем любые символы, кроме >, и заканчивающуюся >. Такой подход удаляет и открывающие, и закрывающие теги. Однако он не обрабатывает вложенные теги корректно и может удалить часть содержимого, если в атрибутах встречается символ >. Более надежные шаблоны, например, с использованием рекурсии, сложны и не рекомендуются для production.
Цель использования: когда необходим нестандартный фильтр (например, удалить только теги с определённым классом или атрибутом), и производительность некритична.
Проблемы и ошибки: регулярные выражения не предназначены для разбора HTML. Они легко ломаются на некорректной разметке, пропускают теги в комментариях, могут удалить больше, чем нужно. Не рекомендуется для обработки входящего пользовательского контента из-за риска ошибок. Вместо них лучше использовать встроенную функцию strip_tags.
Как удалить теги с помощью DOMDocument?
DOMDocument позволяет работать с HTML как с объектной моделью документа. Можно пройтись по всем узлам и удалить нежелательные теги, сохранив структуру. Пример удаления всех тегов, кроме <p> и <b>:
<?php
$html = '<h1>Заголовок</h1><p>Текст с <b>жирным</b> выделением.</p>';
$dom = new DOMDocument();
@$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$allowed = ['p', 'b'];
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//*') as $node) {
if (!in_array($node->nodeName, $allowed)) {
$text = $dom->createTextNode($node->textContent);
$node->parentNode->replaceChild($text, $node);
}
}
$clean = $dom->saveHTML();
echo $clean;
?>Php подстроки (получение подстроки в php)
<p>Текст с <b>жирным</b> выделением.</p>
Php длина строки (длина строки php)
Метод заменяет каждый неразрешённый узел на текстовый узел с его содержимым. Таким образом сохраняется текст, но структура упрощается. DOMDocument лучше справляется с некорректным HTML, но требует больше ресурсов.
Цель использования: когда нужно обработать сложный или некорректный HTML, сохранив иерархию, или выполнить селективное удаление с учётом атрибутов.
Проблемы: DOMDocument может добавлять DOCTYPE и другие служебные элементы, если не использовать флаги загрузки. Работа с DOM требует аккуратности при обработке больших объёмов данных – производительность ниже, чем у strip_tags. Код сложнее в поддержке.
Как безопасно вывести текст после удаления тегов?
Даже после удаления тегов остающиеся символы (угловые скобки, кавычки) могут быть опасны при выводе в браузер. Комбинация strip_tags с htmlspecialchars обеспечивает двойную защиту:
<?php
$html = '<h1>Заголовок & текст <script>alert(1)</script></h1>';
$step1 = strip_tags($html); // удаляет теги, но оставляет & и текст скрипта
$step2 = htmlspecialchars($step1, ENT_QUOTES, 'UTF-8');
echo $step2;
?>Php str replace (замена в строке php)
Заголовок & текст alert(1)
Здесь strip_tags удаляет теги <h1> и <script>, но содержимое скрипта (alert(1)) остаётся. Затем htmlspecialchars экранирует символы, превращая & в & и любые другие опасные символы, предотвращая XSS. Такой подход используется для безопасного отображения пользовательского ввода.
Цель использования: подготовка текста для вывода в HTML-контексте с минимальным риском инъекций.
Проблемы: если разрешены некоторые теги (allowed_tags), то htmlspecialchars не должен применяться к ним, иначе теги будут экранированы и не отобразятся. Приходится разделять обработку: сначала экранировать весь текст, затем применять strip_tags к экранированной версии? Нет, порядок важен. Лучше использовать отдельные функции для разных частей. Кроме того, strip_tags не удаляет атрибуты, поэтому если теги разрешены, атрибуты могут содержать JavaScript-обработчики. Для полной безопасности требуется дополнительная валидация атрибутов.
Расширенные примеры использования strip_tags
Пример 1: Удаление всех тегов, но с добавлением пробелов между словами из разных тегов (чтобы текст не склеивался).
<?php
$html = '<h1>Заголовок</h1><p>Первый абзац.</p><p>Второй абзац.</p>';
$clean = strip_tags($html);
echo $clean;
// Результат: "ЗаголовокПервый абзац.Второй абзац."
// Для улучшения можно заменить теги на пробелы
$clean2 = preg_replace('/<[^>]*>/', ' ', $html);
$clean2 = preg_replace('/\s+/', ' ', trim($clean2));
echo $clean2;
?>ЗаголовокПервый абзац.Второй абзац. Заголовок Первый абзац. Второй абзац.
Пример 2: Удаление PHP тегов вместе с HTML. strip_tags удаляет и PHP теги.
<?php
$str = 'Строка с <?php echo "код"; ?> и HTML.';
$clean = strip_tags($str);
echo $clean;
?>Строка с и HTML.
Пример 3: Обработка строки с комментариями HTML. strip_tags оставляет текст комментариев.
<?php
$html = '<!-- comment -->Видимый текст</-->';
$clean = strip_tags($html);
echo $clean;
?>Видимый текст
Пример 4: Использование strip_tags с array в параметре allowed_tags (PHP 7.4+).
<?php
$html = '<div>Контент <span>спан</span></div>';
$clean = strip_tags($html, ['div']);
echo $clean;
?><div>Контент спан</div>
Пример 5: Сравнение производительности strip_tags и preg_replace на длинной строке (концептуально).
<?php
$bigHtml = str_repeat('<p>Тест</p>', 10000);
$start = microtime(true);
$r1 = strip_tags($bigHtml);
$t1 = microtime(true) - $start;
$start = microtime(true);
$r2 = preg_replace('/<[^>]*>/', '', $bigHtml);
$t2 = microtime(true) - $start;
echo "strip_tags: $t1 сек\npreg_replace: $t2 сек";
?>strip_tags: 0.002 сек preg_replace: 0.015 сек